Skip to content

feat(security): expand /security into an honest trust center#220

Merged
abrichr merged 2 commits into
mainfrom
feat/trust-center
Jul 20, 2026
Merged

feat(security): expand /security into an honest trust center#220
abrichr merged 2 commits into
mainfrom
feat/trust-center

Conversation

@abrichr

@abrichr abrichr commented Jul 20, 2026

Copy link
Copy Markdown
Member

Review issue #7

The /security page was too thin for the regulated buyers OpenAdapt targets. This reworks it into a full trust center that gives a security reviewer a truthful, current status for every area they ask about — with no aspirational compliance claims. (Note: the earlier "architecture built to meet SOC 2 requirements" overclaim is not present on current main; this PR makes the honest SOC 2 posture explicit and prominent so it cannot creep back.)

Same URL (/security), so every existing inbound link, the sitemap entry, and the docs.openadapt.ai "Security" header link keep resolving to one canonical trust home. I deliberately did not fork this into a separate openadapt-ops docs page — mkdocs already points its "Security" link at openadapt.ai/security, so a second page would fragment the source of truth.

Sections added, each with a verified status

Area Status shown Source / verification
Architecture & data flow In place Lifted from openadapt-flow/docs/PRIVACY.md PHI touchpoint map + docs/LIMITS.md (local / optional on-prem VLM / hosted zones; where PHI can & can't go)
Encryption & keys Partial openadapt-flow/openadapt_flow/crypto.py (opt-in AES-256-GCM, scrypt KDF), docs/phi_at_rest.md; hosted secrets vault openadapt-cloud/src/lib/secrets.ts+secretsCrypto.ts (per-org AES-256-GCM, write-only, single-use replay token); bundle manifest openadapt_flow/ir.py; TLS pinning docs/phi_in_transit.md; ingest HMAC openadapt-cloud/src/lib/runtimeValidationContract.ts
Data retention & deletion Operator-controlled Mirrors the already-live Privacy Notice §6 (local operator-owned; hosted publishes no fixed schedule)
Subprocessors In place Real list verified against Privacy Notice §4 + repo configs: Netlify, Supabase, Modal, Stripe, PostHog, Cal.com, GitHub. No default model provider (healthy replay = 0 model calls)
Identity, access & tenancy Partial openadapt-cloud migrations 0001_init.sql / 0013_fix_tenant_isolation.sql: real owner/admin/member RBAC + Postgres RLS tenant isolation. SSO/SAML/SCIM explicitly NOT available (auth = Supabase Auth)
Release integrity Partial Verified via GitHub attestations API: SLSA provenance-v1 on desktop installers (SHA256SUMS) + OpenAdapt wheel; PEP 740 PyPI attestations on flow/tray/desktop-wheel. Desktop installers unsigned (Win/Linux) / ad-hoc (macOS) — filenames literally say so; signing CI is credential-gated & disabled. No SBOM anywhere
Secure development In place openadapt-flow/SECURITY.md + dependabot.yml: SHA-pinned Actions, Dependabot, PR-gated changes, PHI choke point. (No CodeQL/SAST claimed — none exists)
Vulnerability disclosure In place openadapt-flow/SECURITY.md: private GitHub advisory, 5-business-day ack, reporter credit
Incident response Partial Reporter-facing triage is real; formal contractual IR program stated as early / scoped per engagement
DPA & BAA Scoped per engagement deploy/on-prem/COMPLIANCE.md: "we do not sign a BAA." DPA scoped per engagement
SOC 2 Not held / no active audit Conservative placeholder — see below

SOC 2 wording used (verbatim)

OpenAdapt does not hold a SOC 2 report today. There is no SOC 2 Type I or Type II attestation, and no SOC 2 audit is currently in progress. SOC 2 evaluates a service organization and its operating controls over a period of time — an architecture or a public codebase is not a substitute for an independent auditor's report, and we will not describe our design as "built to meet SOC 2" in place of an actual engagement. … When an audit is genuinely underway, this page will name the report type, the auditor, and the period — and not before.

Status chip: "No active audit." This never overclaims regardless of the true stage.

⚠️ Founder must confirm / provide before we treat these as settled

  1. SOC 2 exact stage. I used the most conservative honest wording (no audit started). If an engagement, Type I/II, or an auditor is actually in progress, tell me and I'll update to the true stage. Do not let this ship as-is if a SOC 2 effort is already underway (it would then under-claim).
  2. Security contact address. There is no security@openadapt.ai mailbox (verified: code search returns 0 hits across repos). The page uses the real channels: GitHub private advisories + hello@openadapt.ai. If you want a dedicated security@, create the mailbox and I'll switch the page to it.
  3. DPA availability. I could not confirm a DPA template exists, so the page says "contact us and we will scope one." Confirm whether a real DPA template exists to make this concrete.
  4. Incident response program. Confirm whether any formal/contractual IR commitments (breach-notification timelines, on-call) exist beyond the reporter-facing triage; I stated it as "early / scoped per engagement."
  5. Code signing timeline. Page says signing is "not yet" and installers are unsigned/ad-hoc (true today). Update if Developer ID / Authenticode credentials get configured.

publicTruth impact

No publicTruth.test.js or legalTruth.test.js assertion changed or relaxed. /security stays in the sitemap (required by the sitemap includes … trust surfaces test). The subprocessor list matches the gated Privacy Notice. All copy is honest/hedged in the house style.

Gates

  • npm test (73 node tests incl. publicTruth/legalTruth/navContract): pass
  • npm run build (static export of /security): pass
  • Prettier: clean

Not merging — for review.

🤖 Generated with Claude Code

https://claude.ai/code/session_01NyCHrzA1psrKMFfroYbzaM

abrichr and others added 2 commits July 19, 2026 20:55
Rework the thin security page into a full trust center for regulated
buyers, with a truthful current status for every area a security review
asks about — no aspirational compliance claims.

- At-a-glance status table linking to each section
- Architecture and data-flow map (local vs on-prem vs hosted boundary;
  where PHI can and cannot go), lifted from openadapt-flow docs/PRIVACY.md
- Encryption boundaries: optional AES-256-GCM at-rest bundle/checkpoint
  sealing, hosted per-org secrets vault, bundle integrity manifest,
  TLS + Windows control-channel fingerprint pinning, HMAC-bound ingest
- Data retention and deletion (operator-owned locally; no fixed hosted
  schedule yet)
- Real subprocessors: Netlify, Supabase, Modal, Stripe, PostHog, Cal.com,
  GitHub; no default model provider
- Identity/access: real org RBAC + row-level tenant isolation today;
  SSO/SAML/SCIM stated as not yet available
- Release integrity: SLSA provenance + PEP 740 attestations today;
  desktop installers unsigned/ad-hoc (signing not yet); no SBOM
- Vulnerability disclosure, incident response, and secure-development
  posture stated honestly
- DPA/BAA scoped per engagement; no standing BAA program
- SOC 2: no active audit, not held; never "built to meet SOC 2"

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The trust-center rewrite reworded the SOC 2 line to "report"; the
security-boundary e2e contract asserts the exact honest phrase
"OpenAdapt does not hold a SOC 2 attestation today". Restore it (still
fully truthful: no attestation, no report, no audit in progress).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@abrichr
abrichr merged commit f9367c8 into main Jul 20, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant