# Who can see what: designing the Salesforce access model on purpose

> Most access models were never designed. They were assembled from individual requests, each one reasonable at the time, and the result is an org that cannot explain itself.

- Source: https://synconai.com/insights/salesforce-security-permissions-best-practices
- Publisher: SynconAI (https://synconai.com)
- Desk: Platform & Architecture
- Author: SynconAI Architecture Team, Solution & technical architecture
- Published: 18 June 2026
- Updated: 29 August 2026
- Reading time: 16 minutes
- Topics: Security, Permissions, Sharing model, Governance, Architecture

## Key points

- Access is decided in a fixed order. Fixes applied at the wrong layer add exposure instead of removing it.
- Organisation-wide defaults are the only genuinely restrictive decision. Starting open and tightening later is far harder than the reverse.
- Field-level security is where most real exposure lives, because a field hidden on a page layout is still readable through reports, list views, exports and the API.
- The forgotten surfaces are dashboards running as another user, integration users, Apex without sharing, and data leaving through exports and connected apps.

---
Ask any org one question: who can see this record, and why. Not who owns it. Who can see it, named, with the reason beside each name.

Very few can. That is not usually because the model was built badly. It is because it was never built at all. It was assembled, one access request at a time, over five or seven years, by several administrators who each made a reasonable decision with the information in front of them. Nobody designed the thing, so nobody can now describe it.

The consequence shows up in two places. The first is an audit, where the question is asked formally and the answer takes three people and a week. The second is an incident, where the investigation finds that no single change caused the exposure: it was the sum of four grants, each defensible on its own.

Both come from the same root. Access in Salesforce is decided by a specific sequence of mechanisms, and most organisations treat that sequence as a bag of tools rather than an order. When access is missing, they reach for whichever tool is nearest. When access is excessive, they reach for a tool that cannot restrict, and add more grants trying to remove one.

## The order is the whole model

Salesforce evaluates access to a record in a defined sequence, and the sequence matters more than any individual setting inside it.

Object permissions come first, and they are binary in effect: with no read on the object, nothing further in the chain can give the user a record. Assuming they have it, **organisation-wide defaults** set the baseline for records the user does not own. That baseline is the most restrictive position, and it is the only part of the model whose job is to take access away.

Everything after it opens access back up. The **role hierarchy** grants users visibility of records owned by people below them. **Sharing rules** grant access to defined groups based on ownership or record criteria. **Manual sharing** grants access to individuals on a single record. **Apex managed sharing** grants access programmatically where the declarative options cannot express the requirement. Teams, territories and implicit sharing on related records do the same job in narrower circumstances. None of these can take anything away. They are additive by design, and access accumulates through them the way it does through a permission model.

Two mechanisms sit outside that additive flow. **Restriction rules** narrow what a user sees even where sharing would have granted it, which makes them the second genuinely restrictive tool in the platform. **Scoping rules** set the default set of records a user works in without changing what they are permitted to access, which is a usability control rather than a security one, and it is regularly mistaken for the opposite.

Field-level security is evaluated separately and applies regardless of all of this. A user with full access to a record still cannot read a field their field-level security denies.

::: note The practical consequence
If a user can see something they should not, the fix is almost never another grant. It is either the baseline being too open, a widening mechanism that should not apply to them, or a restriction rule that was never written. Teams who do not hold the order in their heads reliably attempt the fix one layer too late.
:::

## Organisation-wide defaults are the only genuinely restrictive decision

Because everything downstream is additive, the organisation-wide default is the most consequential setting in the access model. It is the ceiling on how private anything can be.

Set an object to private and you have a foundation to build on. Every subsequent grant is deliberate, visible and traceable to a rule you can name. Set it to public read and you have made a decision that cannot be unmade by any amount of downstream configuration, because nothing downstream restricts.

That asymmetry is why starting open and tightening later is so much harder than the reverse. Tightening an organisation-wide default does not merely change a setting. It removes access people have been relying on, usually without knowing which access they relied on, and the platform recalculates sharing across the object. The impact is discovered by users rather than by a report, and the discovery happens on a Monday. Meanwhile every process that quietly assumed broad visibility, a dashboard, a flow, an integration, an assignment rule, stops behaving the way it did.

There is a subtler cost too. When the default is open, nobody ever writes down who needs access, because nobody has had to. So when the tightening finally happens, the requirements do not exist. They have to be reconstructed by asking, and the answers you get are what people believe they need, which is always broader than what they use.

::: warn Open defaults hide the requirements
An open baseline does not just create exposure. It stops the organisation ever learning what its access requirements actually are, because the question is never forced. That is why a private default costs more in design and less in every year afterwards.
:::

The design question is therefore not "what does the business need to see" but "what is the smallest baseline that lets the widening mechanisms express the real rules". Where confidentiality is a regulatory obligation rather than a preference, that calculation changes again, and we have written separately about [what actually changes when the org belongs to a bank](/insights/what-changes-when-the-org-belongs-to-a-bank).

## The role hierarchy is a visibility structure, not an org chart

The most common structural mistake in a Salesforce access model is building the role hierarchy to mirror the organisation chart because the two look alike.

They are not the same object. The org chart describes reporting lines and accountability. The role hierarchy describes one thing only: who inherits visibility of whose records. Where the two happen to coincide, mirroring works. Where they diverge, mirroring produces exposure nobody intended and nobody can see.

The divergences are ordinary. A team leader who manages people but should not read their pipeline. A regional director who reports into a global function with no business reading regional customer data. A matrix arrangement where somebody has two managers and the hierarchy can only express one. A shared services function that sits above several business lines on the chart and, for information barrier reasons, must sit beside them in the data model.

The harm is compounded by inertia. Role hierarchies are rarely revisited, because changing one recalculates sharing and everybody is nervous about it. So the hierarchy built in year one, when the org chart happened to be a fair proxy, survives three reorganisations that made it a bad one.

The discipline is to treat the hierarchy as a deliberate artefact with its own justification. Every level should exist because a specific inheritance is required, not because a management layer exists. Where the answer to "why is this role above that one" is "because that is who they report to", the hierarchy is being used as documentation rather than as a control.

::: tip A cheap test
For each role, name the records it inherits and the business reason for the inheritance. Where the reason is a reporting line rather than a data requirement, that level is a candidate for removal, and removing it is usually less disruptive than the team expects, because the access is duplicated by a sharing rule anyway.
:::

## Sharing rules, and when they are the right answer

Sharing rules are the correct tool for a specific shape of requirement: a group of people needs access to a definable set of records, the rule can be expressed through ownership or record criteria, and the requirement is durable rather than one-off.

They are the wrong tool for three shapes they are nonetheless routinely used for.

**One person, one record, once.** That is manual sharing. Solving it with a criteria-based rule creates a permanent structure to serve a temporary need, and the structure outlives the need by years.

**A requirement that changes constantly.** If the criteria need editing every few weeks, the data model is doing the wrong job. Something that should be a field on the record is being expressed as a rule about records.

**Anything that needs to restrict.** Sharing rules only grant. A rule cannot exclude a subset, and attempting to build exclusion out of grants produces exactly the layering that makes an access model unreadable. Where the requirement is genuinely "these users must not see these records even though other mechanisms would allow it", restriction rules exist for that, and reaching for them early is far cheaper than discovering them late.

Apex managed sharing sits below all of this, and the honest guidance is to treat it as a last resort with a named owner. It can express rules the declarative tools cannot, which is precisely why it accumulates into the place difficult requirements go to be solved invisibly. Sharing written in code is sharing no administrator will find when they audit the sharing settings, so it needs documenting where the access review will look, not only where the developers will.

## Object permissions, field permissions, and where exposure lives

Record access and field access are different questions with different answers, and the second is where most real exposure sits.

Object permissions decide what a user can do with an object at all: read, create, edit, delete, and the broader capabilities that let a user view or modify all records of a type. Those broader capabilities bypass the sharing model entirely. A user with data-wide access sits outside everything described above: the organisation-wide default does not apply to them, the hierarchy is irrelevant, and no sharing rule is doing any work. Counting the humans who hold that access is usually the fastest way to focus a leadership conversation about the model.

Field-level security is the control most orgs under-use, and the reason is a misunderstanding that is easy to hold and expensive to keep. Removing a field from a page layout feels like hiding it. It is not. It hides the field on that page, and the field remains fully available through reports, list views, search results, the API, data exports and anything built on top of them. A salary field taken off a layout is still in the report builder. A customer identifier taken off a layout is still in an export.

That gap is what makes field-level security the highest-leverage control in the model, and it is invisible twice over: nothing in the interface announces it, and a field left readable produces no error, no warning and no evidence until somebody notices it in a report.

Record types belong here for the opposite reason. They control which picklist values and layouts a user sees, and they are frequently assumed to control access. They do not. A record type is a presentation and process construct, and anything depending on one for confidentiality is depending on something that was never a security boundary.

## Permission sets and permission set groups

Permission sets and permission set groups are the current recommended approach for granting permissions, and Salesforce has been steadily moving administrators away from assigning permissions directly on profiles and towards them. Permission set groups compose several sets into a single assignment that matches a job, and muting permission sets handle the exceptions without forking the group.

Profiles have not been removed and no retirement date is established, so treat this as a direction of travel rather than a completed migration, and confirm the current status of any specific capability with Salesforce directly rather than relying on second-hand summaries. Most orgs are somewhere in the middle, which means access is expressed in two places with different mental models, and answering "what can this person see" requires checking both. How that sprawl accumulates, how to measure it and how to clean it up is a subject in its own right, covered in [permission set debt](/insights/permission-set-debt). This article is about the model those permissions sit inside, which has to be right before a clean-up is worth doing.

## What each mechanism grants, and what it can never do

The most useful artefact for an access review is not a permission matrix. It is a statement of what each mechanism is capable of, because most misuse comes from asking a tool to do something it structurally cannot.

| Mechanism | What it grants | What it can never restrict | Where it is checked |
| --- | --- | --- | --- |
| Organisation-wide defaults | The baseline access to records a user does not own | Anything a downstream grant has already widened | Every record access, before any widening |
| Role hierarchy | Visibility of records owned below a user's role | Anything, it only inherits upward | Record access, after the baseline |
| Sharing rules | Access for groups, by ownership or record criteria | Anything, grants are additive only | Record access, after the hierarchy |
| Manual sharing | Access to one record for one user or group | Anything, and it survives until removed by hand | Record access, per record |
| Apex managed sharing | Access expressed in code where rules cannot be declared | Anything, and it is invisible to a settings audit | Record access, at share record level |
| Restriction rules | Nothing, it narrows what sharing granted | The user's object permissions | Record retrieval, after sharing |
| Scoping rules | Nothing, it sets the default record scope | Actual access, users can still reach the records | Default scope, not the security boundary |
| Object permissions | The ability to read, create, edit or delete a type | Field content, and data-wide access bypasses sharing | Every operation on the object |
| Field-level security | Read or edit on individual fields | Record visibility itself | Every surface: UI, reports, list views, search, API |
| Permission sets and groups | Additive capability, object and field access | Anything, muting sets are the exception mechanism | At assignment, composed with the profile |

Read the third column first. Most access failures are an attempt to make something in that column happen anyway, expressed as more configuration.

## The surfaces everybody forgets

The mechanisms above are the model. What follows is where the model gets bypassed, and these are the findings that turn up in audits, because they are the ones nobody looks at until somebody does.

**Reports and dashboards that run as another user.** A dashboard can be configured to run as a specified user, so every viewer sees the data through that user's access rather than their own. That is a deliberate and useful feature, and it is also a general-purpose way to publish data past the sharing model. A dashboard running as an executive shows executive-level data to anyone who can open it. Inventory these, name the running user for each, and treat that choice with the same care as any other access grant.

**List views.** The records inside a list view respect sharing, so a view does not leak records. What it can leak is shape. A view whose filter criteria name a sensitive field, a segmentation or a flag such as an investigation status tells the viewer that the field exists and what its values are, even where every record is filtered out. Visibility of the view definition is configured separately from the records, and almost never reviewed.

**Experience Cloud external users.** External access is a separate model with separate defaults, separate sharing mechanisms and a separate set of assumptions. It is also the place where a mistake is most public, because the audience is outside the organisation. The most common failure is not a misconfigured setting but an internal assumption carried across a boundary: an object, a field or a piece of content designed on the premise that only staff would ever see it. We have written about the design side of that in [portals people actually finish tasks on](/insights/experience-cloud-portal-best-practices), and the access review for an external surface should be run independently rather than inherited from the internal one.

**Integration users.** Almost every org has at least one user with far more access than any person, because it was built to serve several systems and each new integration added a little more, and nothing was ever removed. That user typically has broad object access, often data-wide access, and its credentials sit in configuration somewhere. Scope integration users per integration rather than per platform, review what each one actually calls, and treat any data-wide permission on an integration user as a finding that needs a written justification.

**Apex that runs without sharing.** Apex does not enforce the sharing model unless it is written to, and field-level security is likewise not applied automatically. That is by design, because system context is necessary for plenty of legitimate work, but it means a class, a trigger or an invocable action can read and return records the calling user could never open. Anything user-facing should enforce sharing explicitly and enforce field access explicitly, and the review question is not whether the code is correct but whether anybody decided.

**Search and the API.** Both respect sharing and field-level security, which is exactly why field-level security matters so much: it is the only control that covers them. A field hidden by layout is fully visible to anything that queries the object.

## Access that leaves the org

Every control described so far governs what a user can see inside Salesforce. A separate question is what leaves, and it is governed by a different set of features usually owned by a different person.

Data exports, report exports and bulk extracts move data outside every control the platform enforces. Once a report is in a spreadsheet on a laptop, field-level security is a historical fact rather than a control. Treat the permissions that allow export as elevated rather than routine, and monitor the exports themselves: Event Monitoring records this kind of activity, and it is one of the few ways to answer questions about viewing and extraction rather than editing.

Connected Apps are the other exit. Each one is an authorised path into the org with its own scopes and policies, and the population grows the way permission sets do. Review the list, confirm each app is still in use, and check the permitted users policy and IP restrictions on each. Named Credentials govern the outbound direction and keep authentication details out of code. External Objects bring the question full circle, because data displayed through them lives somewhere else and is governed there.

Around all of this sit the controls deciding who gets in at all: Multi-Factor Authentication, Login IP Ranges and session settings. They are not part of the sharing model, but they bound it, and an immaculate sharing design behind weak authentication has simply moved the weakest link.

## A testable definition of done

An access model is finished when the organisation can answer a small set of questions on demand, with evidence, without convening a working group. Here is the set we use, and how to check each one.

| Question | How to check it |
| --- | --- |
| Who can see this record, and by which mechanism? | Open the record's sharing detail and name the grant behind each entry. Anything unexplained is a finding. |
| Which objects are private, and where is that written down? | Compare the organisation-wide default settings against the design document. A default nobody can justify is a decision nobody made. |
| Who can view or modify all data? | Count the humans, not the profiles. The number should be small and every name justifiable. |
| Which fields are restricted, and on which profiles and permission sets? | Run the field accessibility view for each sensitive field. Layout removal is not an answer. |
| Which dashboards run as another user, and who is that user? | List them and name the running user for each. Treat every one as a published data grant. |
| What does each integration user have, and why? | One written justification per integration. Data-wide access needs a reason and a review date. |
| Which Apex runs without enforcing sharing, and was that deliberate? | Review user-facing classes for sharing and field enforcement. The finding is undecided, not incorrect. |
| Who can export data, and who reviewed the last exports? | Check the export permissions, then check the monitoring. If nobody reviews it, nobody knows. |
| What can external users reach? | Run the external access review separately. Never infer it from the internal one. |
| When was this last checked, and by whom? | A named owner and a date. Without those, every answer above is a snapshot with no shelf life. |

Two platform features make the list cheaper to run than it looks. Health Check measures your security settings against a standard, which is a useful starting position rather than a conclusion, and Security Center aggregates the picture where you run more than one org. Where the obligation extends to proving what happened rather than what was configured, Salesforce Shield adds Event Monitoring for activity and Field Audit Trail for retention, and both are far cheaper to enable before you need them than to explain the absence of afterwards.

None of this is exotic, and none of it requires a programme. It requires somebody to own the model as a design rather than as a queue of requests, and the ten questions above to have answers written down somewhere other than one person's memory. The orgs that can answer them did not build a more sophisticated access model. They built an ordinary one on purpose, and then kept it that way.
