Argument 3Security and architecture

Metadata-only, drawn.

Nothing connects your org to Org Warden. What the package writes down, in its own records inside your org and in the Evidence Pack a person carries out of it, is aggregate counts, classifications, telemetry, and error codes. Never values, file contents, record Ids used as data, or per-record findings. Enforced by pack contract tests, not by promise.
The payload envelope

Two lists. The first is everything a result row or an Evidence Pack may carry. The second has no code path out of the org.

fig. 03 · what an Evidence Pack may carry
fig. 03leaves in the pack · stays in the org
Passes the boundary
countsclassificationstelemetryerror codesrule idssnapshot hashjob statusgate records
Every item that leaves the org is a shape or a signal, never the underlying value.
org boundary
Never leaves the org
valuesfile contentsrecord Ids as dataper-record findingsVersionDataraw regex hitsquery resultsuser identifiers
These items have no code path out of the Salesforce org. Not by policy. By absence of the code that would move them.
Defence in depth

Three layers of write control. If any layer fails, the next one stops the write.

Distribution is not the control. Neither is the runtime check on its own. The write gate is the third and last line. All three are asserted by tests.

fig. 04three concentric layers · one DML call at the centre
blocked at Layer 1 · code does not exist
Layer 1 · INV-2 · Core has no write code
Layer 2 · INV-3 · Sandbox check at dispatch
Layer 3 · INV-3 · Five-check write gate
The DML call
can only reach a customer object after passing all three
sandbox only · after dry-run + gate
Layer 1INV-2
No write code in production
orgwarden-core, the only package installable in production, contains zero DML against customer sObjects. A static check reports every DML statement in core on each CI run; the control is a runtime proof that installs core in a fresh org and shows no write path, wired into CI and waiting on a Dev Hub to run. There is nothing to gate because there is nothing to disable.
Layer 2INV-3
Sandbox check at dispatch
The dispatcher refuses a REDACT job before a chunk starts if Organization.IsSandbox is false, and the handler checks again. Belt to the braces above.
Layer 3INV-3
Five-check write gate
A live redaction run starts only if all five answer yes: the org is a sandbox; redaction is switched on in that org; the running user holds the approver permission set; the request names a Done dry-run with identical scope hash and correlation id, with results present; and every target field is updateable. A refusal is written as a result row, not thrown as an error. The gate runs inside the redaction handler, behind the dispatcher's own refusal, regardless of what the Console displays.
The invariants

Eight testable claims. Every one has a corresponding test suite. If a test breaks, the release does not ship.

These are not marketing copy. They are the sentences a security reviewer can grep for in the codebase.

INV-1
Metadata-only egress.
Result rows and Evidence Packs carry counts, classifications, telemetry, error codes. Never values, file contents, record Ids used as data, or per-record findings.
pack contract tests
INV-2
Zero write code in production.
orgwarden-core contains no DML against customer objects anywhere in its codebase. Not gated. Absent.
static report · runtime proof
INV-3
Defence in depth on writes.
orgwarden-redact hard-gates at runtime on Organization.IsSandbox == true, checked on every write-job start.
dispatcher test
INV-4
One choke point.
Exactly one code path (Core dispatcher) authorises job execution. Handlers contain zero authorisation logic.
dispatch path
INV-5
Records are the API.
Jobs are requested, scoped, and reported via queryable custom objects. Both packages function with zero control-plane connectivity.
contract objects
INV-6
Polite tenancy.
Async consumption is paced, measured, and reported. The pacing is structural: each request runs as one serial chain or one batch, every async transaction it consumes is counted on the request, and the only cross-request cap is the platform’s concurrent-batch ceiling. There is no pacing dial. A stalled request is recovered, never re-run blind.
async meter · batch model
INV-7
Tenant isolation in the app.
Every query tenant-scoped. RLS on every table, enforced by the database. The tenant comes from a signed, server-checked session, never from the request.
RLS + signed session
INV-8
With sharing by default. Two elevated reads, named.
Every class runs with sharing and enforces field-level security, except two reads elevated on purpose, each one grep away: the detection page read, a private inner class in DetectHandler, and the setup-entity queries in SchemaFieldInventory. They are elevated so a scan is not narrowed by who launched it: a scan that sees only what one user can see reports a clean result for data it never looked at. The proof of that against a restricted user is on the run list, so until it runs every count is a lower bound. The elevated reads record only counts and classifications and cannot write. The redaction path checks per-field isUpdateable() and holds no elevation. Bind variables everywhere.
decision records 2026-07-30 · 2026-08-20
What we will not say

We will not publish an unverifiable statistic. We will not put a badge-wall on this page. We will not imply a certification we do not hold. Every claim on this site has a corresponding test, a corresponding line of code, or a linked artefact.

If you spot something on this page you would like to reproduce yourself, email security@orgwarden.co.uk and we will walk you through the assertion in the code.

Free baseline scan

Scan one org free. See where your PII lives.

No install-to-buy. You get a Baseline Report (the same artefact paying customers get) for one Salesforce org. Metadata-only, always. Your data never leaves your org.

Work email · we reply within 1 business day
Next argument · 4
Compare. Why not Shield, Varonis, or AppOmni.
Adjacent tools. One drawing places each of them next to what Org Warden actually does.