railiance-platform/docs/credential-lane-designs/factory-native-acceptance.md
codex 005c68eb4c
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Record native sender acceptance and retained audit readback gate
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
2026-09-11 14:23:07 +02:00

112 lines
6.3 KiB
Markdown

# Bounded native factory sender acceptance
RPF-WP-0035-T08 and AUDIT-WP-0009-T09/T11 retain this acceptance under approved
CCR-2026-0021/0022. Custody and delivery are already complete. This operation
creates no credential, registry entry, approval, disposition or UI service.
The six exclusive resources are one immutable ConfigMap, one probe-only
NetworkPolicy and one Job in each producer namespace. Jobs mount only their
own delivered audit field, have no API token, run as UID 10001 with read-only
root and no capabilities, and use disposable private SQLite state. Egress is
restricted to Audit Core's receiver and cluster DNS; existing namespace
NetworkPolicies refuse preparation for native execution because grants add.
Jobs have a 150-second deadline and no retry. Cleanup is UID guarded and waits
for each Job and its pods to disappear before removing its isolation policy.
The runtime image is the already published Approval Engine 251941a5 digest.
The immutable ZIP contains 31 actual producer Python files from Approval
Engine a0a60297 and Informed Decision bda9381f. Both sources and the full packet
are hash pinned. This proves source adapter/outbox integration on Railiance;
it does not publish or admit Informed Decision's full service image.
Each job seeds exactly one explicitly synthetic outbox record in its disposable
store. It sends through the real audit adapter, loses the successful 202 receipt,
starts a fresh Python process, and drains the preserved outbox with a 200 duplicate.
It checks exact source/tenant refusals, seven evidence-read refusals, invalid
bearer refusal, one own-source reconciliation count and sibling-count refusal.
No domain approval/disposition API is called, and no production heartbeat is
emitted. Domain-transaction atomicity is not retested by synthetic outbox seeding.
The optional attended readback parent reads the authoritative registry only in memory, verifies
the two exact sender scopes, selects an unambiguous existing independent
read-only full-tenant operator, and retrieves only the two named synthetic
events and chain-integrity metadata through a private loopback port-forward.
Credentials never appear in arguments, stdout, logs or receipts. This uses the
reviewed platform-admin envelope; no producer receives the operator registry.
Prepare and inspect before opening the attended window:
```sh
python3 scripts/native_factory_acceptance.py prepare \
--source-root /home/worsch --packet /operator/unique-packet.json
```
The result names the packet digest. Under `scripts/openbao-attended-exec.py`:
```sh
python3 scripts/native_factory_acceptance.py run \
--packet /operator/unique-packet.json --packet-sha256 REVIEWED_SHA256 \
--kubeconfig /operator/railiance-kubeconfig --server https://127.0.0.1:16444 \
--receipt /operator/unique-native-receipt.json \
--confirm 'VERIFY CCR-2026-0021 CCR-2026-0022 PRODUCERS'
```
Five preparation/guard/integration tests pass. The integration test runs both
real source outboxes in the pinned image against actual local Audit Core and
preserves exactly two events with an intact chain. All six native objects pass
server dry-run. Neither rehearsal result is claimed as native evidence.
Success remains `native_producer_delivery_verified_pending_bearer_revocation_and_service_admission`.
Invalid bearer refusal does not prove revocation of a previously admitted audit
bearer. CCRs stay applied until their remaining lifecycle acceptance exists;
rotation/revocation must use its separately reviewed owner procedure. Service
startup, human binding, native policy/caller admission, attestation/offsite
operation and factory execution remain in their existing owner records.
## Consume existing producer credentials without an operator login
The first combined attempt failed at OIDC before command handoff; no native
job ran. Split normal producer consumption from privileged operator readback.
`jobs` uses only Kubernetes metadata and the existing approved Secret references;
it never reads OpenBao or obtains an operator token. The audit credential is
read solely inside its own source-pinned producer Job. The same packet, exact
confirmation, native receiver check and bounded resource/cleanup gates apply.
Run `jobs` with the same options as `run`. A successful receipt has status
`native_sender_checks_passed_pending_independent_readback`. Use a fresh receipt
path, and preserve it. After successful jobs, do not use `run` again: repeat
sends must not be mistaken for a new first acceptance.
For independent readback, use `readback` inside a fresh attended envelope with
`--producer-receipt <successful-jobs-receipt>` and a new `--receipt`. It verifies
the exact packet/run/event identities and reads only those already stored
probe records and chain metadata. It creates no Job and emits no new event.
The operator login remains required for that separate registry-backed reader.
The native local rehearsal uses a setgid tmpfs root to represent fsGroup
volume inheritance. Informed Decision initializes its store through its actual
container helper; unsafe existing private directories remain refused. Failed
Jobs retain only allowlisted assertion codes and HTTP status numbers before
UID-scoped cleanup; arbitrary container output is discarded.
## Retained successful native run
The 2026-09-11 10:42 UTC sender run passed and all temporary resources are gone.
The exact packet and successful sender receipt are retained under `docs/evidence/`
so independent readback can resume without a producer rerun:
```sh
python3 scripts/openbao-attended-exec.py -- \
python3 /home/worsch/railiance-platform/scripts/native_factory_acceptance.py readback \
--packet /home/worsch/railiance-platform/docs/evidence/2026-09-11-factory-native-producer-packet.json \
--packet-sha256 5e8a20e29fb309924005a061939c94d8a40815126c44654b6daeb8adf18424c7 \
--producer-receipt /home/worsch/railiance-platform/docs/evidence/2026-09-11-factory-native-producer-jobs.json \
--kubeconfig /home/worsch/.kube/config-hosteurope \
--server https://127.0.0.1:16444 \
--receipt /tmp/factory-native-independent-readback.json \
--confirm 'VERIFY CCR-2026-0021 CCR-2026-0022 PRODUCERS'
```
Use a fresh receipt path if the named path already exists. Both prior attended
verification attempts failed before command handoff, with remote session
revocation unconfirmed. They did not read the operator registry or run readback.