Security & access
Profiles vs permission sets, the sharing model, field-level security, and least privilege: how to control who sees and edits what without a permissions swamp.
Related
An account exec once forwarded me a report showing every customer’s negotiated discount, contract value, and renewal date across the entire company, including deals two levels above his pay grade. He was not malicious, he was curious, and the org had handed him “View All Data” as part of a profile someone cloned in 2019 and never audited. One checkbox, buried in a profile nobody remembered building, exposed the commercial terms of the whole book to anyone who inherited that profile. Security and access is where a single wrong default is not a bug you fix later. It is a disclosure you cannot take back, because the person has already seen the number.
Access control gets treated as an admin chore, a box to tick during onboarding. It is closer to the blast radius setting for every other mistake in the system. A bad automation touches the records a user can reach. A curious rep sees the fields a profile exposes. Least privilege is not paranoia: it is the practice of making the blast radius as small as the job allows, so that when something goes wrong, and it will, the damage is contained to what that person actually needed.
Profiles set the floor, permission sets add on top
Every user has exactly one profile, and it should grant the minimum every holder of that profile needs. Anything extra rides on a permission set, assigned to the individuals who need it. This is the model Salesforce has pushed toward for years, and the reason is maintainability: a per-person capability layered as a permission set is visible, additive, and removable, where the same capability baked into a cloned profile is invisible and spreads to everyone who ever inherits the clone.
The anti-pattern is the “kitchen-sink profile,” cloned once, granted everything to avoid future tickets, then handed to people who need a tenth of it. That is how a rep ends up with View All Data. Keep profiles thin, push variability to permission sets, and use permission set groups to bundle the sets a role needs so assignment stays one action instead of ten.
The sharing model controls which records, FLS controls which fields
Two separate questions hide behind “who can see this.” Record access (which rows a user can open) is governed by org-wide defaults, role hierarchy, and sharing rules. Field-level security (which columns a user can see or edit on a row they can already open) is governed by FLS on the profile or permission set. Confuse them and you either lock reps out of their own accounts or expose a discount field to the whole company.
Set org-wide defaults to the most restrictive posture the business tolerates (Private for Opportunity is common), then open access back up deliberately with the role hierarchy and sharing rules. Opening up from Private is auditable. Clamping down from Public is a fire drill, because you have to find everyone who already saw what they should not have.
| Record access (sharing) | Field access (FLS) | |
|---|---|---|
| Question answered | Which rows can this user open? | Which fields on that row can they see or edit? |
| Controlled by | Org-wide defaults, roles, sharing rules | FLS on profile or permission set |
| Right default | Private, opened up deliberately | Hidden for sensitive fields, granted on need |
| Failure mode | Public exposes the whole book | Discount and comp fields visible to everyone |
FLS is also the enforcement behind the one-writer-per-field rule from data governance. If enrichment owns employee count, FLS lets only the integration user’s profile write it and locks reps to read-only, so reps cannot fight the enrichment tool. A validation rule makes the intent explicit for the cases FLS alone cannot express.
// Sensitive commercial field: only Deal Desk edits the approved discount.
// Everyone else is read-only via FLS; this backstops it in automation.
AND(
ISCHANGED( Approved_Discount__c ),
NOT( $Permission.Can_Edit_Approved_Discount )
)
View as table
| Stage | Value |
|---|---|
| Before: View All Data | 47 users |
| Before: Modify All Data | 23 users |
| After: View All Data | 6 users |
| After: Modify All Data | 3 users |
- 1
1. Find the god-mode permissions
List every profile and permission set granting View All Data or Modify All Data. This is the highest-blast-radius check, so it goes first.
- 2
2. Thin the kitchen-sink profiles
Strip cloned profiles back to the true minimum. Move anything a subset needs into a permission set.
- 3
3. Set org-wide defaults restrictive
Private where the business allows, then open access up with roles and sharing rules you can point at.
- 4
4. Hide sensitive fields with FLS
Discount, comp, contract terms, and PII visible only to the roles that need them, enforced on profile or permission set.
- 5
5. Bundle role capability into permission set groups
So assigning a role is one action and offboarding is one removal, not a scavenger hunt.
- 6
6. Review on a cadence, and at every role change
Access drifts as people move teams. A quarterly review and a role-change checklist keep the drift from compounding.
Security and access is the one area where the cost of getting it wrong is asymmetric: a too-tight setting is a support ticket, a too-loose one is a disclosure you cannot reverse. Keep profiles thin and add capability with permission sets, separate record access from field access in your head and in the config, default to Private and open up deliberately, and hunt down View All Data before anything else. Grant the least the job needs, review it on a cadence, and the blast radius of every other mistake shrinks to the size of one person’s actual work.
Keep reading
All guides →Object & data model
How the standard objects, record types, and custom fields fit together, plus the grain rules and relationship choices that decide whether reporting ever ties out.
ArchitectCPQ & quote-to-cash
How quotes, price books, approvals, and billing connect into one revenue chain, plus the config choices that decide whether a signed deal actually invoices correctly.
ArchitectAutomation architecture
How flows, triggers, and validation rules coexist without fighting, plus the order-of-execution and consolidation rules that keep automation from eating itself.