From bad954322848062324e5865768595e6a4d80e0a3 Mon Sep 17 00:00:00 2001 From: Danijel Martinek Date: Wed, 20 May 2026 12:31:07 +0000 Subject: [PATCH] docs(compliance): add pre-launch compliance checklist Two-column table covering all 22 playbook sections organised by 13 groups (Infrastructure, Data, Application, Secrets, Sub-Processors, Logging, Breach, DSR, Backup, SDLC, Workforce, Legal, Documentation). Every "Shipped by template" row names a runnable verification command. Consumer and infra responsibilities are explicitly labelled. ADR-025 deferrals (GDPR Art. 22, MFA/lockout, breach-detection patterns) are called out inline. Links outward to compliance-overview.md, all seven policy templates, audit-and-compliance.md, operator-checklist.md, and ADR-025. Co-Authored-By: Claude Sonnet 4.6 --- .../guides/pre-launch-compliance-checklist.md | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 docs/guides/pre-launch-compliance-checklist.md diff --git a/docs/guides/pre-launch-compliance-checklist.md b/docs/guides/pre-launch-compliance-checklist.md new file mode 100644 index 0000000..11fdada --- /dev/null +++ b/docs/guides/pre-launch-compliance-checklist.md @@ -0,0 +1,167 @@ +# Pre-Launch Compliance Checklist + +This checklist operationalises [ADR-025](../decisions/adr-025-eu-compliance-baseline.md)'s three-way coverage split into a checkable launch gate. Work through every section before onboarding paying customers in an EU-regulated context. For the full compliance map — ADR, guide, and template cross-references per section — see [compliance-overview.md](./compliance-overview.md). + +**Coverage labels** + +| Label | Meaning | +| --------------------------- | ----------------------------------------------------------------------------------------------------------------- | +| **Shipped by template** | The template provides this mechanically. Run the inline verification command to produce audit evidence on demand. | +| **Consumer responsibility** | You own this obligation. The template ships fill-in templates or interfaces but not the values. | +| **Infra responsibility** | Your deployment infrastructure owns this. No application-code change is sufficient. | +| **Deferred** | Explicitly deferred in ADR-025. The documented trigger condition must be met before revisiting. | + +--- + +## 1. Infrastructure + +| Obligation | Coverage | +| ------------------------------------------------------------------------------------------------------ | ------------------------ | +| EU / EEA region pinning — compute, managed database, object storage, and backups must reside in EU/EEA | **Infra responsibility** | +| TLS termination at the deploy edge — HTTPS everywhere, no plaintext HTTP fallback | **Infra responsibility** | +| Encryption-at-rest for the PostgreSQL database and any object storage buckets | **Infra responsibility** | +| Network boundary controls — VPN or bastion for admin access; firewall rules block unnecessary ingress | **Infra responsibility** | + +--- + +## 2. Data + +| Obligation | Coverage | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| PII field inventory — every Payload collection's personal-data fields tagged with `custom.pii` (`category`, `purpose`, `exportable`, `restrictable`) | **Shipped by template** — `pnpm compliance:data-map` generates `compliance/data-map.yml`; `pnpm compliance:emit-all --check` validates drift against the live schema | +| Data retention policy — every Payload collection containing PII carries a `custom.retention` schedule (`purgeSchedule` required, `activeRetention` / `coldArchive` / `postDeletion` as needed) | **Shipped by template** — `pnpm compliance:retention-policy` generates `compliance/retention-policy.yml`; `pnpm compliance:emit-all --check` validates it | +| Subject linkage declared — DSR cascade scope defined per collection following the convention in [`docs/compliance/subject-linkage.example.md`](../compliance/subject-linkage.example.md) | **Shipped by template** — subject relationships are embedded in `compliance/data-map.yml`; `pnpm compliance:emit-all --check` | +| Background retention purge wired — `core-shared/jobs/retention-purge.job.ts` reads `custom.retention` at boot and schedules per-collection purge cadence | **Shipped by template** — `pnpm test --filter @repo/core-shared -- --coverage` | + +--- + +## 3. Application + +| Obligation | Coverage | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | -------------- | -------- | ----------- | ------------------ | +| Security headers present on all responses — HSTS, `X-Frame-Options`, `X-Content-Type-Options`, `Referrer-Policy`, `Permissions-Policy`, Content-Security-Policy | **Shipped by template** — scan the deployed origin with [securityheaders.com](https://securityheaders.com) or `curl -sI https:// \| grep -i -E "strict-transport | x-frame | x-content-type | referrer | permissions | content-security"` | +| Rate limiting declared on every auth, write, and export use case (`rateLimit` manifest field set) | **Shipped by template** — `pnpm lint` (rule: `no-undeclared-rate-limit` warns on missing declarations); `pnpm conformance` | +| Cookie consent banner — EU-prominent Reject / Accept (equal visual weight) with granular consent categories | **Shipped by template** — `` in `@repo/core-ui`; `pnpm test:stories` verifies the component story | +| Consent gating on analytics and marketing use cases (`requiresConsent` manifest field set; `withConsent` wrapper wired at bind time) | **Shipped by template** — `pnpm lint` (rule: `no-undeclared-consent-check`); `pnpm conformance` | +| PII scrubbing on the observability pipeline — `sendDefaultPii: false`; `PiiScrubSpanProcessor` and `PiiScrubLogRecordProcessor` wired before every exporter | **Shipped by template** — `grep -rn "sendDefaultPii: true" apps/` must return zero results (CI grep gate in ADR-017) | + +--- + +## 4. Secrets + +| Obligation | Coverage | +| -------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | +| No secrets committed to the repository | **Shipped by template** — gitleaks runs in `ci.yml` (ADR-023); `pnpm fallow:audit` includes a secret-scan step | +| Environment variables / secret-manager inventory documented; rotation cadence agreed | **Consumer responsibility** | +| Repository secrets configured (`TURBO_TOKEN`, `WEB_NEXT_SENTRY_DSN`, `CMS_SENTRY_DSN`, etc.) | **Consumer responsibility** — see [operator-checklist.md](./operator-checklist.md) | + +--- + +## 5. Sub-Processors + +| Obligation | Coverage | +| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Sub-processor inventory generated from library-decision traces | **Shipped by template** — `pnpm compliance:sub-processors` generates `compliance/sub-processors.yml`; `pnpm compliance:emit-all --check` validates it against traces in `docs/library-decisions/` | +| Every SDK library marked `is-sub-processor: true` carries DPA-signed status, SCCs flag, `data-sent` declaration, and EU `region` in its library-decision trace frontmatter | **Shipped by template** — `pnpm lint` (rule: `pii-declaration-must-be-complete` catches incomplete sub-processor traces); ADR-022 | +| Manual entries for REST sub-processors (third-party APIs without an SDK) authored in `compliance/sub-processors.manual.yml` | **Consumer responsibility** — the generator merges manual entries automatically; format is documented in [`docs/compliance/sub-processors.example.yml`](../compliance/sub-processors.example.yml) | +| DPAs signed with all sub-processors that process personal data | **Consumer responsibility** | +| SCCs executed for sub-processors outside the EU/EEA | **Consumer responsibility** | + +--- + +## 6. Logging + +| Obligation | Coverage | +| --------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Audit logging wired for all data-access, mutation, consent, and DSR use cases (`audits` manifest field set; `withAudit` wrapper wired at bind time) | **Shipped by template** — `pnpm lint` (rule: `no-undeclared-audit` warns on missing declarations); `pnpm conformance` | +| Audit trail shipped to an append-only log store (Vector / Fluent Bit pipeline configured) | **Consumer responsibility** — see [audit-and-compliance.md](./audit-and-compliance.md) for log-shipper configuration examples and hostile-actor immutability test | +| Audit trail retention period set to ≥ 12 months (or applicable jurisdictional minimum) | **Consumer responsibility** — configure in the log-shipping sink; must survive the immutability test in [audit-and-compliance.md](./audit-and-compliance.md) | + +--- + +## 7. Breach + +| Obligation | Coverage | +| -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Breach detection surfaces active — Sentry error alerting, rate-limit exhaustion surfaced in metrics, audit-log anomaly queries enabled | **Shipped by template** — Sentry DSN configured per [operator-checklist.md](./operator-checklist.md); `pnpm conformance`; breach detection _patterns_ deferred per ADR-025 (trigger: first downstream consumer has live traffic + observability backend) | +| Incident runbook authored with GDPR Art. 33 timeline, contact chain, and SA notification template | **Consumer responsibility** — fill in [`docs/compliance/templates/incident-runbook.template.md`](../compliance/templates/incident-runbook.template.md) and commit the filled copy to `compliance/` | +| GDPR Art. 33 — Supervisory Authority notified within 72 hours of a qualifying personal-data breach | **Consumer responsibility** — runbook triggers; SA contact and submission URL filled in the runbook | +| GDPR Art. 34 — High-risk data subjects notified without undue delay | **Consumer responsibility** — runbook triggers; subject-notification template filled in the runbook | + +--- + +## 8. DSR + +| Obligation | Coverage | +| ----------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Art. 15 (access) and Art. 20 (portability) — `IDataExport` interface + `/api/gdpr/export` endpoint wired | **Shipped by template** — `pnpm test --filter @repo/core-dsr -- --coverage` | +| Art. 16 (rectification) — `IDataRectify` interface + `/api/gdpr/rectify` endpoint wired | **Shipped by template** — `pnpm test --filter @repo/core-dsr -- --coverage` | +| Art. 17 (erasure) — `IDataDelete` interface + `/api/gdpr/delete` endpoint wired; `eraseSubject` pseudonymizes the audit trail | **Shipped by template** — `pnpm test --filter @repo/core-dsr -- --coverage` | +| Art. 18 (restriction of processing) — `IProcessingRestriction` interface + `/api/gdpr/restrict` endpoint wired | **Shipped by template** — `pnpm test --filter @repo/core-dsr -- --coverage` | +| Art. 21 (objection) — `IConsent.withdraw` wired; withdrawal propagates to all consent-gated use cases | **Shipped by template** — `pnpm test --filter @repo/core-consent -- --coverage` | +| Art. 22 (automated decision-making and profiling) | **Deferred** — ADR-025: template has no ML; revisit when a downstream consumer adds automated decisions | +| DSR intake procedure, identity-validation steps, and response-log template documented | **Consumer responsibility** — fill in [`docs/compliance/templates/dsr-procedure.template.md`](../compliance/templates/dsr-procedure.template.md) and commit the filled copy to `compliance/` | + +--- + +## 9. Backup + +| Obligation | Coverage | +| -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Backup schedule, storage location (EU/EEA), encryption, and access controls documented | **Consumer responsibility** — fill in [`docs/compliance/templates/backup-policy.template.md`](../compliance/templates/backup-policy.template.md) and commit to `compliance/` | +| Restore procedure tested and results recorded; RPO / RTO targets declared | **Infra responsibility** — confirmed by executing the restore procedure documented in the filled backup policy | +| Post-deletion data disposal method declared (secure wipe / crypto-shred) | **Consumer responsibility** — document in the filled backup policy | + +--- + +## 10. SDLC + +| Obligation | Coverage | +| ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | +| Dependency vulnerability scanning — Renovate auto-merges patch / minor; Socket.dev blocks supply-chain behavioural anomalies; `npm audit` runs in CI | **Shipped by template** — `pnpm audit`; Socket GitHub App installed per [operator-checklist.md](./operator-checklist.md); ADR-023 | +| SBOM generated per release (CycloneDX format, uploaded as CI artifact) | **Shipped by template** — `cyclonedx-npm` step in `ci.yml` (ADR-023 amendment) | +| Static analysis and secret scanning — CodeQL + gitleaks run in CI on every push | **Shipped by template** — CI workflow; `pnpm fallow:audit`; ADR-023 | +| Library evaluation policy enforced — EU residency filter, socket-score gate, and library-decision trace required before any new runtime dependency | **Shipped by template** — `pnpm lint` (library-policy-nudge hook fires on new deps); ADR-022 | +| Penetration test scheduled; scope, methodology, and remediation SLA agreed | **Consumer responsibility** | + +--- + +## 11. Workforce + +| Obligation | Coverage | +| ------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Staff onboarding procedure — system access provisioning, security orientation, compliance acknowledgement, 30-day review | **Consumer responsibility** — fill in [`docs/compliance/templates/onboarding.template.md`](../compliance/templates/onboarding.template.md) and commit to `compliance/` | +| Staff offboarding procedure — access revocation checklist, device return, data handover, 30-day post-departure review | **Consumer responsibility** — fill in [`docs/compliance/templates/offboarding.template.md`](../compliance/templates/offboarding.template.md) and commit to `compliance/` | +| Device management policy — MDM enrollment, EDR, acceptable-use rules, lost / stolen device response | **Consumer responsibility** — fill in [`docs/compliance/templates/device-policy.template.md`](../compliance/templates/device-policy.template.md) and commit to `compliance/` | +| Password and MFA policy — complexity rules, rotation cadence, account lockout thresholds | **Consumer responsibility** — fill in [`docs/compliance/templates/password-policy.template.md`](../compliance/templates/password-policy.template.md) and commit to `compliance/`; **MFA + lockout implementation deferred** (ADR-025: trigger is first downstream consumer establishing auth threat model) | +| Background checks and NDAs for personnel with access to personal data | **Consumer responsibility** | +| Quarterly access review — privilege audit against current job roles | **Consumer responsibility** | +| Security awareness training completed and records kept | **Consumer responsibility** | + +--- + +## 12. Legal + +| Obligation | Coverage | +| ------------------------------------------------------------------------------------------------------------------ | --------------------------- | +| Data Processing Agreement (DPA) executed with every controller / processor counterparty | **Consumer responsibility** | +| Privacy Policy published — GDPR Art. 13 / 14 notices, lawful basis for each processing purpose declared | **Consumer responsibility** | +| Terms of Service published | **Consumer responsibility** | +| Standard Contractual Clauses (SCCs) executed for sub-processors and data transfers outside EU/EEA | **Consumer responsibility** | +| Data Protection Impact Assessment (DPIA) conducted for high-risk processing (Art. 35) | **Consumer responsibility** | +| Records of Processing Activities (RoPA) maintained and available to the Supervisory Authority on request (Art. 30) | **Consumer responsibility** | + +--- + +## 13. Documentation + +| Obligation | Coverage | +| -------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| Compliance evidence bundle generated and committed — `compliance/data-map.yml`, `compliance/retention-policy.yml`, `compliance/sub-processors.yml` | **Shipped by template** — `pnpm compliance:emit-all --check`; format documented in [`docs/compliance/README.md`](../compliance/README.md) | +| Filled policy artifacts committed to `compliance/` at repo root — one filled copy per template | **Consumer responsibility** — fill each template in [`docs/compliance/templates/`](../compliance/templates/) and commit the result to `compliance/` | +| Operator checklist actions completed — GitHub Apps installed, branch protection enabled, repository secrets set | **Consumer responsibility** — see [operator-checklist.md](./operator-checklist.md) | +| This checklist reviewed; every outstanding item resolved or explicitly accepted-as-risk before go-live | **Consumer responsibility** | + +--- + +_Part of [Epic D — Compliance docs scaffolds](../work/epics/compliance-docs-scaffolds/_epic.md). Governed by [ADR-025](../decisions/adr-025-eu-compliance-baseline.md)._