Security PD1 · Sharing, Profiles, Permissions & Apex Security

Overview

PD1 doesn't just test "name the feature." It tests whether you know which layer controls what — record visibility vs object/field permissions vs code-level access — and which feature to reach for in a given scenario. Security threads through Developer Fundamentals, UI, and Apex Logic sections alike.

1Profile per user
1Role per user
NPermission Sets per user
67.0+API: Apex user mode default

The single most important distinction

Can the user SEE this record?

→ Sharing: OWD, Role Hierarchy, Sharing Rules, Manual Sharing, Apex Managed Sharing

Can the user USE this object/field/class?

→ Permissions: Profile, Permission Set, Permission Set Group

Top trapsRole gives no object/field permissions · Permission Sets do not change the profile, they add on top · with sharing controls record access only, never CRUD/FLS · a role hierarchy does not have to mirror the org chart · Apex is not always system mode — API 67.0+ defaults to user mode.

The Security Stack

Security is layered, not a single switch. Permissions are additive — you build up access, you don't flip one flag.

Org-Wide Defaults (floor) Role Hierarchy Sharing Rules Manual / Apex Sharing Profile + Permission Sets Apex / LWC enforcement

OWD sets the baseline; everything to its right can only raise access above that floor (sharing never removes access OWD already grants — except with restriction rules, see Advanced Topics).

Record Access ("Can they see it?")

1. Organization-Wide Defaults (OWD)

  • The baseline record access level per object — answers "if a user doesn't own the record and has no special sharing, can they see it?"
  • Everything else in the sharing model (roles, rules, manual/Apex sharing) can only raise access above this floor.

2. Role Hierarchy

  • Grants users in higher roles access to records owned by users below them in the hierarchy.
  • Purely a record-access concept — does not grant object or field permissions.
  • Does not need to mirror the actual org chart — it's a data-access structure.
Trap"Manager should see subordinate records" → Role Hierarchy. "User should be able to edit the field" → Profile/Permission Set, not role.

3. Sharing Rules

TypeShares based onExample
Ownership-basedRecord owner's role/group"Share all records owned by Sales with Service"
Criteria-basedField values on the record"Share records where Region = West"

4. Manual Sharing

  • Share a single record to a user/group via UI, Apex, or SOAP API.
  • If the owner changes, manual sharing is automatically removed.
  • Best for exceptional, one-off access — not a permanent rule.

5. Public Groups

  • Can contain users, other groups, roles, or territories.
  • Used as sharing targets so you share to a logical collection instead of hardcoding individuals.

Record vs Permission access — the exam's favorite split

Record access (can they SEE it)Permission access (can they USE it)
OWDProfile
Role HierarchyPermission Sets
Sharing RulesPermission Set Groups
Manual / Apex SharingMuting Permission Sets
Teams / Territory modelsApex class access, system permissions

Permission Access ("Can they use it?")

Profiles

  • The user's baseline security identity — not "extra access."
  • Controls object permissions, FLS, tab visibility, app access, login behavior, class access, some setup access.
  • One profile per user — a core exam fact.

Permission Sets PD1 favorite

  • Grant additional access without changing the user's profile.
  • Extend: objects, fields, tabs, Apex classes, custom permissions, system permissions.
  • The least-privilege mechanism — keep profiles narrow, grant extras via permission sets.
  • A user can have multiple permission sets.

Permission Set Groups & Muting Permission Sets

  • Permission Set Group — bundles multiple permission sets into one assignable unit (easier management at scale, by job function).
  • Muting Permission Set — lets admins reduce specific permissions inside a group without rebuilding it.
Trap"Bundle several permission sets into one assignment" → Permission Set Group. "Remove one permission from a group without changing the whole set" → Muting Permission Set.

Apex class access is part of the permission model

An authenticated or guest user can call an @AuraEnabled Apex method only if their Profile or an assigned Permission Set grants access to that Apex class. If a component can't call Apex, check profile access, permission set access, class visibility, and the method annotation — not just sharing.

Apex Security

Sharing keywords — record-level only

KeywordEffect
with sharingEnforces sharing rules for record access
without sharingBypasses sharing rules (system mode for records)
inherited sharingInherits caller's sharing context; clarifies intent
  • In API 67.0+, Apex runs in user mode by default, and record sharing is enforced by default unless you declare without sharing.
Critical trapSharing keywords control record-level security only. They do NOT enforce object-level or field-level security (CRUD/FLS) — that's a separate mechanism entirely.

WITH USER_MODE

Enforces object permissions, field permissions, and sharing in the current user's context — the safer default choice.

SELECT Id, Name
FROM Expense__c
WITH USER_MODE

WITH SYSTEM_MODE

Explicitly bypasses object/FLS restrictions — use only when the requirement intentionally needs elevated access.

SELECT Id, Name
FROM Expense__c
WITH SYSTEM_MODE

stripInaccessible()

Sanitizes records you already have — strips fields the current user cannot access, for graceful cleanup instead of a hard failure.

DistinctionstripInaccessible() cleans up records you already queried. WITH USER_MODE makes the query itself respect permissions from the start.

PD1 shortcut

  • Need record sharing respected? → with sharing
  • Need explicit bypass of sharing? → without sharing
  • Need object/field permissions enforced in a query? → WITH USER_MODE
  • Need elevated access, explicitly? → WITH SYSTEM_MODE
  • Need to sanitize records already in hand? → stripInaccessible()
  • Need the safest standard UI record access? → Lightning Data Service (handles sharing, CRUD, and FLS automatically)

Advanced Topics

Researched additions

These extend beyond your original notes — gap-filling topics PD1 scenario questions frequently test, verified against Salesforce documentation.

Apex Managed Sharing High-yield

  • Any custom object with OWD below Public Read/Write auto-generates a share table: ObjectName__Share (standard objects: AccountShare, OpportunityShare, etc.)
  • Key fields: ParentId (record shared), UserOrGroupId (recipient), AccessLevel (Read / Edit — never settable to All, that's system-reserved for the owner), RowCause (why it was shared).
  • RowCause values: Manual, Rule, Owner, or a custom Apex Sharing Reason (defined under Setup → Sharing Reasons).
Custom_Object__Share cos = new Custom_Object__Share();
cos.ParentId = recordId;
cos.UserOrGroupId = userOrGroupId;
cos.AccessLevel = 'Edit';
cos.RowCause = Schema.Custom_Object__Share.RowCause.My_Apex_Reason__c;
insert cos;
Critical trapNever rely on RowCause = 'Manual' for permanent access — if the record owner changes, Salesforce automatically deletes all shares with that RowCause. Custom Apex sharing reasons survive ownership changes. Access from all mechanisms (OWD/role/rules/manual/Apex share) is combined — most permissive wins, never restrictive.
Trigger phrase"A batch process needs to grant edit access programmatically without changing OWD" → Apex Managed Sharing. A sharing rule is declarative/criteria-based, not for one-off programmatic grants.

CRUD/FLS: Describe methods vs modern enforcement

The old manual pattern is still valid syntax and still testable — it's verbose, not deprecated.

if (!Schema.sObjectType.Account.isAccessible())  { /* block read   */ }
if (!Schema.sObjectType.Account.isCreateable())  { /* block insert */ }
if (!Schema.sObjectType.Account.isUpdateable())  { /* block update */ }
if (!Schema.sObjectType.Account.isDeletable())   { /* block delete */ }
if (!Schema.sObjectType.Account.fields.Name.isAccessible())  { /* field read  */ }
if (!Schema.sObjectType.Account.fields.Name.isUpdateable()) { /* field write */ }
ApproachEnforces automatically?Granularity
Schema Describe (isAccessible() etc.)No — you gate logic manuallyObject + per-field
WITH USER_MODE (SOQL/DML)Yes — throws or filters at query/DML timeObject + field + sharing
stripInaccessible()You call it explicitly; then strips silently (no exception)Field-level, works on record lists
TrapQuestion emphasizes checking before a DML statement, per object/field → Describe methods (still correct, if old-school). Emphasizes concise enforcement directly in SOQL/DMLWITH USER_MODE. Emphasizes sanitizing a bulk result set before returning to a component → stripInaccessible().

Sharing Recalculation

  • Salesforce automatically recalculates sharing when: role hierarchy changes, a user's role changes, group/queue membership changes, territory hierarchy changes, or sharing rule criteria change.
  • Recalculation is asynchronous — large jobs can take minutes to hours; an email is sent on completion.
  • Defer Sharing Calculations (Setup feature) batches multiple structural changes (mass role moves, OWD changes, data migrations) into one recalculation instead of many.
Trap"5,000 users' roles changed and sharing didn't update immediately" → this is expected async behavior, not a bug. Planning a large reorg → use Defer Sharing Calculations.

Session-Based Permission Sets

  • A permission set flagged "Session Activation Required" is inactive by default, even if assigned — it only grants access during an active session once explicitly activated.
  • Activated via a Flow core action ("Activate Session-Based Permission Set") or programmatically by inserting a SessionPermSetActivation record.
  • Ends automatically at logout — no manual cleanup needed.
Trigger phrase"Grant access only temporarily, only during this session, or only after a runtime condition is verified" → Session-Based Permission Set, not a standing assignment.

Delegated Administration

  • Lets non-admin users manage specific User records (reset passwords, freeze/unfreeze, create/edit users in specified roles) and specific custom objects (fields, layouts, record types, validation rules).
  • Standard objects cannot be delegated. Delegates can never grant "Modify All Data," "View All Data," or the System Administrator profile.
Trigger phrase"Regional managers should create/manage users and reset passwords for their region only, without full admin access" → Delegated Administration. Assigning System Administrator (too broad) or a permission set with "Manage Users" (org-wide, not scoped) are both wrong.

Field History Tracking vs Scoping Rules vs Restriction Rules Frequently confused

FeatureWhat it doesAffects access?
Field History TrackingAudits old/new values for up to 20 fields per objectNo — pure audit trail, not access control
Scoping RulesFilters the default view in list views/lookups/search/reportsNo — users can still see out-of-scope records directly
Restriction RulesCriteria-based, actually narrows what a user can see across list views, lookups, reports, SOQL/SOSLYes — the only one of these three that restricts
Key distinctionSharing rules only ever widen access. Restriction Rules are the one mechanism that narrows access below what sharing already grants. Up to 2 active rules per object for both Scoping and Restriction Rules.

Login Hours, Login IP Ranges & Session Settings

  • Login Hours (per Profile) — restricts login times; outside those hours, active sessions are immediately logged out.
  • Login IP Ranges (per Profile) — login from outside the range triggers identity verification (unless the IP is in an org-wide Trusted IP Range, which bypasses verification entirely).
  • Session Settings (org-wide, Setup) — timeout duration, IP-locking sessions, forced logout behavior.
TrapThese all live on the Profile, not permission sets — permission sets cannot restrict login hours or IP ranges.

Guest User Security Tightened in recent releases

  • Guest User OWD is enforced as Private for all objects — cannot be raised, regardless of prior config.
  • Guest users cannot be in public groups/queues, and cannot receive Manual Sharing or Apex Managed Sharing.
  • The only supported way to grant a guest user record access is a Guest User Sharing Rule (a special criteria-based rule type).
Favorite trap"Experience Cloud site needs guest/unauthenticated users to see specific records" → Guest User Sharing Rule is the only correct answer. Public groups, manual sharing, Apex sharing, and OWD above Private are all invalid for guest users — this contradicts normal sharing knowledge on purpose.

Final trap round-up

  • Profile vs Role — Profile = object/field/system permissions + login constraints. Role = record visibility via hierarchy only. Frequently conflated.
  • Master-Detail child of a standard parent forces OWD to "Controlled by Parent" — cannot be changed; sharing follows the parent entirely.
  • without sharing bypasses record-level sharing only. It does NOT bypass CRUD/FLS — object and field permissions still apply regardless of the sharing keyword. This is one of the most common PD1 traps.
  • A muting permission set can only remove permissions granted by permission sets within the same group — never permissions coming from the profile itself.

Decision Tables

Scenario → best answer

RequirementBest answer
Baseline record accessOWD
Manager sees subordinate recordsRole hierarchy
Share records to a group/roleSharing rule
Share one record manuallyManual sharing
Add extra access without changing profilePermission set
Bundle permission setsPermission set group
Remove specific permissions from a bundleMuting permission set
Respect record sharing in Apexwith sharing
Enforce user object/FLS in a queryWITH USER_MODE
Sanitize inaccessible fieldsstripInaccessible()
Safest standard UI record accessLightning Data Service
Access to Apex class from LWCProfile or Permission Set access
New component security architectureLightning Web Security

Ultra-short memory sheet

  • Profile = base permissions
  • Role = record hierarchy
  • Permission Set = extra access
  • Permission Set Group = bundle of permission sets
  • Muting Permission Set = reduce access inside a group
  • Sharing Rule = share records beyond OWD
  • Manual Sharing = share one record
  • with sharing = record-level sharing in Apex
  • WITH USER_MODE = enforce user object/FLS in SOQL
  • stripInaccessible() = sanitize records · LDS = safest UI data access

Final answer pattern

  • Problem about seeing records? → sharing / roles / OWD
  • Problem about doing things? → profile / permission set
  • Problem about Apex record visibility? → with sharing
  • Problem about Apex field/object access? → WITH USER_MODE or stripInaccessible()
  • Problem about UI record access? → Lightning Data Service

Flashcards

Active recall

Answer in your head first, then reveal. Use "Reveal all" in the header to read straight through.