ISO 27001 SoA, ISMS, checker

Task 6227 · Done · Coder · created · updated

Part of epic 6213. Child C6 of 9. Depends on C1 (`packages/evidence.CONTROLS` incl. `control-checks`), C4 (`trust.md`, whose ISO 27001 line this child flips) and C3 (so collector-backed controls — C2+C3 collectors — are live and can be cited by id honestly). ## Original requirement (verbatim) > "Identify which security and compliance certifications Jaah's competitors have — SOC 2, HIPAA, ISO 27001, etc. — and close the gap. Without breaking anything :)" **R1 — ISO/IEC 27001:2022 readiness** (verbatim): - ISMS scope statement whose boundary is the SOC 2 boundary (prod control plane + the fleet it launches/enrols; dev out) — D-6. - Statement of Applicability covering all 93 Annex A (2022) controls: applicable/excluded + justification + the operating control it points at. - A crosswalk onto the existing SOC 2 programme (pointer per row, never restated prose — single-home), in the style of `hipaa-crosswalk.md`. - The ISO-only clauses 4–10 artefacts that SOC 2 lacks: context of the organisation / interested parties, ISMS objectives, internal audit programme, management review record template, corrective-action / nonconformity procedure, competence & awareness. - Every ISO-only gap either built (if agent-buildable and non-breaking) or carried by a named risk-register row; owner actions named (incl. choosing/contracting a certification body). D-2 done bar: audit-ready + owner-action list; no certificate claimed until issued. ## Scope (architecture §3.5 ISO 27001) - `docs/compliance/iso27001-soa.md`: opens with a clause 4–10 table (one row per clause requirement 4.1–10.2 → its artefact); then all 93 Annex A:2022 controls, each "Applicable" with pointer (policy section, live file path, readiness-checklist criterion, collector id, risk id or owner-action id) or "Excluded" with justification. Status column uses exactly `live | built | gap | owner action`. Gap rows carry an `R-ISO-*` risk id or an `ISO27-OA-n`. Owner-actions section at the end (HIPAA-crosswalk style): select and contract a certification body, internal auditor independence, sign the SoA, hold the ISMS management review; where shared with SOC 2, POINT at the H-/I- row instead of copying. - `docs/compliance/iso27001-isms.md`: only what SOC 2 lacks — ISMS scope (boundary = pointer to `system-description.md`), interested parties and needs, ISMS objectives with measures, internal audit programme, management-review input/output template, nonconformity and corrective-action procedure, competence and awareness. Where an existing policy covers part of a clause, point there. - Sort every ISO-only gap: **built** (document/template/procedure — write it in the ISMS file), **built in code** (additive non-breaking product change — none found at design; if you find one, NAME it as a deferred follow-up, don't widen this child), **gap row** (needs a human or would alter an existing control). - `R-ISO-*` rows in `docs/compliance/risk-register.md` with score/treatment/owner. - `tools/iso_crosswalk.py` modelled on `tools/hipaa_crosswalk.py`, GENERALIZED (takes doc path + control list; C7 reuses it). Asserts: exactly 93 Annex A rows; no blank cell, no TBD; every `R-*` id exists in the risk register; every `*-OA-*` id resolves to an owner-action row; every evidence folder named is in `packages.evidence.CONTROLS`. Wire it into the gate (`tools/check.sh` / wherever `hipaa_crosswalk.py` is wired) with its own tests. - `docs/compliance/README.md` rows for the new docs; widen its first sentence from "SOC 2 programme" to name ISO 27001/42001 and GDPR artefacts. - Flip `docs/compliance/public/trust.md`'s line "ISO/IEC 27001 — planned" to "ISO/IEC 27001 — readiness" and repoint its internal pointer to `iso27001-soa.md` (no unfinished marker). Credentials & reach: AC1–AC3, AC11 | nothing beyond the worktree (`tools/check_context.py`, `tools/iso_crosswalk.py`, grep, `./dc check full`) | **verified** (worktree-only). AC-X2 | runner's own forge login via `jaah-forge` | **verified**. Out of scope: Do NOT contract a certification body or auditor; do NOT sign the SoA. Do NOT change MFA, sessions, retention or IAM behaviour to satisfy a control — gap row instead. Do NOT touch HIPAA crosswalk except to add pointers. Do NOT write ISO 42001 content (C7). Epic-wide (PRD §6, verbatim): "**Do not** obtain, buy, sign or contract anything (cert body, auditor, Drata, SafeBase, pentest firm, NDAs); **do not** contact outside parties. Those are owner actions only. **Do not** claim any certification as held (trust page, security page, marketing, PRs). **Do not** start FedRAMP, PCI, TISAX, Cyber Essentials, ISO 27017/27018/27701 or CSA STAR work. **Do not** change HIPAA mode behaviour, the BAA text, or the HIPAA crosswalk except to add pointers. **Do not** widen the audit boundary to dev; **do not** alter existing controls' behaviour (MFA, sessions, retention, IAM) to satisfy ISO — record a gap row instead unless the change is clearly non-breaking and additive. **Do not** copy SOC 2 policy prose into ISO documents — pointer per row (single-home); no parallel policy set. **Do not** put instance data (people, account ids) in reusable docs — `portfolio/projects/jaah.md` only. **Do not** add a new evidence-store folder outside `tools/evidence_store.py`'s list." Done means: - AC1 (R1) SoA lists all 93 Annex A:2022 controls, each with applicability, justification and a resolving pointer (live file, risk-register row, or owner-action id) — no row blank, no "TBD". → verify: count rows = 93; `python3 tools/check_context.py` green (all links resolve); grep for TBD/TODO in the new files = 0. - AC2 (R1) Every clause 4–10 requirement maps to an existing or new artefact or a named gap row. → verify: crosswalk table reviewed clause by clause; each pointer opens. - AC3 (R1/R3) Every ISO gap row has a risk-register id with score/treatment/owner; every human-only step has an owner-action id listed in one owner-action section (no duplication with the SOC 2/HIPAA lists — pointers where shared). → verify: grep each gap id in risk-register.md. - `python3 tools/iso_crosswalk.py docs/compliance/iso27001-soa.md` passes and runs in the gate; a seeded bad row (blank cell / unknown R- id) makes its test fail. - AC11 for the flipped ISO 27001 line: no status claims a certificate not issued → cross-checked vs `iso27001-soa.md`. - AC-X1 (A3) Nothing breaks: `./dc check full` green on every PR. → verify: gate output. - AC-X2 (A3) Every PR's Jaah Deploy succeeds on dev. → verify: GitHub deploy run status.

Outcome

ISO 27001 SoA (93 Annex A + clauses 4–10), ISMS doc, 5 R-ISO risk rows, generalized tools/iso_crosswalk.py in quick gate; trust line → Readiness. Full gate green, PR #5409 merged, dev Jaah Deploy succeeded. Follow-ups in report.

Pull request

Artifacts

Activity

  • Draft
  • Ready
  • Runner started
  • Runner ended (done)