SfSkills Domains Docs GitHub

Home / architect / security-architecture-review

security-architecture-review

Use when conducting a dedicated security architecture review of a Salesforce org — assessing sharing model completeness, FLS/CRUD enforcement, Apex security patterns, exposed API surface, Connected App policies, and Shield readiness.

Open the skill folder on GitHub


Use this skill when you need a dedicated, deep-dive security architecture review of a Salesforce org. Where the well-architected-review skill surveys all three WAF pillars at breadth, this skill goes deep on the Trusted pillar — examining the sharing model, field-level security, Apex code security patterns, API exposure, Connected App configuration, and Shield licensing decisions. It produces a structured findings report with severity ratings and a comprehensive checklist, suitable for delivery to a security team, a compliance officer, or an architecture review board.

This skill does not cover implementation of fixes. Once findings are identified, route to apex/apex-security-patterns, apex/soql-security, or security/ domain skills for remediation guidance.


Before Starting


Questions to Ask Before Configuring

Ask these before scoring a single checklist item. Each traces to a gotcha in references/gotchas.md.

QuestionWhy it mattersWhat a good answer addsWhat a proper review adds over just doing it
"When was the org created, and does it have Experience Cloud sites or guest access?"Pre-Spring '20 orgs inherited external defaults from internal ones (Gotcha 1); personal-info settings are not enforced in Apex (Gotcha 7)The external surface to review and the default-access historyExternal exposure is reviewed from the real defaults, not assumed Private
"Which API version are the Apex classes and triggers saved at?"Undeclared sharing and access mode flip at 67.0 (Gotchas 2 and 5)A version-bucketed class inventoryFindings score each class on its own version, not on the org release
"Which integrations use connected apps, which use external client apps, and which are planned?"New connected apps are restricted as of Spring '26 (Gotcha 6)An OAuth app inventory with owners and last useRemediation proposes something the org can actually create
"Which code runs as the Automated Process user or another non-human user?"Automated Process users need permission sets for access checks (Gotcha 8)The running user per async entry pointAccess checks are tested under the user that runs them
"How far back must audit evidence go?"Setup Audit Trail covers at least 180 days only (Gotcha 9)A retention requirement and an export planEvidence exists when the auditor asks
"Where are secrets stored today?"Protected settings protect only inside managed packages (Gotcha 11)A secret inventory with storage locationEvery exposed secret is moved and rotated, not just noted

What a proper review adds over "just running Health Check": each finding is scored against the version, user, and default-access facts that make it real or not, and remediation names mechanisms the org can still create.


Review Domains

Domain 1: Sharing Model Completeness

The sharing model defines who can see and modify which records. A misconfigured sharing model is one of the highest-impact security risks in a Salesforce org because it is difficult to audit retrospectively and often grows more permissive over time.

Checklist items:

  1. OWD settings per object — Every custom object and every standard object holding sensitive data must have its OWD documented and justified. "Public Read/Write" on objects holding financial, health, or personal data is a Critical finding. "Public Read Only" on those same objects is High unless a specific business reason is documented.
  2. Sharing rules coverage — Are sharing rules granting access beyond the role hierarchy? Review each sharing rule: criteria-based rules can grant overly broad access if the criteria are poorly designed. Role-and-subordinates sharing rules grow in scope as the role hierarchy expands.
  3. With sharing / without sharing Apex — Every Apex class that performs DML or queries should have an explicit sharing declaration. Classes using without sharing should be documented with a reason. Classes using inherited sharing should be traced to their caller chain to confirm the caller enforces sharing. What a missing declaration means is version-gated on the apiVersion in the class's .cls-meta.xml, not the org's release: at 67.0+ (Summer '26) a bare public class Foo runs with sharing, and so does any class whose inheritance chain contains a 67.0+ class; at 66.0 and earlier the same class runs without sharing. Read the meta file before scoring an absent keyword — on a 58.0 class it is a live exposure, on a 67.0 class it is a documentation gap. Apex triggers are a special case, and the usual summary of it is wrong. A trigger cannot carry a sharing keyword — the Apex Developer Guide says it "always run[s] implicitly in a without sharing context" — but that is the baseline, not the outcome. The same page states that "database operations within trigger bodies ... run in user mode unless system mode is explicitly specified", and that "user mode overrides the trigger's without sharing context". So at 67.0+ a bare query in a trigger body enforces sharing, FLS and CRUD; only an explicit WITH SYSTEM_MODE / AccessLevel.SYSTEM_MODE falls back to bypassing all three. Score each trigger query on its own access mode and the trigger's .trigger-meta.xml apiVersion — never on the absent keyword — and review the handler class as well. Canonical table: 9 § Apex security idiom by API version.
  4. Community / Experience Cloud external OWD — External OWD settings are separate from internal OWD. Correction (2026-10-03): earlier text said an object set to "Private" internally can be "Public Read Only" externally; the Security Guide says the external access level cannot be more permissive than the internal level. The real risk is older orgs: for orgs created before Spring '20, external defaults were set to the original (often Public) defaults, while newer orgs default external access to Private. Review all objects accessible in Experience Cloud sites against their external OWD.
  5. Manual sharing and Share objects — Review whether manual shares (AccountShare, OpportunityShare, etc.) are present at scale. Manual shares are invisible in standard UI reports and can accumulate over years without review.
  6. Role hierarchy depth and scope — An overly flat hierarchy grants broad data visibility to senior roles. Review whether roles at the top of the hierarchy genuinely need visibility to all subordinate records or whether territory management or criteria-based sharing would be more appropriate.

Domain 2: Field-Level Security and CRUD Enforcement

Field-Level Security (FLS) controls which fields individual users can read and write. CRUD controls whether they can create, read, update, or delete records of a given object. Violations allow authenticated users to read or modify data they should not access, even if the sharing model is correct.

Checklist items:

  1. FLS enforcement in Apex — Whether Apex bypasses FLS with no keyword at all is version-gated on the class's apiVersion: at 66.0 and earlier SOQL, SOSL, DML, and Database methods run in system mode and bypass FLS and CRUD; at 67.0+ they run in user mode by default and enforce them. Review all Apex classes that read or write sensitive fields, checking the API version first. Enforcement mechanisms: WITH USER_MODE on the query (GA in API 57.0, Spring '23), as user or AccessLevel.USER_MODE on DML and Database methods, or Security.stripInaccessible(AccessType.READABLE, records) — which returns an SObjectAccessDecision, so operate on .getRecords(). WITH SECURITY_ENFORCED is legacy tech debt at 57.0–66.0 and does not compile at 67.0+; flag it rather than scoring it as clean. Canonical table: 10 § Apex security idiom by API version.
  2. CRUD enforcement in Apex — Before performing DML, Apex should verify the current user has create/read/update/delete permission on the object. Use Schema.sObjectType.Account.isAccessible() (or isCreateable() / isUpdateable() on the describe for writes), or rely on user-mode DML — as user / AccessLevel.USER_MODE, which is also the default at apiVersion 67.0+. WITH USER_MODE is a SOQL clause and is not valid on a DML statement.
  3. AuraEnabled and LWC wire methods — with sharing on the class does not by itself enforce FLS on what @AuraEnabled methods and wire adapters return; record-level sharing and field-level security are separate controls. Below 67.0 those queries bypass FLS unless one of the item-7 mechanisms is used; at 67.0+ they default to user mode. Review all @AuraEnabled methods for FLS enforcement on fields returned to the UI.
  4. Integration user FLS — Integration users (named credentials, connected app users) often have broad profiles because they "need access to everything." Review the integration user's profile and permission sets against the minimum necessary access principle. A CRUD-level over-permission on an integration user is a High finding.
  5. Visualforce and field references — Visualforce pages that reference fields via {!record.Field__c} will render even if the running user has no FLS read permission on that field — Visualforce does not enforce FLS automatically (UNVERIFIED 2026-10-03: no fetched guide states the Visualforce FLS behavior either way; test with a restricted user). Any VF page displaying sensitive fields must use $ObjectType.describe() checks or be replaced with an LWC that enforces FLS server-side.

Domain 3: Apex Security Patterns

Insecure Apex code can bypass the sharing model, enable data exfiltration, or allow privilege escalation. Review focuses on injection, encoding, and system-context risks.

Checklist items:

  1. SOQL injection — Dynamic SOQL built by string concatenation with user-supplied input is a Critical finding. Check all classes that use Database.query() with string variables that originate from user input, URL parameters, or external system payloads. Remediation: use bind variables or String.escapeSingleQuotes().
  2. SOSL injection — Same pattern as SOQL but for Search.query(). Less common but equally severe.
  3. Encoding in Visualforce — All output rendered in Visualforce should use {!HTMLENCODE(value)} or equivalent. Unencoded output of user-controlled strings enables stored XSS. The Apex Developer Guide ("Security Tips for Apex and Visualforce Development") says nearly all Visualforce tags escape by default, so concentrate on escape="false" and formulas outside components.
  4. Hardcoded credentials and sensitive strings — Passwords, tokens, client secrets, and encryption keys must not be stored in Apex code, Custom Labels, or Custom Metadata that is accessible to all users. Use Named Credentials for endpoint authentication and Protected Custom Metadata for secrets. Correction (2026-10-03): the Apex Developer Guide says protection applies only inside a managed package, and that outside one you should use named credentials or encrypted custom fields; protected custom metadata is a packaging tool, not a secrets store for an unpackaged org.
  5. System-context callouts — Apex making callouts in system context (batch jobs, future methods, platform events) should be reviewed to confirm they do not relay data the calling user could not access directly. Below 67.0 an async class with no sharing declaration is in system context by default; at 67.0+ it is not, so the finding there is an explicit without sharing, as system, or WITH SYSTEM_MODE rather than an absent keyword.

Domain 4: API Surface and Connected Apps

Every Connected App is an OAuth entry point. Misconfigured Connected Apps allow credential theft, session hijacking, and unauthorized data export. The Security Guide notes that connected app creation is restricted as of Spring '26 and recommends external client apps, so review both inventories (ConnectedApplication and ExternalClientApplication in the Object Reference). UNVERIFIED (2026-10-03): the IP relaxation, scope, and token-policy behavior in items 17–19 is Help-only.

Checklist items:

  1. IP relaxation on Connected Apps — Connected Apps with "Relax IP restrictions" allow access from any IP address without MFA step-up. This is a High finding for any app not explicitly approved for IP-unrestricted access. Review each Connected App's IP policy.
  2. OAuth scope breadth — Connected Apps with full or api scope have unrestricted access to all objects the authorized user can access. Review whether each app's scope can be narrowed. A Connected App used only for reading Account data should not hold full scope.
  3. Session policy and token lifetime — Review session security level and token validity settings per Connected App. Refresh tokens that never expire combined with IP relaxation are a Critical finding for apps holding sensitive data.
  4. Unused or dormant Connected Apps — Connected Apps that have not been used in 90+ days should be reviewed for deactivation. Each dormant app is a latent attack surface. Evidence: OauthToken.LastUsedDate and UseCount per AppName (Object Reference; a user with Customize Application sees all users' tokens).
  5. Named Credential certificate management — Named Credentials using JWT or certificate-based auth should have documented certificate expiry dates and a renewal process. Expired certificates cause integration failures; unrotated credentials are a security risk.

Domain 5: Shield Needs Assessment

Salesforce Shield comprises three capabilities: Event Monitoring, Field Audit Trail, and Platform Encryption. This domain assesses whether the org's data profile and compliance obligations require Shield.

Assessment criteria:

CriterionEvent MonitoringField Audit TrailPlatform Encryption
Org holds HIPAA-regulated PHIRequiredRequiredRequired
Org holds PCI-DSS cardholder dataRequiredRequiredRequired
Org subject to FedRAMPRequiredRequiredRequired
SOC 2 Type II audit scopeRecommendedRecommendedRecommended
Org has 500+ users with data export accessRecommendedNot requiredNot required
Fields store SSN, passport, or financial account numbersNot requiredRecommendedRequired
Org has experienced a data breachRequiredRequiredRecommended

If two or more "Required" criteria are met, a Shield licensing conversation is a Critical finding. If only "Recommended" criteria are met, it is a Medium finding with a recommendation to evaluate Shield.


Severity Rating Definitions

SeverityDefinitionExpected Response
CriticalExploitable risk with high likelihood or high impact on regulated dataRemediate before go-live or within 72 hours in production
HighSignificant risk or compliance gap not yet exploitedRemediate within the current sprint or within 2 weeks
MediumRisk present but requires additional conditions to exploitSchedule remediation within the quarter
LowBest-practice deviation with minimal exploitabilityAddress in next maintenance cycle

Review Sequence

  1. Gather inputs (see frontmatter inputs section above).
  2. Complete the 21-point checklist across all five domains.
  3. Rate each finding (Critical / High / Medium / Low / N/A).
  4. Complete the Shield Needs Assessment table.
  5. Produce the findings report: findings table, Shield recommendation, and prioritized remediation backlog.
  6. Route Critical and High findings to appropriate security/ or apex/ skills for remediation.


Official Sources Used

See references/well-architected.md for fetch status on 2026-10-03 and the PDFs read in this pass.

  1. Ask the six questions in "Questions to Ask Before Configuring" and record the org creation date, API-version spread of Apex, OAuth app inventory, and audit retention requirement.
  2. Collect evidence with the queries in references/examples.md Example 3 (privileged permission holders, external defaults, dormant tokens, Setup Audit Trail export), saving raw output with timestamps.
  3. Work the 21 checklist items across the five domains, scoring each Apex finding on its class's apiVersion and each external finding on the external default.
  4. Complete the Shield Needs Assessment and rate every finding with the severity definitions.
  5. Fill templates/security-architecture-review-template.md, then run python3 skills/architect/security-architecture-review/scripts/check_security_architecture_review.py <completed-review.md> to confirm the five domains, scorecard, severity table, Shield assessment, and remediation backlog are all present.
  6. Route Critical and High findings to the remediation skills under Related Skills; this skill stops at the findings report and backlog.

Package files