Statement of Applicability
Generated from [`register/controls.yaml`](../register/controls.yaml) by `tools/soa.py` — do not hand-edit this file, edit the register and regenerate.
Satisfies ISO/IEC 27001:2022 clause 6.1.3(d). 90 of 93 Annex A controls are applicable to stratify's ISMS scope (see GOV-01 for exclusion justifications).
Status summary
| Status | Count |
|---|---|
| Implemented | 5 |
| Partially implemented | 40 |
| Planned | 1 |
| Not started | 34 |
| Not applicable | 13 |
⚠️ This is a Phase 0 gap-analysis snapshot (1 August 2026), not a certification readiness claim. not_started is an honest, expected state for several controls on a pre-seed, single-engineer team — see `PLAN.md` and `register/facts.md` for what's real vs. what's a documented gap.
5 — Organizational controls
| ID | Control | Applicable | Status | Justification | ||||
|---|---|---|---|---|---|---|---|---|
| 5.1 | Policies for information security | Yes | Planned | No written InfoSec policy exists yet above the real technical controls (RLS, CI gate, audit-log). GOV-02/POL-01 formalise this. | ||||
| 5.2 | Information security roles and responsibilities | Yes | Partially implemented | Roles exist informally and are now confirmed for this ISMS (ISMS Owner + DPO/Privacy Owner, facts.md) but not yet documented in a RACI. See GOV-03. | ||||
| 5.3 | Segregation of duties | Yes | Not started | Zero human PR reviewers besides Toby (single committer confirmed via git log, facts.md) — CODEOWNERS exists but is fully commented out/inert. A real, current gap. | ||||
| 5.4 | Management responsibilities | Yes | Partially implemented | Required CI check (verify, dos-ci.yml) demonstrates management commitment in enforcement; not yet stated as policy. | ||||
| 5.5 | Contact with authorities | Yes | Not started | No documented contact procedure with EDÖB, cantonal DPA, or a CERT exists. | ||||
| 5.6 | Contact with special interest groups | Yes | Not started | No special-interest-group / threat-intel-sharing membership established. | ||||
| 5.7 | Threat intelligence | Yes | Not started | No dependency/SCA scanning exists in either CI pipeline (facts.md — confirmed absent, unlike a mature baseline) and no other threat-intel process runs. A real, current gap. | ||||
| 5.8 | Information security in projectmanagement | Yes | Partially implemented | CI gate (lint, typecheck, tests, secret-scan) applies security requirements per-change; not framed as a project-management-stage requirement. | ||||
| 5.9 | Inventory of information and other associated assets | Yes | Not started | No formal asset inventory exists yet. assets.yaml seeded from facts.md's real table/service list, not yet a maintained inventory. | ||||
| 5.10 | Acceptable use of information and other associated assets | Yes | Not started | No acceptable-use policy exists yet. | ||||
| 5.11 | Return of assets | Yes | Not applicable | Single-person engineering team, no company-owned equipment issued to a second party yet — relevant once the team grows. | ||||
| 5.12 | Classification of information | Yes | Not started | No information classification scheme exists; personal-data tables are known (facts.md) but not formally classified — see assets.yaml. | ||||
| 5.13 | Labelling of information | No | Not applicable | No physical/document labelling regime in use; classification (5.12) will be enforced structurally (RLS, DB schema) rather than by labelling. | ||||
| 5.14 | Information transfer | Yes | Partially implemented | TLS assumed for all traffic (Traefik in front of the Hetzner Docker stack); no documented information-transfer policy for e.g. partner API onboarding or data exports. | ||||
| 5.15 | Access control | Yes | Implemented | RLS is real and enforced on ≥23 tables, auth.uid() = user_id pattern, deny-by-default on audit_log/signal_deliveries (facts.md) — a genuinely operating access-control layer. No written access-control policy exists above the implementation, so POL-03 is still needed to document it, not to build it. | ||||
| 5.16 | Identity management | Yes | Partially implemented | Supabase Auth (GoTrue) provides identity management; no documented identity-lifecycle policy (account creation/deactivation rules) exists. | ||||
| 5.17 | Authentication information | Yes | Partially implemented | OTP codes (6-digit, 10-min expiry, rate-limited) replace passwords for the primary flow; a password fallback also exists (facts.md/ADR-0002) — no documented policy on credential strength or MFA requirements. | ||||
| 5.18 | Access rights | Yes | Partially implemented | RBAC (`subscriber\ | pilot\ | compliance\ | founder\ | admin via subscriber_roles) is real and centrally guarded (apps/web/lib/admin/guard.ts`); no periodic access-rights review process exists yet — see PRO-02. |
| 5.19 | Information security in supplier relationships | Yes | Partially implemented | Real sub-processor list exists (facts.md: Supabase, AWS SES, Stripe, PostHog, Sentry, Vercel AI Gateway, Expo/APNs/FCM) but no supplier security policy or systematic DPA tracking beyond dsgvo-data-flow.md §10 exists. | ||||
| 5.20 | Addressing information security within supplier agreements | Yes | Partially implemented | DPA links are tracked per-supplier in dsgvo-data-flow.md §10; no standard security-clause template used when onboarding a new supplier. | ||||
| 5.21 | Managing information security in the information and communication technology (ICT) supply-chain | Yes | Not started | No ICT-supply-chain-specific risk process (e.g. for a Vercel AI Gateway model change, or a new push/email vendor swap like the Resend→SES migration that already happened once) exists yet. | ||||
| 5.22 | Monitoring, review and change management of supplier services | Yes | Not started | No periodic supplier review process exists — see PRO-10; dsgvo-data-flow.md states DPA links are reviewed quarterly by Antonios but this isn't a documented procedure. | ||||
| 5.23 | Information security for use of cloud services | Yes | Partially implemented | Hetzner (self-hosted Docker) and Supabase's own upstream cloud dependencies are in active use without a documented cloud-security policy; the production cutover away from Vercel/Supabase-Cloud (facts.md) was a real architectural decision, undocumented as policy. | ||||
| 5.24 | Information security incident management planning and preparation | Yes | Partially implemented | No general incident-management plan exists, but a real, specific P0 runbook exists for audit-chain corruption (docs/runbooks/db-recovery.md §3.3) including a notification path — a concrete precedent to generalise into PRO-08, not a blank slate. | ||||
| 5.25 | Assessment and decision on information security events | Yes | Not started | No incident triage/severity taxonomy exists beyond the single P0 scenario above. | ||||
| 5.26 | Response to information security incidents | Yes | Partially implemented | The db-recovery.md §3.3 runbook is a real incident-response runbook for one scenario; no general incident-response runbook exists for other classes of event (e.g. credential leak, RLS bypass). | ||||
| 5.27 | Learning from information security incidents | Yes | Not started | No post-incident review process exists — natural extension of GOV-11 once an incident occurs. | ||||
| 5.28 | Collection of evidence | Yes | Partially implemented | The db-recovery.md P0 runbook specifies a forensic-snapshot step; no general evidence-collection procedure for other security events exists. | ||||
| 5.29 | Information security during disruption | Yes | Not started | No continuity-during-disruption plan beyond the single-host-outage §3.4 scenario in db-recovery.md. | ||||
| 5.30 | ICT readiness for business continuity | Yes | Partially implemented | A read-only-mode failover toggle is documented for host outage (db-recovery.md §3.4); no broader ICT-continuity plan exists. | ||||
| 5.31 | Legal, statutory, regulatory and contractual requirements | Yes | Partially implemented | GDPR/revDSG applicability is understood and substantially documented (dsgvo-data-flow.md); the parallel FIDLEG/MiFID-II regulatory ladder is tracked separately in regulatory-roadmap-ch-eea.md. Not yet consolidated into a single legal/regulatory register spanning both. | ||||
| 5.32 | Intellectual property rights | Yes | Not started | No documented IP policy (open-source usage, pilot-authored signal content ownership, AI-drafted content) exists yet. | ||||
| 5.33 | Protection of records | Yes | Partially implemented | Ledgered, sequentially-numbered DB migrations (0001–0021+) are a real form of schema-record protection; broader records-retention policy beyond dsgvo-data-flow.md's per-table retention table doesn't exist. | ||||
| 5.34 | Privacy and protection of personal identifiable information (PII) | Yes | Implemented | A real, substantive privacy programme already exists and is operative: dsgvo-data-flow.md (controller/processor map, data categories, Art. 6 legal bases, subject-rights table, Art. 32 measures, DPA tracking) plus working code for export (Art. 15) and erasure/anonymization (Art. 17) (facts.md). This is materially ahead of a typical pre-seed baseline — the ISMS's job is to formalise and cross-reference it (PRIV-01/02), not build it from zero. Two known staleness corrections (Vercel→Hetzner, Resend→SES) are tracked as a GOV-13 item. | ||||
| 5.35 | Independent review of information security | Yes | Not started | No internal audit has yet been run — see GOV-11, not yet executed. | ||||
| 5.36 | Compliance with policies, rules and standards for information security | Yes | Partially implemented | The CI gate enforces some policies (secret scanning) structurally; no formal compliance-monitoring process exists for policies once GOV-02/Tier 1 are written. | ||||
| 5.37 | Documented operating procedures | Yes | Partially implemented | CONTRIBUTING.md and the ADRs (docs/adr/) are real, substantive operating procedures for the codebase; ISMS-level procedures (Tier 2) don't exist yet. |
6 — People controls
| ID | Control | Applicable | Status | Justification |
|---|---|---|---|---|
| 6.1 | Screening | Yes | Not applicable | Single-founder-adjacent engineering team (Toby only, per git history); no screening process needed until the first hire. |
| 6.2 | Terms and conditions of employment | Yes | Not started | No standard employment terms addressing information security exist yet — relevant at first hire. |
| 6.3 | Information security awareness, education and training | Yes | Not started | No security awareness/training programme exists — see PRO-16. |
| 6.4 | Disciplinary process | Yes | Not started | No disciplinary process for security violations documented — relevant once the team grows. |
| 6.5 | Responsibilities after termination or change of employment | Yes | Not started | No offboarding procedure for post-termination responsibilities exists yet. |
| 6.6 | Confidentiality or non-disclosure agreements | Yes | Not started | No documented standard NDA/confidentiality process for contractors or the wider founder team. |
| 6.7 | Remote working | Yes | Partially implemented | Team works distributed by default; no documented remote-working security policy (endpoint hygiene, home-network expectations) exists yet. |
| 6.8 | Information security event reporting | Yes | Not started | No formal security-event reporting channel for the founder team (as distinct from automated CI/gitleaks detection) exists. |
7 — Physical controls
| ID | Control | Applicable | Status | Justification |
|---|---|---|---|---|
| 7.1 | Physical security perimeters | Yes | Not applicable | No Stratify-owned/leased datacenter or controlled office perimeter — production runs on a single rented Hetzner server; physical perimeter security is Hetzner's control, referenced via their own certifications (see PRO-10/suppliers.yaml). |
| 7.2 | Physical entry | Yes | Not applicable | No physical premises with controlled entry identified — delegated to Hetzner for infrastructure; the wait, what. Advisory registered address is a standard commercial address, not a secured facility. |
| 7.3 | Securing offices, rooms and facilities | Yes | Not applicable | No Stratify-controlled server room/facility exists; delegated to Hetzner. |
| 7.4 | Physical security monitoring | Yes | Not applicable | No Stratify-controlled facility to monitor; delegated to Hetzner. |
| 7.5 | Protecting against physical and environmental threats | Yes | Partially implemented | Hetzner carries environmental-threat protection for the production host; no equivalent consideration documented for the founder's home-office equipment. |
| 7.6 | Working in secure areas | Yes | Not applicable | No Stratify-designated secure physical work area exists (distributed, single-person team). |
| 7.7 | Clear desk and clear screen | Yes | Not started | No clear-desk/clear-screen policy documented. |
| 7.8 | Equipment siting and protection | Yes | Partially implemented | A laptop is the primary owned equipment (no server-room hardware, production runs on a rented Hetzner host); no documented siting/protection guidance for the home-office setup. |
| 7.9 | Security of assets off-premises | Yes | Not started | No policy for equipment used off standard premises (the laptop, phone) exists yet. |
| 7.10 | Storage media | Yes | Not started | No storage-media handling/disposal policy exists; relevant mainly for laptop disk retirement given the self-hosted-but-remote production host. |
| 7.11 | Supporting utilities | Yes | Not applicable | No Stratify-controlled facility with supporting utilities (power, HVAC) — Hetzner's control. |
| 7.12 | Cabling security | Yes | Not applicable | No Stratify-controlled cabling/facility infrastructure. |
| 7.13 | Equipment maintenance | Yes | Not applicable | No Stratify-owned hardware requiring maintenance beyond the founder's laptop — covered under 7.8/7.9, not facility maintenance. The Hetzner host itself is Hetzner's maintenance responsibility. |
| 7.14 | Secure disposal or re-use of equipment | Yes | Not started | No documented secure-disposal process for retired laptops/media exists yet. |
8 — Technological controls
| ID | Control | Applicable | Status | Justification |
|---|---|---|---|---|
| 8.1 | User end point devices | Yes | Partially implemented | The founder's laptop is the primary endpoint; no documented endpoint-security baseline (disk encryption, screen-lock timeout, EDR) exists yet. |
| 8.2 | Privileged access rights | Yes | Partially implemented | RBAC distinguishes subscriber/pilot/compliance/founder/admin (facts.md); the service-role key is the sole structural RLS-bypass path, tightly scoped to server-side admin code. No formal privileged-access-review process exists. |
| 8.3 | Information access restriction | Yes | Implemented | Row-Level Security is real and enforced on ≥23 personal-data-bearing and operational tables, with explicit deny-by-default (no SELECT policy) on audit_log and signal_deliveries (facts.md). A genuinely implemented control, not aspirational — this is stronger than a typical pre-seed baseline. |
| 8.4 | Access to source code | Yes | Partially implemented | Source-code access is controlled via GitHub repo permissions; the CODEOWNERS/branch-ruleset gate exists per CONTRIBUTING.md description but CODEOWNERS itself is inert (facts.md) and branch-protection settings aren't verifiable from repo contents alone. |
| 8.5 | Secure authentication | Yes | Partially implemented | Email-OTP authentication (6-digit, 10-min expiry, rate-limited to 30 verify attempts) replaced broken magic links (ADR-0002, facts.md) — a real, deliberately-hardened control. No MFA is offered for any role, including elevated admin/founder/compliance roles — a genuine gap given the elevated data access those roles carry. |
| 8.6 | Capacity management | Yes | Not started | No capacity-management/monitoring process documented for the single Hetzner host. |
| 8.7 | Protection against malware | Yes | Not started | No anti-malware control documented — relevant primarily for the founder's endpoint and any file-upload handling paths. |
| 8.8 | Management of technical vulnerabilities | Yes | Not started | No dependency/SCA scanning exists in CI (confirmed absent — no pnpm audit, Dependabot, or Renovate, facts.md). A real, current gap and a priority fix given it's cheap to close. |
| 8.9 | Configuration management | Yes | Partially implemented | Sequentially-ledgered DB migrations constitute real configuration management for the schema; the Hetzner Docker/Traefik stack config exists as versioned files (infra/hetzner/) but isn't managed via a broader infra-as-code / drift-detection process. |
| 8.10 | Information deletion | Yes | Implemented | A real, working deletion path exists: eraseSubscriberData hard-deletes several tables and anonymizes the subscribers row, compliance-actor-gated, itself audit-logged (facts.md). Currently admin-triggered only, not self-service — see PRO-09/PRIV-11 for the self-service gap. |
| 8.11 | Data masking | Yes | Not started | No data-masking process documented for any non-prod environment that might use copies of real subscriber/portfolio data. |
| 8.12 | Data leakage prevention | Yes | Not started | No DLP control (egress monitoring, etc.) beyond RLS/service-role scoping exists. |
| 8.13 | Information backup | Yes | Partially implemented | A real, operating nightly backup exists (pg_dump cron on the Hetzner host, 14-dump retention, RPO ≤24h/RTO ≤60min stated — facts.md), but restore has never been tested (db-recovery.md's own checklist item is unchecked). Honestly scored partial, not implemented, until a restore drill is logged — see PRO-07. |
| 8.14 | Redundancy of information processing facilities | Yes | Not started | Single Hetzner host, no redundancy/failover beyond a manual read-only-mode toggle for host outage (db-recovery.md §3.4) — a real, current single-point-of-failure gap. |
| 8.15 | Logging | Yes | Partially implemented | Sentry (server-only) and PostHog EU capture errors/events; no client-side/browser Sentry init exists (facts.md), a real front-end-error visibility gap. |
| 8.16 | Monitoring activities | Yes | Not started | Logs/events are produced (8.15) but no documented alerting rules or on-call process exist in-repo — appears to be managed outside the repo if at all. |
| 8.17 | Clock synchronization | Yes | Not started | No explicit clock-synchronization control documented for the Hetzner host; standard NTP presumably applies but isn't confirmed or policy-stated. |
| 8.18 | Use of privileged utility programs | Yes | Partially implemented | The Supabase service-role key is the one privileged-utility-equivalent path (structurally bypasses RLS), tightly scoped to server-side admin code (facts.md); no broader inventory of privileged-utility usage exists. |
| 8.19 | Installation of software on operational systems | Yes | Partially implemented | Dependency versions are pinned in package.json/lockfiles; no documented policy restricting ad-hoc software installation on the operational Hetzner host. |
| 8.20 | Networks security | Yes | Partially implemented | The Hetzner host's public IP is firewalled to Tailscale-only access (facts.md, docs/runbooks/deploy.md) — a real, meaningful network-security control; not yet written up as policy. |
| 8.21 | Security of network services | Yes | Partially implemented | Traefik terminates TLS in front of the Docker stack; no documented policy on which network services are exposed vs. internal-only beyond what the Tailscale/firewall setup already enforces in practice. |
| 8.22 | Segregation of networks | Yes | Partially implemented | No per-client network segregation exists (single shared Postgres instance); RLS (8.3) is the current tenant-isolation control at the data layer, which is the correct control for this architecture, not a gap to fill with network segmentation. |
| 8.23 | Web filtering | No | Not applicable | No web-filtering control is relevant to Stratify's own infrastructure model (it is not an end-user network operator). |
| 8.24 | Use of cryptography | Yes | Partially implemented | TLS via Traefik for transport; SHA-256 chain-hashing for audit-log integrity (facts.md) is real applied cryptography; secrets are Keychain (dev) / Docker env vars (prod) rather than a formal key-management system. No documented cryptography policy (algorithm choices, key lifecycle/rotation) exists — see POL-04. |
| 8.25 | Secure development life cycle | Yes | Partially implemented | A real, required CI gate exists (dos-ci.yml: lint, typecheck, tests, gitleaks secret-scan, build) — genuinely non-trivial, but lacks dependency/SCA scanning (8.8) and any SAST/DAST step. Partial, not implemented, until that gap closes. |
| 8.26 | Application security requirements | Yes | Partially implemented | TypeScript strict mode and an OpenAPI 3.1 contract (openapi/stratify-api.yaml) provide some structural application-security discipline; not documented as an explicit security-requirements process. |
| 8.27 | Secure system architecture and engineering principles | Yes | Partially implemented | ADRs (docs/adr/0001, 0002) document real architectural security decisions (dev-operating-standard adoption, the OTP-auth pivot away from broken magic links) — a genuine secure-architecture practice, though not framed as an ISO control. |
| 8.28 | Secure coding | Yes | Implemented | Lint + typecheck enforced in CI on every PR via the required verify check (facts.md) — a real, non-bypassable-in-CI secure-coding control (though local --no-verify can skip the equivalent pre-commit hook). |
| 8.29 | Security testing in development and acceptance | Yes | Partially implemented | A test job runs in CI, and a substantially larger suite landed 2026-08-01 (partner-auth, signal fan-out, rate-limit/Stripe-webhook-sig, RLS + audit-chain integration, ingest-adapter transforms) plus per-workspace coverage floors (test:cov + vitest.config.ts thresholds in web/mobile/shared). Still no dedicated security-testing (SAST/DAST) step, and the coverage floors aren't yet wired into the required CI verify check — genuinely stronger than before, but not yet a mature baseline on this control. |
| 8.30 | Outsourced development | No | Not applicable | No outsourced/contracted development activity — the codebase is developed in-house (single human plus an AI coding agent, facts.md). |
| 8.31 | Separation of development, test and production environments | Yes | Partially implemented | A real integration-test harness (test:integration, landed 2026-08-01) runs RLS + audit-chain tests against a local Supabase instance, structurally separate from the single Hetzner production host — genuine dev/test separation at the testing-infrastructure level. No formal staging environment sits between local and production, though. |
| 8.32 | Change management | Yes | Partially implemented | Required CI check + a described (but not repo-verifiable) branch ruleset governs merges to main; deploy itself is a pull-based systemd timer against the Hetzner host (facts.md), which is a real but informally-documented change path. |
| 8.33 | Test information | Yes | Not started | No documented policy on use of production-realistic test data (e.g. anonymised subscriber data for testing) exists yet. |
| 8.34 | Protection of information systems during audit testing | Yes | Not started | No documented control for protecting production systems during audit/pentest activity — not yet relevant since no pentest has been executed (only an unsent RFP exists, facts.md). |
Regulatory crosswalk
Full per-control crosswalk (GDPR / revDSG article refs) lives in controls.yaml directly. Query the YAML for a specific regulation's controls, e.g.: yq '.controls[] | select(.crosswalk.gdpr_art | length > 0) | .id' register/controls.yaml.