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

6.3 KiB

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:

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:

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:

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.