Skip to content

Why Your Developers Don't Need Modify All Data (And What They Actually Need Instead)

Modify All Data is org-wide read and write that does not even override field-level security. Here are the five real requests behind it, and what each one needs.

Part 1 of 4 in the Salesforce Delivery Team Access series. This part is the diagnosis. Parts 2 to 4 build the model, size it to your team, and ship the metadata.

TL;DR

  • Modify All Data is not "slightly more access". It is create, read, edit, and delete on every record of every object in the org, regardless of sharing, and enabling it automatically enables its dependent permissions.
  • It does not override field-level security. Users still need field permissions or View All Fields, which is why the developer who was granted it often comes back an hour later asking for more.
  • The permission almost nobody reaches for first is object-level Modify All Records, set per object, which covers most legitimate cases without opening the whole org.
  • Nearly every request is a proxy for one of five narrower needs: deploying metadata, reading a record blocked by sharing, running code over all records, cleaning up test data, or making a test pass. Four of the five do not touch data permissions at all.
  • One trap to know before you design anything: viewing debug logs in Setup requires View All Data. There is no narrower permission, so "let support read production logs" is really "grant org-wide data read".

What You'll Learn

  • What Modify All Data actually grants, and the two things about it that surprise people
  • The difference between org-wide Modify All Data and object-level Modify All Records, and why the distinction is the whole game
  • The five real requests hiding behind "I need Modify All Data", and the narrower permission for each
  • Why debug log access costs more than it looks
  • A SOQL query that tells you who holds it in production today, and whether it arrives via a profile or a permission set

The Problem

Ask a Salesforce delivery team how access is managed during build and you usually get a version of the same answer: everyone who needs to do anything has System Administrator, in every sandbox, and probably in production too, because nobody wanted to work out the minimum on go-live weekend.

Nothing has gone wrong yet. That is precisely why it persists. The cost is invisible until it is not, and it shows up in three ways.

There is no blast radius control. A developer testing a data fix in a sandbox holds the same permission to run it in production. The only thing preventing an incident is which browser tab they were on and how tired they are.

There is no audit signal. When everyone holds Modify All Data, Setup Audit Trail tells you a change happened, but the set of people who could have made it is the entire team. Attribution collapses exactly when you need it.

There is no exit path. Offboarding a contractor means reasoning about what a System Administrator profile touched, and the answer is everything.

Before designing any of that away, it is worth being precise about the permission at the centre of it, because most teams are wrong about what it does.

Common Questions This Article Answers:

  • Why would a developer ever need Modify All Data, and what should they get instead?
  • What is the difference between Modify All Data and Modify All?
  • What permissions does a developer actually need to deploy metadata?

Quick Answer

Modify All Data grants create, read, edit, and delete on every record of every object in the org, regardless of sharing settings, and it implies View All Data. It does not override field-level security, so a developer holding it can still be blocked from a field, which is why granting it frequently fails to solve the reported problem. The narrower permission almost nobody reaches for first is the object-level Modify All Records, set per object on a permission set, which covers the legitimate cases without opening the entire org.

The five requests that hide behind it resolve like this: deploying metadata needs Modify Metadata Through Metadata API Functions plus Customize Application, not Modify All Data; being unable to read a record is a sharing problem, so use object-level View All or a sharing rule; a batch or trigger that must touch every record already runs in system context, so the developer's own permissions are irrelevant; cleaning up test data needs Modify All Records on the specific objects, in a sandbox; and a failing test almost always means the test is wrong, because Apex tests do not see org data by default.

What Modify All Data actually grants

Salesforce documents two distinct pairs of permissions that people routinely conflate.

Org-wide: View All Data and Modify All Data. These apply to every object in the org. Modify All Data lets a user create, read, edit, and delete all records regardless of sharing settings, and it implies View All Data. In a profile or permission set, enabling it automatically enables its required dependent permissions, and disabling one of those required permissions disables Modify All in turn.

Object-level: View All Records and Modify All Records, set per object in the object permissions of a permission set. Same override of the sharing model, scoped to one object.

The distinction is the entire game. "I need to be able to fix any Case in this sandbox" is an object-level request. It gets answered org-wide because the org-wide checkbox is the one people know about, and because it sits conveniently near the top of the permission list.

Two properties of Modify All Data are worth stating explicitly, because both surprise people.

It does not override field-level security. Neither the org-wide nor the object-level variants do. Users still need field permissions on each field, or the View All Fields object permission. This is the source of a very common support loop: a developer is granted Modify All Data to unblock them, still cannot see the field they were actually asking about, and comes back for more. The grant was both too broad and beside the point.

It is a genuine super-permission for a small number of platform operations. The clearest example is Apex managed sharing on custom objects, where only users with Modify All Data can add or change the sharing on a record, and that sharing survives owner changes. That is a real requirement, and it is also a one-off setup task rather than a reason for a standing grant on six developers.

The five requests hiding behind it

When someone asks for Modify All Data, the useful next question is not yes or no. It is "what are you trying to do". In practice the answer is one of five things.

1. "I need to deploy"

This is the most common and the most misdiagnosed. Metadata deployment does not need Modify All Data. It needs Modify Metadata Through Metadata API Functions, alongside Customize Application. That pair is designed precisely to let a user deploy without holding org-wide data access.

There is a real gotcha here, and it is worth testing before you build a whole model on it. There is a long-standing known issue where the permission granted through a permission set does not take effect for metadata operations invoked from Apex, throwing System.NoAccessException: Not allowed to install or modify metadata via Apex, while the same permission granted on a profile works as expected. For ordinary sf project deploy start pipelines the permission set path is the one to try first, but if your deploys pass through Apex-invoked metadata operations, and some managed package post-install scripts do, you may be forced onto a profile-based grant for the deployment user specifically.

Test this in an integration sandbox before you commit. If a reduced-permission deploy fails, record which metadata type failed rather than falling back to Modify All Data wholesale.

2. "I can't see the record to debug it"

This is a sharing problem wearing a permissions costume. The fix is object-level View All Records on the one object involved, or a sharing rule, or in production a temporary elevation rather than a standing grant.

And as covered above, if the actual complaint is a missing field rather than a missing record, no amount of View All or Modify All will help. Check field-level security first. It takes thirty seconds and it resolves this request more often than people expect.

3. "My batch job has to touch every record"

This is the one that reveals the underlying confusion most clearly, because it conflates the developer's permissions with the code's execution context.

Apex running in system context, which includes classes declared without sharing and most batch and scheduled contexts, operates independently of the running user's sharing access. The developer who writes it does not need Modify All Data for the code to work. What matters is the context the code declares and, since API version 67, the fact that database operations default to user mode. If you have not yet worked through what that change means for existing classes, the Summer '26 secure-by-default Apex changes are the place to start.

Granting a developer Modify All Data so their batch job works is treating a symptom that does not exist.

4. "I need to clean up test data"

Legitimate, and it needs Modify All Records on the specific objects being cleaned, in a sandbox where that is appropriate. Not org-wide, and not in production.

If the cleanup is recurring, it belongs in a script that runs in the pipeline rather than in a standing human permission. A recurring manual task performed with elevated access is a candidate for automation, and noticing that is one of the more useful side effects of taking permissions seriously.

5. "The test fails without it"

Apex tests do not see org data by default. A test that only passes when the running user holds Modify All Data is usually a test that depends on org state it should be creating itself, or a test of permission-sensitive code that should be exercising System.runAs deliberately.

Either way, the fix is in the test, not the permission.

The debug log trap

There is a sixth request that deserves separate treatment, because it looks small and is not.

Viewing, retaining, and deleting debug logs in Setup requires View All Data. There is no narrower permission for it, which is a long-standing gap that customers have raised as a product idea precisely because the current behaviour forces an org-wide data read grant to perform a diagnostic task.

So "give the developer debug log access in production" is not a minor convenience. It is org-wide read on every record of every object. The same applies to your support team, and it applies more severely there because a support function is usually larger and turns over faster than a development team.

This single fact reshapes the access design in part 2: debug log access has to be temporary and approved, never standing, no matter how routine the diagnostic work is.

Find out who holds it today

Before designing anything, measure. This query tells you who currently holds Modify All Data in production and, critically, whether the grant arrives through a profile or a permission set:

SELECT Assignee.Name, Assignee.Username, PermissionSet.Label,
       PermissionSet.IsOwnedByProfile
FROM PermissionSetAssignment
WHERE PermissionSet.PermissionsModifyAllData = true
  AND Assignee.IsActive = true
ORDER BY Assignee.Name

Run it with sf data query --query "..." --target-org my-prod.

The IsOwnedByProfile field matters more than it looks. A grant that arrives through a profile is metadata that deploys between orgs. A grant through a genuine permission set is an assignment that does not. That distinction turns out to be the mechanism the whole access model rests on, which is where part 2 begins.

Swap PermissionsModifyAllData for PermissionsViewAllData to find everyone who can read your entire org. That list is usually longer, and more surprising, than the first one.

Frequently Asked Questions

Q: Is there any legitimate reason for a developer to hold Modify All Data?

A: Rarely, and almost never as a standing grant. The clearest genuine requirement is Apex managed sharing on custom objects, where only users with Modify All Data can add or change record sharing. That is a one-off setup task, which makes it a candidate for temporary elevation rather than permanent assignment. For everything else, ask what the developer is trying to accomplish. Deployment needs Modify Metadata Through Metadata API Functions plus Customize Application. Reading a blocked record is a sharing question. Code that must touch every record already runs in system context. Test data cleanup needs object-level Modify All Records on named objects. A failing test needs a better test.

Q: What is the difference between Modify All Data and Modify All?

A: Scope. Modify All Data is org-wide and applies to every object. Modify All Records is set per object in a permission set's object permissions and applies only to that object. Both override the sharing model, and neither overrides field-level security, so a user with either still needs field permissions or View All Fields to see individual fields. Most requests that arrive asking for the org-wide permission are satisfied by the object-level one, which is why the first question should always be which object is involved.

Q: My developer has Modify All Data and still cannot see a field. Why?

A: Because field-level security is a separate layer that Modify All Data does not override. The user needs the field permission on that specific field, or the View All Fields object permission. This is worth checking first whenever someone reports that elevated access "did not work", because it is usually the actual cause and it means the elevation was unnecessary in the first place.

Q: Do we need Shield or a third-party tool to audit this?

A: No. The query above uses standard SOQL against PermissionSetAssignment, which every org has. Setup Audit Trail covers production Setup changes without additional licensing. Shield and Event Monitoring add depth on the detection side, but nothing in this diagnosis requires them.

Key Takeaways

  • Modify All Data is org-wide and it does not do what people think: it grants create, read, edit, and delete on every record of every object, implies View All Data, and still does not override field-level security.
  • Ask what they are trying to do, not whether to grant it: four of the five requests behind it are not data permission problems at all.
  • Deployment is a metadata permission, not a data permission: Modify Metadata Through Metadata API Functions plus Customize Application, with a known issue to test for on the permission set path.
  • Object-level Modify All Records is the answer most of the time: same sharing override, one object instead of the whole org.
  • Debug logs require View All Data: there is no narrower permission, so production log access is a step-up decision rather than a standing convenience.
  • Measure before you design: find out who holds it today and whether it arrives via a profile or a permission set.

What's Next?

Recommended Reading:

Action Items:

  1. Run the query above in production and write down, for each person holding Modify All Data, what they were granted it for.
  2. For every answer that is "to deploy", pilot a user with Modify Metadata Through Metadata API Functions plus Customize Application in an integration sandbox instead.
  3. For every answer that is "to see a record", check field-level security before changing any permission.
  4. Note which grants arrive via a profile rather than a permission set. Those are the ones that travel between orgs.

Resources & References


About This Guide: Part 1 of the Salesforce Delivery Team Access series. Last updated July 2026. Permission behaviour and known issues change between releases, so verify the deployment permission path in an integration sandbox before adopting it.

Tags: #salesforce #security #leastprivilege #apex #salesforceadmin