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
- What is the scope? Full org or a specific solution/integration? Scope determines which checklist sections are mandatory.
- What are the regulatory requirements? HIPAA, PCI-DSS, GDPR, FedRAMP, and SOC 2 each have specific control requirements that shape which findings are Critical vs Low.
- Is Shield licensed? Event Monitoring, Field Audit Trail, and Platform Encryption are add-ons. The review will assess whether they are needed even if not yet licensed.
- Are there external users? Experience Cloud sites change the OWD calculation — external OWD settings are independent of internal OWD and are frequently misconfigured.
- What integrations exist? REST/SOAP APIs, Connected Apps, and named credentials each have their own exposure surface.
Questions to Ask Before Configuring
Ask these before scoring a single checklist item. Each traces to a gotcha in references/gotchas.md.
| Question | Why it matters | What a good answer adds | What 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 history | External 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 inventory | Findings 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 use | Remediation 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 point | Access 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 plan | Evidence exists when the auditor asks |
| "Where are secrets stored today?" | Protected settings protect only inside managed packages (Gotcha 11) | A secret inventory with storage location | Every 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:
- 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.
- 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.
- With sharing / without sharing Apex — Every Apex class that performs DML or queries should have an explicit sharing declaration. Classes using
without sharingshould be documented with a reason. Classes usinginherited sharingshould be traced to their caller chain to confirm the caller enforces sharing. What a missing declaration means is version-gated on theapiVersionin the class's.cls-meta.xml, not the org's release: at 67.0+ (Summer '26) a barepublic class Foorunswith 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 explicitWITH SYSTEM_MODE/AccessLevel.SYSTEM_MODEfalls back to bypassing all three. Score each trigger query on its own access mode and the trigger's.trigger-meta.xmlapiVersion — never on the absent keyword — and review the handler class as well. Canonical table: