Fix broken forward reference to compliance-overview.md (story 05 output) by replacing the hyperlink with plain text annotated as forthcoming. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
168 lines
27 KiB
Markdown
168 lines
27 KiB
Markdown
# 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 `docs/guides/compliance-overview.md` (forthcoming in story 05).
|
|
|
|
**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://<your-domain> \| 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** — `<CookieConsentBanner>` 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)._
|