Inbox 2026-11-07: executor tenant tenant:platform, audit-core pin 4da952c, P6 answers recorded
All checks were successful
Bounded-execution contracts / contracts (push) Successful in 1m35s
Build and Publish bounded-executor / build-and-push (push) Successful in 12s
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Identity provider journey acceptance / provider (push) Successful in 37s

- 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 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 149903@bnt-lap001
Assistant-Session: 4c20a536-1452-4a85-bc09-e1987d9817d6
This commit is contained in:
tegwick 2026-11-07 14:21:50 +01:00
parent f8b6a0bbbc
commit e1cad11a80
6 changed files with 43 additions and 9 deletions

View file

@ -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"),

View file

@ -8,7 +8,7 @@
},
{
"repo": "audit-core",
"commit": "3157454b848b21bfb164efa4ac3293adde774904"
"commit": "4da952c1c7a26dd0516c366eb8242ab2cc9378bc"
},
{
"repo": "informed-decision",

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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