audit-core/docs/flex-auth-secrets-engine-admission.md
tegwick 64509d2c40
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Define retained PDP audit admission and complete-ledger reconciliation
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
2026-10-16 19:25:03 +02:00

183 lines
12 KiB
Markdown

# First protected workflow: Audit Core admission packet
Prepared 2026-10-16 for TSA-09, AUDIT-WP-0013-T02, FLEX-WP-0031-T02/T06/T08,
SECRETS-WP-0013 and RPF-WP-0035-T12. This packet grants no sender, observer,
credential, deployment or protected effect authority. T02 remains waiting.
## Exact source and receiver compatibility
Reviewed Access source `0a05383195213e7eaacd08388ce1d7892ce756df`, particularly
`internal/emission/outbox.go` and `delivery.go`; Audit base
`2e97f37c01b583ac779310a2aa0d938bb9816604`. The protected consumer pin is
`flex-auth.secrets-engine`, distinct from generic `flex-auth` and other pins.
Access emits the existing eight-field contract in `docs/event-envelope.md`.
No translating adapter or second event schema is needed. Preserve event id,
Idempotency-Key, source, tenant, correlation, original time and data; the archive
does not authenticate a decision signature or establish approval validity.
Inventory: `flex-auth.decision.allow`, `.deny`, `.redact`, `.not_applicable`,
`.audit_only`, plus transport class `audit-core.heartbeat`. Heartbeat data.class
names one exact rare class, with assertion, committed and released_uncommitted
counts. Four heartbeats are four retained events, not four decision counts.
Outbox sequence and committed_at are local entry fields; the current wire event
has no stream_instance_id or sequence. Do not promise native receiver instance
filtering or wire sequence-gap detection for this source merely because the
receiver has that optional filter. Scope, lifetime and boundary are required
before comparing cumulative source counts.
The new isolated receiver tests exercise all five decision types: first202,
same-id duplicate200, changed-body409, write-only read403, independent fixture
readback, exact source/tenant, once-only counts and half-open acceptance-time
boundaries. They exercise wrong scope refusals and class-specific silence.
The identities and narrowed tenant:platform in tests are synthetic fixtures,
not proposed production grants. No live record or real decision validation is
claimed by these tests.
## Existing deployed evidence and its limit
Audit `docs/evidence/2026-10-15-cadence-admission/receiver-cadence-release-native.json`
records image `sha256:b479801b0bc76df66a36a85376c45aaf399c6d82feade9ba81430b774c4a8271`,
Deployment UID `b85fe3d0-75c9-4e0d-8c34-c6f1df0881bb`, source5227fb1 and
synthetic native cadence/heartbeat/exact-scope/SQLite/PostgreSQL feature probes.
The same folder records migration0007 and admitted Qonto/Approval metadata.
These are historical receiver capability receipts, not fresh flex-auth admission
or independent protected-workflow acceptance. Revalidate deployed image, readyz,
configuration metadata and migration compatibility before using them for native
acceptance. No production inspection was performed for this packet.
## Metadata prerequisites before any custody change
Access owner must return one reviewed per-pin registration payload and canonical
cadence bytes/digest for this pin, plus authoritative retained deployment source,
image, namespace `flex-auth`, exact AND namespace/pod selectors and configured
emission source. Do not derive pod selectors solely from a Helm release name.
Existing six-pin commitment in docs/cross-repo-evidence-admission.md requests
write true/read false, exact per-pin source, tenants ["*"] on the recorded
deny-before-tenant-creation justification, explicit redact and load-bearing.
This packet neither narrows that accepted scope to the fixture tenant nor widens
it; a revised scope requires its owner review. Retention/access/export policy
and owner must be explicit; an intake accepting custody is not that policy.
Current `docs/contracts/decision-emission-cadence.json` declares generic
source flex-auth, four heartbeat intervals86400 and allow expected_min1 per3600;
its source state and observer status remain pending. It is not a final per-pin
payload. Its daily source heartbeat cannot be registered as hourly f3600 without
an Access-owned runtime/declaration update and provenance. If hourly frame is
adopted, record f3600/wait7200/effective10800 and prove actual runtime adoption.
Do not silently apply Approval Engine's `cadence_registration.prepare`: that
helper deliberately validates source=approval-engine and its own class set.
The generic SenderRegistry parser already supports the reviewed flex-auth
metadata; custody tooling can validate an in-memory candidate with it.
Platform owns contained sender seed/delivery, registry CAS/readback/ESO reload,
transport and PVC admission. Resolve the actual usable custody route with
`warden route find` and `show` before any credential/access request. Historical
AUDIT-WP-0013-T02 names an unusable draft audit-core-senders route; do not assume
it is corrected. Obtain current route evidence and required scoped approval.
Never copy a registry/token to this packet or give a writer archive-read scope.
Receiver ingress must pair namespace AND exact pod selector to port8080;
source egress and receiver service DNS are separately admitted. Source-owned
single-writer flock/64MiB bound is source progress; actual mounted durable PVC,
restart, full/fenced failure, bounded drain and retained cursor need native proof.
## Native writer acceptance, followed by independent readback
1. Retain source/deployment/configuration pins, registry metadata version/digest,
source declaration digest, original exact change authorization and rollback.
Check accepted source/class/tenant/retention/secret policy inventory against
actual receiver configuration without exporting credentials.
2. Owner runs the approved bounded fixture through its contained existing lane.
Record durable event IDs, original correlation/decision/approval/operation
references, source class/tenant, local outbox identity/lifetime and entry
sequence/committed_at; retain before/after cursor, pending, lag, counters and
sanitized first202/duplicate200/refusal receipts. No new metadata operation
is authorized by this packet; where native effect is unadmitted, retain wait.
3. Exercise wrong source/tenant400, invalid/expired bearer401, writer read403,
payload conflict409 and formerly-valid bearer refusal after owner revocation.
A dead letter is not accepted custody and a source stdout202 is not readback.
4. Existing independently authorized read-only owner retrieves each exact ID via
GET /v1/events/{id}; compare source, tenant, action, correlation and normalized
original payload/hash, plus accepted_at. GET /v1/events?correlation_id=... can
enumerate related records within that reader's actual authorized scope.
Record reader identity/role separation metadata and original receiver receipt
references; credentials stay contained. Existing operator reader is evidence
of a past lane, not automatic current access. If no admitted scoped reader
exists, this gate waits on that owner; never upgrade the source writer.
5. Establish the full producer denominator before matching any chosen IDs. The
independent owner retains the complete producer outbox.jsonl snapshot, source
revision, outbox/PVC lifetime identity and bytes/SHA256/EOF high-water H. Check
every newline-terminated entry, contiguous seq1..H, exact source, unique event
IDs, valid committed_at and complete inventory including zero classes. Pin
drain cursor seq/offset, committed counters and pending/lag to that snapshot;
cursor must refer to a real entry boundary and never exceed H. This is an
independently retained full ledger, not a producer-selected list of successful
IDs. An arbitrary chosen-ID readback cannot satisfy this denominator. Retain
independent transition/effect-owner receipts too: an omitted transition never
queued by a compromised producer remains outside the archive guarantee.
Compare all ledger IDs versus independently retained receiver records, after
explicitly declared bounded drain lag. Missing pending
IDs are lag until the bound expires, then a finding; acknowledged-but-missing
IDs, conflicts and unexpected IDs are separate findings. Exclude four heartbeat
transport events from decision-effect totals. Preserve duplicate attempt counts
while accepted IDs count once. Keep nonzero released_uncommitted as a finding;
zero observed after restart does not establish its historical absence.
6. For aggregate GET /v1/reconciliation name exact source/tenant and explicit
[since,until) accepted_at bounds. Derive the local comparison set by the same
independently read accepted_at of the exact retained IDs, not occurred_at,
local commit time or a cumulative GET /v1/emission snapshot. Report unresolved
boundary arrivals separately and repeat after bounded drain. Source status
lacks tenant/window splits and persisted remote acceptance times; its raw
total cannot be compared to an arbitrary receiver time-window total. This
event-ID/accepted_at method supports a bounded admitted run without claiming a
general unattended reconciliation implementation. Compare the complete map of
all classes, including unexpected classes, against receiver aggregate counts:
all expected IDs must exist, and any receiver count above the independently
enumerated expected map is an unaccounted-record finding. This detects extras
without pretending GET-by-ID itself enumerates the receiver. Correlation search
has a1000 ceiling and no pagination; it is not a complete source export.
Concurrent arrivals require a second independently retained complete ledger
watermark H2 covering the same receiver window, or an approved quiescent
bounded run. Do not report agreement while that boundary remains unsettled.
Independently retained full snapshots, repeated cadence execution, actual
missing-class observation and independent observer adoption remain required
for operational TSA-09 acceptance; this packet alone closes none of them.
7. Independently observe four distinct rare-class heartbeats, actual configured
cadence and lag. A controlled withheld-heartbeat check belongs in an admitted
non-production exercise; do not suppress production evidence. Keep never-seen,
stale, missing-class, duplicate, count and boundary findings distinct. King's
Guard owns independent operational observer acceptance under KG-WP-0005.
Rollback restores only the exact earlier admitted scope/configuration, records
uncertain delivery and retains outbox/cursor/events. It never deletes evidence,
replays an uncertain protected effect, accepts unsigned decisions, widens a grant
or revives a revoked credential. Audit arrival proves custody after arrival;
neither arrival nor an empty finding set proves source completeness. Independent
chain-head/offsite custody remains AUDIT-WP-0015-T01's separate open boundary.
## Cross-owner accounting review — 2026-10-16
Access owner confirms the initial lifecycle signer slice keeps auditDelivery
disabled. Its current native package has no wire/accounting extension and makes
no G2/hourly-adoption claim. Audit owner accepts the complete independently
retained ledger + exact-ID readback + all-class receiver-count protocol above
for a bounded source-to-receiver reconciliation. A source self-selected receipt
list is insufficient. This is an evidence protocol using existing APIs, not a
new assertion format or permission. Audit has no current source-wide paginated
export endpoint or canonical producer-accounting receipt schema. Original owner
ledger bytes and receiver records are authoritative; a Custodian summary is not.
For future unattended monitoring, Access may separately propose durable
outbox-lifetime stream identity and sequence metadata, but must preserve signed
DecisionEnvelope bytes. A receiver-compatible wrapper would need a source-owned
versioned wire contract and fixture changes; post-sign insertion into decision
data is refused. An emitter restart is not automatically a new outbox lifetime.
No producer extension is mandatory for the bounded full-ledger protocol above;
repeated complete producer ledger capture/independent retention and source-owned
per-pin cadence/runtime adoption are mandatory operational work still missing.
The previously skipped existing cross-owner test was run directly from the real
canonical Audit checkout using its actual sibling NetKingdom/Approval fixtures:
`python3 -m pytest -q tests/test_cadence_registration.py::test_real_owner_proposal_when_checkout_available`
passed1. This makes114 tested cases across the focused isolated run and the
canonical owner-fixture check; the isolated run itself remains113 pass/1 skip.
No foreign source was changed (pytest cache writes were denied by the sandbox).