Prepare scoped factory audit custody and enforce receiver compatibility
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
parent
d3a502b45c
commit
bfe65a5b05
11 changed files with 1053 additions and 1 deletions
121
docs/credential-lane-designs/factory-audit-senders-review.md
Normal file
121
docs/credential-lane-designs/factory-audit-senders-review.md
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
# Factory audit senders: concrete custody review
|
||||
|
||||
CCR-2026-0021 and CCR-2026-0022 are **proposed**. RPF-WP-0035-T08 owns the
|
||||
platform work; AUDIT-WP-0009-T09/T11 retain receiver admission. This packet
|
||||
requires the named platform operator, Audit Core owner and each producer owner
|
||||
to approve its request before native credential mutation.
|
||||
|
||||
## Scope to approve
|
||||
|
||||
| Request | Producer / exact source | OpenBao path | Producer Secret / key |
|
||||
| --- | --- | --- | --- |
|
||||
| CCR-2026-0021 | approval-engine | platform/workloads/approval-engine/audit-sender | approval-engine/approval-engine-audit / audit-token |
|
||||
| CCR-2026-0022 | informed-decision | platform/workloads/informed-decision/audit-sender | informed-decision/informed-decision-audit / token |
|
||||
|
||||
Each sender is limited to `tenant:platform`, write true, read false,
|
||||
`evidence_kind: load-bearing`, `secret_policy: redact`. The producer receives
|
||||
only its own `AUDIT_TOKEN`. `CUSTODY_REQUEST` is a non-secret provenance marker
|
||||
stored beside that token, enabling an interrupted first provision to identify
|
||||
its own version-1 value. It is not projected to the producer.
|
||||
|
||||
Each lane has its own exact-path policy, Kubernetes auth role and namespace-
|
||||
restricted ClusterSecretStore. Only `external-secrets/external-secrets` may
|
||||
log in to the reader role (15-minute session). Neither producer can read the
|
||||
full sender registry or its sibling's token. The coding-agent boundary gains
|
||||
exact denies on the two new data/metadata paths; existing rules are preserved.
|
||||
|
||||
The approved first-provision operation would generate two independent values
|
||||
in the attended platform process, store them with CAS=0, and append the exact
|
||||
identities to `platform/workloads/audit-core/senders` with compare-and-set on
|
||||
its observed KV version. That process necessarily reads the existing registry
|
||||
in memory; it never emits its credentials or gives it to a producer. No token
|
||||
passes through Git, a Hub record, command arguments or stdout/stderr.
|
||||
|
||||
## Blocking receiver finding
|
||||
|
||||
On 2026-09-11 the native receiver is 1/1 Ready on
|
||||
`forgejo.coulomb.social/coulomb/audit-core@sha256:c2fe39a0185b99be3fc0cb14d2de69772b8e66e20490097c9d11d90cc39719a6`.
|
||||
Its `SenderIdentity` has **no evidence_kind support**. A synthetic registration
|
||||
probe in the native pod fails the load-bearing contract; the same probe against
|
||||
current Audit Core source passes. Readiness did not detect this contract gap.
|
||||
|
||||
`factory_audit_custody.py receiver-check` now enforces that contract before any
|
||||
credential access. An approved CCR alone cannot bypass it. Audit Core must
|
||||
build, publish, admit and roll out its current implementation and source scope
|
||||
first. Its existing AUDIT-WP-0009-T09/T11 tasks retain that work; no completed
|
||||
source task is reopened. No receiver restart or deployment was done here.
|
||||
|
||||
Approval Engine's namespace is also absent. Three of four ESO objects passed
|
||||
server dry-run in their intended namespaces; its ExternalSecret was refused
|
||||
because that namespace does not exist. This packet creates no namespace,
|
||||
workload or network permission. Its owner must supply that prerequisite.
|
||||
|
||||
## Executable sequence
|
||||
|
||||
Review the source and exact policies:
|
||||
|
||||
```sh
|
||||
python3 scripts/credential-change.py render CCR-2026-0021
|
||||
python3 scripts/credential-change.py render CCR-2026-0022
|
||||
python3 scripts/factory_audit_custody.py plan
|
||||
```
|
||||
|
||||
After a compatible receiver release, the credential-free check is:
|
||||
|
||||
```sh
|
||||
python3 scripts/factory_audit_custody.py receiver-check \
|
||||
--kubeconfig /operator/railiance-kubeconfig \
|
||||
--expected-receiver-image forgejo.coulomb.social/coulomb/audit-core@sha256:ADMITTED_DIGEST \
|
||||
--receipt /operator/unique-receiver-receipt.json
|
||||
```
|
||||
|
||||
The seed command requires approved CCR files with all named owner reviews,
|
||||
the expected image, exact Railiance cluster UID, ready/current pod, both target
|
||||
namespaces and the Warden attended platform-admin login envelope. Route via
|
||||
`warden route show openbao-platform-admin-login --json` before arranging access.
|
||||
Use its installed attended wrapper; do not copy a token into the command.
|
||||
|
||||
Inside that envelope, invoke:
|
||||
|
||||
```sh
|
||||
python3 scripts/factory_audit_custody.py seed \
|
||||
--kubeconfig /operator/railiance-kubeconfig \
|
||||
--expected-receiver-image forgejo.coulomb.social/coulomb/audit-core@sha256:ADMITTED_DIGEST \
|
||||
--confirm 'PROVISION CCR-2026-0021 CCR-2026-0022' \
|
||||
--receipt /operator/unique-custody-receipt.json
|
||||
```
|
||||
|
||||
A successful seed deliberately reports
|
||||
`custody_seeded_pending_delivery_and_receiver_reload`. It applies the exact
|
||||
reader metadata and seeds custody, but does not apply ESO objects, reload the
|
||||
shared receiver or claim live ingestion. Preserve that receipt. After an
|
||||
interruption, review it and use `--resume` with a new receipt: only exact
|
||||
request-owned version-1 custody is reused. Changed tokens, source scopes,
|
||||
provenance, unknown duplicate identities and concurrent registry writes refuse.
|
||||
No automatic deletion or rotation is attempted on failure.
|
||||
|
||||
Under the same reviewed lane, the subsequent attended delivery uses
|
||||
`manifests/factory-audit-senders.yaml`; verify both stores/ExternalSecrets and
|
||||
exact token equality inside the protected process. Sync the existing registry
|
||||
ExternalSecret, verify its update, and reload Audit Core through its owner
|
||||
runbook. Then run each real producer's accepted/duplicate and wrong-source,
|
||||
wrong-tenant/read-refusal checks and retrieve evidence with the independent
|
||||
operator reader. The script does not yet automate these owner acceptance steps.
|
||||
Do not mark either CCR verified/active until those receipts exist.
|
||||
|
||||
## Revocation and limits
|
||||
|
||||
ESO login expiry does **not** expire an audit bearer. Stop the affected producer,
|
||||
remove only its token from the receiver registry using CAS, reload the receiver
|
||||
and prove refusal, then disable its reader/projection. Retain stored events and
|
||||
KV provenance. Rotation is separately reviewed and overlap-first. Existing
|
||||
senders and reader permissions remain intact.
|
||||
|
||||
`warden route show audit-core-senders` still points to the older Mason bootstrap.
|
||||
The receiver runbook records the later OpenBao migration; this packet uses that
|
||||
current authority and the platform's existing attended custody mechanics. It
|
||||
creates no second registry or generic credential broker.
|
||||
|
||||
Factory policy/caller admission, registered human binding, CCR-2026-0019's
|
||||
operator group, native runtime delivery and spending/operating acceptance stay
|
||||
with their existing records. Sender approval does not admit any of those acts.
|
||||
Loading…
Add table
Add a link
Reference in a new issue