From e1cad11a80a86a9d4dd58b4dff0ab457b12933a8 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 7 Nov 2026 14:21:50 +0100 Subject: [PATCH] Inbox 2026-11-07: executor tenant tenant:platform, audit-core pin 4da952c, P6 answers recorded - AUDIT-WP-0020-T03: exercise_audit_sender emits tenant:platform and probes tenant:other as the wrong tenant (row E6); contract suite 131 passed against audit-core 4da952c. - Intake doc: audit-core P6 answers (tenant, correlation_origin, privacyIDEA option b, no backfill, 30-day recoverability). - NK-WP-0055-T11 note; NK-WP-0035-T04 and NK-WP-0054-T04 wait reasons now name the founder/next step after the 2026-11-03 owner deliveries. Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 149903@bnt-lap001 Assistant-Session: 4c20a536-1452-4a85-bc09-e1987d9817d6 --- bounded-executor/exercise_audit_sender.py | 6 ++-- contracts/owner-pins.json | 2 +- docs/audit-core-intake-identity-providers.md | 28 +++++++++++++++++-- ...-0035-emission-cadence-security-profile.md | 7 ++++- .../NK-WP-0054-service-identity-policy.md | 8 +++++- ...-security-platform-production-readiness.md | 1 + 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/bounded-executor/exercise_audit_sender.py b/bounded-executor/exercise_audit_sender.py index eb368f0..1bdafdb 100644 --- a/bounded-executor/exercise_audit_sender.py +++ b/bounded-executor/exercise_audit_sender.py @@ -11,7 +11,7 @@ Checks: (tools/execution-attribution-receipt, schema v0.1) - a retry of the same event is a duplicate (200); the same id with another body is a conflict (409), which the client reports as a run-id-reuse defect - - wrong source, wrong tenant (`tenant:platform`), no token and a wrong token are refused; nothing is stored for them + - wrong source, wrong tenant (`tenant:other`), no token and a wrong token are refused; nothing is stored for them - a started event whose admission window has passed, with no receipt, becomes an opening_without_closing finding held to that window; the closed runs do not Synthetic tokens only. Writes a value-free receipt. Exit 0 when every check passes. @@ -92,7 +92,7 @@ def run_executor(name: str, audit, fail_checks=()) -> list[dict]: checks={c["id"]: fake.check for c in doc["spec"]["checks"]}, trust=lambda _s: True, audit=Tee(), alert=lambda *_a: None, sleep=lambda _s: None) cfg = X.Config(executor_identity=doc["spec"]["executor"]["identity"], - runtime_principal="system:serviceaccount:sso:nk-bind-executor", tenant="platform", + runtime_principal="system:serviceaccount:sso:nk-bind-executor", tenant="tenant:platform", environment="TEST", approver_subjects={"admin": "kc-sub-0f3a"}, approver_issuer="https://kc.coulomb.social") run = X.Run(doc, G.APPROVAL, cfg, deps) @@ -218,7 +218,7 @@ def exercise(args) -> dict: refused = { "wrong_source": (fresh(completed[0], source="user-engine"), "executor"), - "wrong_tenant": (fresh(completed[0], tenant="tenant:platform"), "executor"), + "wrong_tenant": (fresh(completed[0], tenant="tenant:other"), "executor"), "other_sender_token": (fresh(completed[0]), "other"), "no_token": (fresh(completed[0]), None), "unknown_token": (fresh(completed[0]), "synthetic-unknown-token"), diff --git a/contracts/owner-pins.json b/contracts/owner-pins.json index 311bc46..1342052 100644 --- a/contracts/owner-pins.json +++ b/contracts/owner-pins.json @@ -8,7 +8,7 @@ }, { "repo": "audit-core", - "commit": "3157454b848b21bfb164efa4ac3293adde774904" + "commit": "4da952c1c7a26dd0516c366eb8242ab2cc9378bc" }, { "repo": "informed-decision", diff --git a/docs/audit-core-intake-identity-providers.md b/docs/audit-core-intake-identity-providers.md index 70c0321..8a7320e 100644 --- a/docs/audit-core-intake-identity-providers.md +++ b/docs/audit-core-intake-identity-providers.md @@ -46,8 +46,9 @@ repositories. If that move happens, the source name stays the same and only the **Tenant policy.** All three providers are platform-scoped: there is a single realm and directory, `dc=netkingdom,dc=local`. - The envelope requires `tenant` to be a non-empty value. -- Proposal: use the fixed value `platform` for every event, and give the sender credential only `platform` as a permitted tenant. -- [unknown] Is `platform` the spelling audit-core uses for platform-scoped sources? If not, use audit-core's spelling. +- Use the fixed value `tenant:platform` for every event, and give the sender credential only `tenant:platform` as a + permitted tenant. Settled by the founder on 2026-11-07 (audit-core AUDIT-WP-0020); this replaces the `platform` + first proposed here. **Shipper.** One small collector per provider: the *intake shipper*. - It runs in the provider's namespace, either as a sidecar or as a CronJob. @@ -429,9 +430,30 @@ The `type` is derived from `action`, the HTTP method plus endpoint: | P3 | Read-only PostgreSQL role for `pidea_audit` | rapp-postgres / railiance-platform with net-kingdom | | P4 | Pseudonymisation key in OpenBao, and a sender credential for each source | net-kingdom via the attended OpenBao path (`warden route`) | | P5 | Traefik JSON access log with `traceparent` kept (no cookies or auth headers) | railiance-cluster | -| P6 | `tenant` value for platform-scoped sources; `correlation_origin` field placement (AUDIT-WP-0017-T05); per-subject encrypted personal payload for signed privacyIDEA rows; whether to backfill privacyIDEA history; longer retention for privacyIDEA | audit-core | +| P6 | Answered 2026-11-07, see below | audit-core | | P7 | KeyCape sends `traceparent` on its back-channel calls to Authelia and privacyIDEA | key-cape | +### audit-core answers to P6 (2026-11-07, founder decisions recorded in AUDIT-WP-0017-T04) + +- **Tenant:** `tenant:platform` for all three sources (AUDIT-WP-0020). This corrects audit-core's first answer + of `platform`. +- **`correlation_origin`:** in `data.correlation_origin`, next to `data.actor` and `data.outcome`; the envelope is + unchanged. Senders opt in with `"correlation_contract": "audit-correlation-v0.1"` (audit-core `364e723`, + `docs/event-envelope.md`, "The correlation contract"). It is not live until the next receiver image. +- **Signed privacyIDEA rows:** option (b). audit-core has no per-subject encrypted payload (R2, no + crypto-shredding). Send pseudonymised `data`, `subject` and `actor`, plus `signature`, `native_signature_alg`, + `verification_key_fingerprint` and a row hash, never the raw signed columns. The raw row is verified against the + source database while it is retained. The legal basis for keeping raw personal data stays with risk-nexus. +- **Backfill:** none. The cursor starts at `max(id)` on activation. +- **Retention:** audit-core is append-only but recoverable for 30 days only (`data.backup`) and has no archive class + (`data.archive` unprocured, reviewed 2026-12-31). The privacyIDEA database therefore stays authoritative for the + 1-year horizon, and its retention must be at least that long. +- **Shipper:** one shipper and one sender credential per source; audit-core prepares a per-source ingress + NetworkPolicy with each overlay. + +Still owed by NetKingdom before audit-core prepares overlays: the section 6 unknowns, P1-P5 and P7, then a +per-provider registration (exact source, selectors, cadence, heartbeat class). + ## 6. Unknowns to verify before overlays are prepared 1. **Log content.** Exact Authelia 4.39.28 and LLDAP log messages and fields at info level. Capture them on synthetic diff --git a/workplans/NK-WP-0035-emission-cadence-security-profile.md b/workplans/NK-WP-0035-emission-cadence-security-profile.md index c174406..187e80f 100644 --- a/workplans/NK-WP-0035-emission-cadence-security-profile.md +++ b/workplans/NK-WP-0035-emission-cadence-security-profile.md @@ -90,7 +90,7 @@ Python compilation and `git diff --check` pass. id: NK-WP-0035-T04 status: wait priority: high -blocking_reason: "Elapsed-hour capture done 2026-10-15 (3 events, receiver readback captured). Readback run 2026-10-23: presence 3/3, counts refused 403 source_not_allowed (operator reader scoped to user-engine); audit-core cross-source count path implemented (d46e89e); waiting on the founder's audit-core release (AUDIT-WP-0013-T07) and the rerun, then King's Guard acceptance (KG-WP-0005-T03, wait) and QONTO-WP-0006-T03." +blocking_reason: "Founder rerun of the receiver readback: audit-core released the independent count path on 2026-11-03 (AUDIT-WP-0013-T07, image sha256:304cfb83, basis independent_reader). Precheck GET /v1/stats is 200 under the operator reader, then rerun; an agree receipt goes to King's Guard (KG-WP-0005-T03) and QONTO-WP-0006-T03." state_hub_task_id: "e3fbc8b8-00d5-57ce-ba0c-19b58044c950" ``` @@ -463,6 +463,11 @@ releases the audit-core image (AUDIT-WP-0013-T07: `make image-publish`, pin dige apply, rollout), checks `GET /v1/stats` returns 200 under the operator reader token, then reruns the same readback. An `agree` receipt goes to King's Guard (KG-WP-0005-T03) and qonto-assistant. +2026-11-03: audit-core released it (AUDIT-WP-0013-T06/T07, image `sha256:304cfb83…`, source `8185893`, pin +`b365525`; the live Deployment reads back that digest). A tenant-scoped reader gets 403 +`full_tenant_scope_required`, which would mean the operator identity needs a registry scope change by audit-core. +Next: the founder runs the precheck and the readback. + ## Automate staged receiver derivation without sibling mutations ```task diff --git a/workplans/NK-WP-0054-service-identity-policy.md b/workplans/NK-WP-0054-service-identity-policy.md index cdbd0c7..87ce57b 100644 --- a/workplans/NK-WP-0054-service-identity-policy.md +++ b/workplans/NK-WP-0054-service-identity-policy.md @@ -195,7 +195,7 @@ status: wait priority: medium assignee: claude-code depends_on: [NK-WP-0054-T03] -blocking_reason: "Validator delivered (T03, provisional). Await the T02 review and owner agreement on what read-only metadata each service can provide." +blocking_reason: "OpenBao and PostgreSQL live metadata delivered 2026-11-03 (railiance-platform b0b6c0c). Next: run the conformance check against it with the freshness bound on collected_at; KeyCape live view (KEY-WP-0045-T02) is still the founder's." state_hub_task_id: "c8db4607-9306-572b-a3cb-c35ca5989ec7" ``` @@ -225,6 +225,12 @@ Declared from source: `fluid-telegram-operators` OPERATE on four exact KV entrie which is therefore inert). `coding-agent` `agent.mode` stays unknown (KeyCape KEY-WP-0043). The founder's live export commands are in RPF-WP-0067-T03. +**2026-11-03 (OpenBao, PostgreSQL live):** RPF-WP-0067-T03 done. railiance-platform `b0b6c0c`, +`docs/evidence/2026-11-03-nk-wp-0054-t04-identity-metadata/`: `openbao-identity-metadata.json` (sha256 `60da6df0…`; +6 auth mounts, 67 policies, 73 roles) and `postgresql-identity-metadata.json` (sha256 `e627278b…`; cluster +net-kingdom-pg, 5 roles, 4 databases), schema `railiance-platform.service-identity-metadata.v1`. Collected by the +founder; no Secret read, secret-shape guard passed. Apply the evidence-freshness bound to `collected_at`. + ## Split the directory bind from the human admin ```task diff --git a/workplans/NK-WP-0055-security-platform-production-readiness.md b/workplans/NK-WP-0055-security-platform-production-readiness.md index 93e7b71..384a9cd 100644 --- a/workplans/NK-WP-0055-security-platform-production-readiness.md +++ b/workplans/NK-WP-0055-security-platform-production-readiness.md @@ -339,6 +339,7 @@ AUDIT-WP-0015-T01's offsite chain head. 2026-10-27 owner scoping (proposed workplans, unpushed in the owner repos): audit-core AUDIT-WP-0017 (`ead0f09`: intake package per sender, correlation field, quarterly restore drill, offsite chain head); railiance-platform RPF-WP-0066 (`87a488c`: file audit device plus async sidecar shipper, snapshots, live conformance); railiance-cluster RCLUSTER-WP-0021 (`3ed1ac1`: k3s audit policy, node buffer, shipper, founder-run restart); access-engine FLEX-WP-0031-T10/T11 and FLEX-WP-0039 (`7cbd4e5`). NetKingdom's part: the [Audit Correlation Contract v0.1](../canon/standards/audit-correlation_v0.1.md) (proposed) and the four identity-provider intake packages (still to draft). Noted: audit-core lists six access-engine pins, the registry has nine. 2026-10-27 identity-provider intake: KeyCape package and propagation task in key-cape KEY-WP-0044 (`9adfb0b`; KeyCape emits stdout JSON only, `/token` failures, client-auth failures, revoke and introspect are unaudited today, issuance lacks subject/tenant). Authelia, LLDAP and privacyIDEA packages in [docs/audit-core-intake-identity-providers.md](../docs/audit-core-intake-identity-providers.md) (`ccd0b15`, draft): Authelia via a read-only SQLite sidecar plus JSON logs; LLDAP text logs, image must be pinned first; privacyIDEA signed `pidea_audit` export with signatures intact. Open decision for audit-core and the founder: signed privacyIDEA rows carry raw usernames and IPs, and pseudonymising them breaks the signature. +2026-11-07 audit-core answers: the correlation contract is implemented as opt-in `audit-correlation-v0.1` (audit-core `364e723`, AUDIT-WP-0017-T05; not live until the next receiver image). The P6 answers are recorded in the [intake doc](../docs/audit-core-intake-identity-providers.md): tenant `tenant:platform`, privacyIDEA option (b) with pseudonymised fields and the signature, no backfill, 30-day recoverability only. AUDIT-WP-0017-T04 waits on our section 6 unknowns, P1-P5 and P7, and then the per-provider registrations. Tenant spelling (AUDIT-WP-0020): the bounded executor now emits `tenant:platform` (rapp-bounded-executor `examples/config.pilot.json`; `exercise_audit_sender.py` probes `tenant:other` as the wrong tenant). Contract row E6, `make contract-test` 131 passed against audit-core `4da952c` (pin moved). audit-core narrows its overlay (AUDIT-WP-0020-T04) after the first run is accepted under `tenant:platform`, which the next admission window shows. ## Record live conformance receipts ```task