Identity and Access Management - Patterns
Learn more about Well-Architected Trust → Identity and Access Management
Patterns
| Where to look | What good looks like |
|---|---|
| Platform | Architecture | ✅ Access controls verify identity explicitly on every request, independent of network location or device |
| Platform | Architecture | ✅ Identity-based security controls replace network-based trust assumptions |
| Platform | Org | ✅ Access decisions consider who is requesting access (authentication), what they are authorized to do (authorization), and context (device, location) |
| Platform | Documentation | ✅ Security architecture documents identity as the primary trust boundary, not network perimeter |
Anti-Patterns
| Where to look | What bad looks like |
|---|---|
| Platform | Architecture | ⚠️ Users on corporate network or VPN are assumed trustworthy and granted broader access based on network position alone |
| Platform | Architecture | ⚠️ Access controls rely on network perimeter rather than identity verification |
| Platform | Org | ⚠️ Access decisions do not consider context signals (device, location, time, behavior patterns) |
| Platform | Documentation | ⚠️ Security architecture treats network location as primary trust boundary |
Patterns
| Where to look | What good looks like |
|---|---|
| Platform | Org | ✅ Solutions leverage all four Salesforce access layers: Organization (licenses, features), Object (CRUD), Field (FLS), Record (sharing) |
| Platform | Org | ✅ Access model is designed top-down (org → object → field → record) and validated bottom-up |
| Platform | Org | ✅ Organization-wide defaults (OWD) are set to Private for objects containing sensitive data |
| Platform | Org | ✅ OWDs set to Public Read Only are limited to reference objects (products, price books) where broad visibility supports business without exposing risk |
| Platform | Org | ✅ Organization-level constraints (licenses, IP ranges, login hours, feature permissions) define baseline capabilities for user populations |
| Platform | Org | ✅ Object permissions (via profiles and permission sets) control create, read, edit, and delete access to each object for user segments |
| Platform | Org | ✅ Field-level security protects sensitive fields even when object access is granted |
| Platform | Org | ✅ Record-level sharing uses role hierarchy and sharing rules based on documented business requirements |
| Platform | Org | ✅ Access is expanded deliberately from restrictive baseline, not restricted after permissive defaults |
Anti-Patterns
| Where to look | What bad looks like |
|---|---|
| Platform | Org | ⚠️ Access model does not leverage all four layers (organization, object, field, record) |
| Platform | Org | ⚠️ OWDs are set to Public Read/Write for convenience during development without restriction plans |
| Platform | Org | ⚠️ Overly permissive OWDs set early become exponentially harder to restrict as data volume grows and business processes crystallize |
| Platform | Org | ⚠️ Field-level security is not configured, relying solely on object or record-level access controls |
Patterns
| Where to look | What good looks like |
|---|---|
| Platform | Org | ✅ Multi-factor authentication (MFA) is enforced for all users accessing production environments (mandatory for UI access) |
| Platform | Org | ✅ MFA is extended to privileged operations including bulk data exports, permission changes, and administrative configuration |
| Platform | Org | ✅ Single sign-on (SSO) uses SAML 2.0 or OpenID Connect protocols |
| Platform | Org | ✅ Session timeout is configured appropriately: 2 hours for standard users, 15-30 minutes for administrators and users accessing Restricted data |
| Platform | Org | ✅ IP restrictions are enforced for administrative profiles and integration users |
| Platform | Org | ✅ Login hours restrict service accounts to expected operational windows |
| Platform | Org | ✅ Native device activation verifies logins from unrecognized devices; MFA and IP restrictions add protection for high-privilege accounts |
| Platform | Org | ✅ If SSO is enabled, approved admin users have direct login access (break-glass procedures) |
| Platform | Org | ✅ The relationship between users and entities logging into Salesforce is 1:1 (no shared user accounts) |
| Platform | Org | ✅ API Access Control prevents users from authenticating via unauthorized connected apps |
| Platform | Named Credentials | ✅ Named credentials and external credentials manage authentication centrally with rotation capabilities |
| Platform | Named Credentials | ✅ Named credentials abstract authentication details from code, enabling credential updates without code changes |
| Platform | Named Credentials | ✅ Credentials are never embedded in code, configuration files, or version control |
| Platform | Apex | ✅ Methods that execute authentication use named credentials to handle username/password flows |
| Platform | Apex | ✅ No usernames or passwords appear in code in readable formats (no hard-coded values or strings) |
| Platform | Aura | ✅ Methods that execute authentication use named credentials to handle username/password flows |
| Platform | Aura | ✅ No usernames or passwords appear in code in readable formats |
| Platform | Lightning Web Components (LWC) | ✅ Methods that execute authentication use named credentials |
| Platform | Lightning Web Components (LWC) | ✅ No usernames or passwords appear in code |
| Integration | API | ✅ OAuth 2.0 JWT bearer flow is used for server-to-server integrations in trusted environments (preferred for production integrations) |
| Integration | API | ✅ OAuth 2.0 web server flow is used for server-to-server integrations requiring user context |
| Integration | API | ✅ OAuth 2.0 device flow is used for headless devices; CLI and CI/CD tooling use web server flow (sf org login web) or JWT bearer flow (sf org login jwt) — device flow was blocked for the default Salesforce CLI connected app as of Aug 28, 2025 |
| Integration | API | ✅ Username-password OAuth flow is not used; existing integrations that rely on it are migrated to JWT bearer or client credentials flow |
Anti-Patterns
| Where to look | What bad looks like |
|---|---|
| Platform | Org | ⚠️ MFA is not enforced for production environment access |
| Platform | Org | ⚠️ Login configurations do not align to Salesforce MFA requirements |
| Platform | Org | ⚠️ MFA is not extended to privileged operations (bulk exports, permission changes, administrative configuration) |
| Platform | Org | ⚠️ Session timeout is not configured or is excessively permissive (>24 hours) |
| Platform | Org | ⚠️ Session policies do not differentiate between standard users and administrators/users accessing Restricted data |
| Platform | Org | ⚠️ IP restrictions are not enforced for administrative profiles and integration users |
| Platform | Org | ⚠️ Service accounts do not have login hours restricted to expected operational windows |
| Platform | Org | ⚠️ High-privilege accounts rely on nothing beyond device activation — no MFA or IP restrictions added |
| Platform | Org | ⚠️ If SSO is enabled, no approved admin users have direct login access (no break-glass procedures) |
| Platform | Org | ⚠️ The relationship between users and entities is not 1:1 (shared user accounts exist) |
| Platform | Org | ⚠️ API Access Control is not enabled |
| Platform | Named Credentials | ⚠️ Credentials are embedded directly in code, configuration files, or version control |
| Platform | Apex | ⚠️ Usernames and passwords appear in code in readable formats |
| Platform | Apex | ⚠️ Authentication is handled ad hoc without consistent implementation |
| Platform | Aura | ⚠️ Authentication is handled ad hoc without named credentials |
| Platform | Aura | ⚠️ Usernames and passwords appear in code |
| Platform | Lightning Web Components (LWC) | ⚠️ Authentication is handled ad hoc without named credentials |
| Platform | Lightning Web Components (LWC) | ⚠️ Usernames and passwords appear in code |
| Platform | Business | ⚠️ User provisioning and deprovisioning SLAs and requirements do not exist |
| Integration | API | ⚠️ Username-password OAuth flow is used when more secure OAuth flows are available |
| Integration | API | ⚠️ OAuth scopes are overly permissive (full access when limited scope is sufficient) |
| Integration | API | ⚠️ Client credentials (client ID, client secret) are stored insecurely in code or config files |
Patterns
| Where to look | What good looks like |
|---|---|
| Platform | Org | ✅ Role hierarchy depth is 5-7 levels maximum (avoiding performance overhead and troubleshooting complexity) |
| Platform | Org | ✅ Permission sets and permission set groups provide flexible, additive access without profile proliferation |
| Platform | Org | ✅ Permission sets grant access for specific job functions, applications, or temporary elevated privileges |
| Platform | Org | ✅ Permission set groups combine related permission sets with muting capabilities for exceptions |
| Platform | Org | ✅ All functional access is granted through permission sets and permission set groups (not profiles), providing flexibility as job roles evolve |
| Platform | Org | ✅ Transaction Security policies extend authorization with real-time contextual evaluation |
| Platform | Org | ✅ Transaction Security policies detect and block anomalous behavior (bulk data downloads exceeding patterns, login from unexpected geographies, permission changes outside change windows) |
| Platform | Org | ✅ IP restrictions are configured for highly sensitive operations or data access |
| Platform | Org | ✅ A unique API-only integration user is configured for every integration |
| Platform | Apex | ✅ All code accessing data enforces CRUD and FLS using WITH USER_MODE, WITH SYSTEM_MODE keywords or Security.stripInaccessible() methods |
| Platform | Apex | ✅ SOQL queries use WITH USER_MODE or WITH SYSTEM_MODE keywords explicitly based on business requirements |
| Platform | Apex | ✅ DML operations use Security.stripInaccessible() for access enforcement before insert/update/upsert operations |
| Platform | Apex | ✅ Database DML statements declare user or system mode explicitly for data operations |
| Platform | Apex | ✅ Database operations use stripInaccessible() methods to filter query and subquery results |
| Platform | Apex | ✅ Sharing keywords (with sharing, without sharing, inherited sharing) are used appropriately based on business security requirements |
| Platform | Design Standards | ✅ Use cases for granting elevated privileges (Modify All Data, View All Data) are clearly documented with business justification |
Anti-Patterns
| Where to look | What bad looks like |
|---|---|
| Platform | Org | ⚠️ Role hierarchy is deeper than 5-7 levels, creating performance overhead in sharing calculations and troubleshooting complexity |
| Platform | Org | ⚠️ Role hierarchy grants broad access without business justification |
| Platform | Org | ⚠️ Profiles are cloned repeatedly for minor permission variations, creating dozens of profiles with unclear distinctions |
| Platform | Org | ⚠️ Profiles contain access controls for metadata (should use permission sets) |
| Platform | Org | ⚠️ Transaction Security policies are not implemented to detect anomalous behavior |
| Platform | Org | ⚠️ IP restrictions are not configured for highly sensitive operations or data access |
| Platform | Org | ⚠️ API-only users are not configured or are shared across multiple integrations |
| Platform | Org | ⚠️ View All Data or Modify All Data permissions are granted without documented justification |
| Platform | Apex | ⚠️ SOQL/SOSL queries and DML operations run in default system mode without explicit access checks |
| Platform | Apex | ⚠️ CRUD and FLS enforcement is inconsistent or missing |
| Platform | Apex | ⚠️ SOQL relies on WITH SECURITY_ENFORCED, which has been removed and now causes a compilation error (replace with WITH USER_MODE) |
| Platform | Apex | ⚠️ Sharing keywords are used inconsistently or not at all |
| Platform | Design Standards | ⚠️ Use cases for granting elevated permissions are not clearly documented |
Patterns
| Where to look | What good looks like |
|---|---|
| Platform | Data 360 | ✅ RBAC (roles, profiles, permission sets) controls platform access (who can use Data 360), ABAC controls data access (what data they see based on attributes) |
| Platform | Data 360 | ✅ AI agents execute in the requesting user’s context (on-behalf-of), so agent-generated queries are constrained by that user’s access rather than running with system-level access |
| Platform | Documentation | ✅ Data classification taxonomy is documented with attribute definitions, enforcement rules, and business justification |
Anti-Patterns
| Where to look | What bad looks like |
|---|---|
| Platform | Data 360 | ⚠️ Access that must follow data classification is forced through role hierarchy and sharing, which cannot express it, instead of reaching for attribute-based access control |
| Platform | Data 360 | ⚠️ FLS bypass: users without field-level access retrieve data via API or SOQL queries that don’t enforce FLS |
| Platform | Data 360 | ⚠️ AI agents query data without executing in the requesting user’s context; agent-generated queries bypass object-, field-, and record-level access controls |
| Platform | Data 360 | ⚠️ Agent execution context does not include user-on-behalf-of attributes; agents operate with system-level access |
| Platform | Documentation | ⚠️ Data classification taxonomy is undocumented; attribute definitions vary by team creating inconsistent enforcement |
Patterns
| Where to look | What good looks like |
|---|---|
| Platform | Org | ✅ Critical impact accounts (system administrators, integration users, automated process accounts) are identified and tracked in asset inventory |
| Platform | Org | ✅ Critical impact accounts represent high-value targets due to elevated privileges providing broad platform access |
| Platform | Org | ✅ Hardware security keys or authenticator apps are required for MFA (not SMS, which is vulnerable to SIM swapping) |
| Platform | Org | ✅ Login IP ranges are restricted to known administrative locations |
| Platform | Org | ✅ Login alerts and permission change notifications are enabled |
| Platform | Org | ✅ Quarterly access reviews are conducted with documented attestation |
| Platform | Org | ✅ Break-glass procedures exist for emergency access with post-use audit |
| Integration | Service Accounts | ✅ OAuth flows are used for integration and service accounts (never username-password) |
| Integration | Service Accounts | ✅ IP restrictions are enforced for integration users |
| Integration | Service Accounts | ✅ Credential rotation schedules are implemented (quarterly or per policy) |
| Integration | Service Accounts | ✅ Anomalous API usage patterns are monitored through Event Monitoring |
| Integration | Service Accounts | ✅ Each integration has a dedicated service account with minimum required permissions (not shared “integration user” with broad access) |
| Integration | Service Accounts | ✅ Service accounts apply least privilege rigorously since they operate unattended |
Anti-Patterns
| Where to look | What bad looks like |
|---|---|
| Platform | Org | ⚠️ Critical impact accounts (admin, integration, automation) are not identified, tracked, or inventoried |
| Platform | Org | ⚠️ System administrators use SMS-based MFA instead of hardware security keys or authenticator apps |
| Platform | Org | ⚠️ Critical impact accounts have no login hour or IP restrictions |
| Platform | Org | ⚠️ No alerts are configured for login or permission changes on privileged accounts |
| Platform | Org | ⚠️ Critical impact account access is never reviewed or reviewed irregularly (not quarterly) |
| Platform | Org | ⚠️ No break-glass procedures exist for emergency access |
| Integration | Service Accounts | ⚠️ A single “API User” account is shared across multiple integrations with Modify All Data permission |
| Integration | Service Accounts | ⚠️ Service accounts use username-password authentication when OAuth is available |
| Integration | Service Accounts | ⚠️ Service account credentials use static passwords unchanged for years (no rotation) |
| Integration | Service Accounts | ⚠️ Service accounts have excessive privileges beyond what integration requires |
| Integration | Service Accounts | ⚠️ Anomalous API usage patterns for service accounts are not monitored |
Patterns
| Where to look | What good looks like |
|---|---|
| Platform | Process | ✅ Identity lifecycle includes: Provisioning (create with baseline access), Access adjustment (grant/revoke as roles change), Periodic recertification (quarterly validation), Deprovisioning (immediate revocation) |
| Platform | Org | ✅ SCIM (System for Cross-domain Identity Management) is implemented for automated provisioning from identity providers |
| Platform | Process | ✅ Provisioning creates accounts with baseline access matching job function, triggered by HR system events |
| Platform | Process | ✅ Access adjustment grants additional permissions as roles expand and revokes permissions when roles change |
| Platform | Process | ✅ Periodic recertification occurs quarterly where managers review and validate access for their teams |
| Platform | Process | ✅ Deprovisioning revokes access immediately when employment ends or role no longer requires Salesforce |
| Platform | Org | ✅ Automated detection identifies users who have not logged in within 90 days and triggers access review workflows |
| Platform | Org | ✅ Just-in-time (JIT) provisioning creates users automatically from SSO when appropriate |
Anti-Patterns
| Where to look | What bad looks like |
|---|---|
| Platform | Org | ⚠️ SCIM provisioning is not implemented despite having identity provider integration |
| Platform | Process | ⚠️ New users are created manually without standard onboarding procedures |
| Platform | Process | ⚠️ Initial user access is inconsistent or based on copying existing users |
| Platform | Process | ⚠️ Access changes for role changes or transfers are delayed or incomplete |
| Platform | Process | ⚠️ Offboarding is delayed; former employees retain access after termination (not same-day deactivation) |
| Platform | Org | ⚠️ No automation exists for user provisioning (manual user creation only) |
| Platform | Process | ⚠️ No access recertification campaigns exist (no quarterly or annual review) |
| Platform | Process | ⚠️ Unnecessary access identified during recertification is not removed |
| Platform | Process | ⚠️ Access recertification is not rigorous for privileged accounts, cross-org access, external users |
| Platform | Org | ⚠️ Dormant accounts (no login in 90+ days) accumulate without review or deactivation |