Build access-verification and export tooling

Task 5344 · Done · Coder · created · updated

Epic 5329 ask (verbatim): "Analyze current code, processes and documentation and close the gap to being SOC 2 compliant. Humans can participate but only where it cannot be avoided legally. Ask questions, but do not offload any work that you are technically able to do." Sources: PRD (Task 5330) and architecture (Task 5331) of epic 5329 — read them with `task_read` / `task_read_artifact` for full context. Target is **Type I readiness** (D2). Binding operator decisions (PRD §2, verbatim): "D1 ... Execute every step except an approval act. Operator: 'I only PR to main. You do develop.' Agents deliver everything to `develop` through PRs. Roman alone opens and merges develop→master promotion PRs and signs." "D3 Outreach: None. Agents contact no outside party." "D4 People with production access: Only Roman." AS1 (verbatim): "agents may run prod terraform, scripts and tests, but only code that has reached `master` through Roman's promotion, plus read-only and test actions that need no code change ... An agent never merges to `master`, never pushes to `master`, and never applies an un-promoted change to prod." Credentials: `jaah/system/bootstrap-admin` (org/AWS, read-only here) and `gmind/skynet/main` (console login); confirm with `task_credential_list` first (missing = BLOCKER ask). Evidence naming (architecture DA6): `<control>/<YYYY-MM-DD>/<slug>[.draft|.signed].<ext>`; the prod bucket `jaah-main-evidence-366008913850` is Object Lock GOVERNANCE 3y, so every filing is permanent. ## Requirement (verbatim from PRD) "### R7 — Logical access (CC6.1–CC6.3; G-01, G-03, G-05, OA-10, OA-11, OA-23) - **AC7.1** MFA is verified behaviourally on prod: a login without a second factor gets no session. *Verify:* the scripted check's output is filed to `reviews/`. - **AC7.2** `cp_readonly` is verified on prod: a write is refused, and the break-glass page fires. *Verify:* the check's output is filed to `reviews/` and `alarms/`. - **AC7.3** An entitlement export covers console users and roles, AWS Identity Center and IAM users in every org account, and GitHub. It is filed to `entitlements/` as a review ready for Roman's signature. *Verify:* the object exists, and it lists `bootstrap-admin`, `jaah-cp-psql-reader` and `jaah-node-launcher`." "### R15 ... **AC15.2** `tools/evidence_store.py` filing works against the prod bucket from the agent environment. *Verify:* each filed object exists, and its upload log names the object key." This child owns the BUILD half of AC7.1–AC7.3 and AC15.2's key print. ## Scope and approach (from the settled architecture) A5 (architecture §3 A5 + "Prod probe identity"): - **`tools/mfa_check.py`:** signs in as a probe user with TOTP enrolled, omits the second factor, asserts no session cookie/token is issued and the expected status comes back; writes a record to `reviews/`. The password path is refused from the internet, so it runs over the tailnet / internal host (`public-ui.tf` priority 2). - **Probe identity (pinned):** no standing test user. Each run creates a fresh non-superadmin user through the prod CP admin API (signed in as `gmind/skynet/main`), enrols TOTP holding the seed in memory only, runs, then **disables** the user. Address is a plus-address on `jaah.ai` (no outside invite, D3). Nothing persisted. Ship this as a reusable helper used by `mfa_check.py`, by the internal security assessment child, and by the access verification child. - **`tools/cp_readonly_check.sh`:** through `tools/cp_psql.sh main`, attempts one harmless write in a rolled-back transaction, asserts it is refused, writes to `reviews/`. (The break-glass check is behavioural and the access verification child's.) - **`tools/entitlements_export.py`:** enumerate the org (`organizations list-accounts`), assume `OrganizationAccountAccessRole` per account for IAM users/keys/roles, add Identity Center (`sso-admin list-instances`, `identitystore list-users`, account assignments); keep the `--aws-profile` loop for non-org accounts. - **`tools/evidence_store.py`:** add a CLI entry point (`python3 tools/evidence_store.py <control> <file> [--date] [--draft]`, honouring the DA6 naming) that prints the full `s3://bucket/key` on success (AC15.2); `write()` returns that URI too. Other children use this CLI to file evidence. - Tests for each with stubbed AWS and HTTP. - Delivered as a develop PR; the prod RUNS of these tools are the access verification child's (after promotion), so the evidence lands there. Out of scope: Epic-wide fences (PRD §6, verbatim): "No agent merges or pushes to `master`. No agent approves its own promotion. No agent applies to prod any change not yet promoted. Delivery is a PR to `develop` (D1)." "No contact with any outside party: no emails, Slack messages to externals, vendor portals, NDA click-throughs or RFPs sent; no contracts; no new vendor or subprocessor, which also excludes PagerDuty/Opsgenie and Drata (D3, D7, D8)." "Legacy account 210352747749 is untouched." "Out of scope: Security Hub MEDIUM and LOW findings (D10) — registered only; evidence automation: no new crons, workflows or collectors whose purpose is recurring evidence (D7); Type II, the observation window, the audit, auditor engagement; `compliance_locks` and the vault-lock *compliance* mode." "No change to the console Compliance page, `portfolio/registry.toml` or `portfolio/engine/`" (epic 5303 owns them). "No change to dev's control plane or account beyond what an R-item strictly needs." "No secret value in any doc, register, evidence object or report." "No weakening of an existing control to make a check pass." This child: Do not file anything to the prod evidence bucket — dry-run to `./evidence-out/` only. No change to auth/MFA application code (`apps/api/app/auth.py`, `mfa*.py`). No persisted probe user or secret. No scheduling of these tools (D7: one-off only). Done means: - Tests — oracle: new pytest modules for `mfa_check`, the probe helper, `entitlements_export` (org enumeration + Identity Center) and the `evidence_store` CLI pass with stubbed AWS/HTTP; `cp_readonly_check.sh` has a `--dry-run`/stub test. - `evidence_store.py` CLI prints `s3://<bucket>/<key>` — oracle: unit test invokes the CLI against a stubbed S3 and asserts the stdout line and the `.draft.` key shape. - Entitlement export quality — oracle: a read-only dry run against dev (org creds) writes to `./evidence-out/` a document listing per-account IAM users, Identity Center users + assignments, console users/roles and GitHub collaborators in readable tables (not a raw JSON dump); excerpt cited in the report. - `mfa_check.py` against dev (probe user created then disabled) reports "no session issued without 2nd factor" — output cited; the dev probe user shows disabled afterwards. - `./dc check full` green; PR merged to `develop`.

Outcome

Built mfa_check, probe helper, cp_readonly_check, org/Identity Center entitlement export, evidence_store CLI; full gate green, PR #4659 merged. Dev MFA PASS not produced (Org B MFA-exempt; operator chose ship).

Pull request

Artifacts

Activity

  • Draft
  • Ready
  • Runner started
  • Awaiting response
  • Awaiting response
  • Runner resumed
  • Runner ended (done)