How to audit who can see sensitive data in Salesforce (profiles and permission sets)

TL;DR

Access accumulates and nothing removes it. Four questions to answer for every sensitive object, without clicking through every profile.

Salesforce permission sets Salesforce security audit field-level security

Auditing data visibility means answering one question for each sensitive object: which profiles and permission sets grant read, edit, delete, or export access to it, and whether each of those grants is still justified. The answer lives entirely in metadata, so it can be read out of your repository in one pass instead of assembled by opening user records one at a time.

This post covers why access accumulates, the four questions an audit has to answer, and how to run it without clicking through every profile.

The pain: access accrues and nothing removes it

Nobody decides to expose a compensation field to the whole company. It happens the way it always happens.

  1. Someone cloned a profile. A new hire needed access roughly like a colleague's, so the fastest correct-looking move was to clone that profile and adjust it. The clone carried everything the original had, including grants inherited from a clone made two years earlier by someone who has since left.
  2. Someone needed it temporarily. A permission set was assigned for a migration, a month-end close, or a consultant's engagement. The work finished. The assignment did not. Nothing in Salesforce expires it, and nothing reminds you it is there.

Both are reasonable decisions made under time pressure, and neither leaves a trace that surfaces on its own. The system has no opinion about access that stopped being necessary, so exposure only grows, quietly, until an auditor, a customer security review, or an incident asks the question directly.

At that point the question is genuinely hard to answer, because the truth is spread across profiles, permission sets, permission set groups, field-level security, and object permissions, and no single screen reads them together.

The bridge: exposure is a question about metadata

Two things make this tractable.

First, every one of those grants is metadata. Object permissions, field-level security, the contents of a profile, the definition of a permission set: all configuration, stored as text, and therefore readable in one pass rather than one screen at a time. The audit feels impossible not because the information is hidden but because the interface presents it per user, per profile, per object, and never in aggregate.

Second, once that metadata is tracked in a repository, the audit stops being an event and becomes a query. The same read that answers the question today answers it again next quarter, and the difference between the two answers is itself visible, which is the part that catches access quietly widening.

The audit: four questions per sensitive object

Start by naming the objects that actually matter: the ones holding personal data, compensation, pricing, contracts, or anything under a regulatory obligation. For each one, answer four questions in order.

  1. Who can read the object at all. Object-level read on any profile or permission set that reaches a real user. This is the outer boundary, and nothing inside it matters if this is already wider than you expected.
  2. Who can see the specific fields that matter. Field-level security is where the real exposure usually sits. An object can be properly restricted while one salary or margin field stays readable to everyone through a permission set nobody remembers assigning.
  3. Who can edit, delete, or take the data out. Edit and delete on the object, plus the system permissions that override object settings entirely, including View All Data, Modify All Data, and the ability to export reports. One administrative permission can make your first two answers irrelevant.
  4. Where each grant comes from. For every access path you found, the profile, permission set, or permission set group that produces it. That is the difference between knowing you have a problem and knowing which line to change.

The output is a list of specific grants on specific objects and fields, each traced to its source. That is the form a finding has to take to be actionable, and it is the form a fix can be written against.

Who this is for

Anyone who would currently answer a security questionnaire with a screenshot.

Alone, the value is being able to answer at all, on the day you are asked, without a week of clicking. With a team, it is a shared and current statement of who can see what, so access decisions are made against the real model rather than an assumption about it. With auditors or a security reviewer involved, it is a record that shows both the current state and how it got there, which is usually the harder half of the request.

Why this is the audit worth running first

Access is the change class with the widest consequences and the weakest feedback. A broken flow announces itself within a day. An over-permissioned field does not announce itself at all, until the moment it becomes expensive.

FlowSprite ships this as a built-in audit. It reports which profiles and permission sets grant broad read, edit, or delete access to sensitive objects, read from your synced metadata, changing nothing in the org. Any remediation that follows travels the same route as every other change, which is a pull request in your own repository, a sandbox, and your approval before anything reaches production.

Get started

Try it at flowsprite.com. Point it at your org, name the two or three objects you would least like to be wrong about, and read what comes back.

If it surfaces access you cannot explain, that is the audit working. Tell us what it found and what you expected to find.

Ship your next Salesforce change with FlowSprite

Describe the change in plain English. FlowSprite drafts the metadata, opens a PR, deploys to sandbox first.

Start free