The helper previews delivery with no OpenBao or node effect and refuses execution while the CCRs stay draft. Policies are read-only on each workload path. No provider key is included. Assistant: grok Assistant-Session: 01a11cdb-f9fe-7011-947c-936e72007e54
11 KiB
Application backup credential delivery — 2026-10-08
Prepared for RPF-WP-0053-T02/T05, CSOC-WP-0008-T02 and EMAIL-WP-0007-T03. Both requests are draft, bindings unconfirmed and delivery admission false. This packet creates no provider identity, OpenBao structure/value, ServiceAccount, node file, backup capture or timer. Source preparation is not owner acceptance.
| Consumer | Reader request | Authoritative KV pair | Node destination |
|---|---|---|---|
| Coulomb paired archive | CCR-2026-0036 | platform/workloads/coulomb-social/backup-primary | /etc/coulomb-social-backup/primary.env |
| Email ledger archive | CCR-2026-0037 | platform/workloads/email-connect/backup-primary | /etc/email-connect-backup/primary.env |
Both records contain exactly AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. Each has its own Scaleway IAM application/key, Kubernetes ServiceAccount namespace, OpenBao role and read policy. The destinations are root:root0600 in root:root0700 directories. Workers receive provider credentials; the delivery reader alone uses OpenBao, without a persistent bootstrap credential. Age decryption identities belong to independent recovery custody.
Public review sources
- credential-change-requests/CCR-2026-0036-coulomb-social-backup-primary.yaml
- credential-change-requests/CCR-2026-0037-email-connect-backup-primary.yaml
- openbao/policies/workload-kv-read-{coulomb-social,email-connect}-backup-primary.hcl
- openbao/backup-primary-serviceaccounts.yaml: two accounts, automount=false; no RoleBinding, Secret, mounted JWT or workload deployment.
- scripts/application_backup_credentials.py: dependency-free node reader/delivery.
- scripts/render_backup_credential_contract.py: existing platform validator and PyYAML export YAML source to a public JSON contract; the node needs no PyYAML.
- tests/test_application_backup_credentials.py: synthetic fixtures only.
The exporter verifies exact reader coordinates, delegated metadata-applier scope and policy equality. It embeds source CCR/policy hashes. After every owner/status update, regenerate and review the JSON export and pin its SHA256 in the node command; an old draft export cannot execute. The CCR remains the source of truth.
Required owner setup, in order
- Admit the proposed railiance01 root executor under T01. It already needs k3s administration for coherent capture; this design explicitly records that node administrators and namespace writers can exercise the reader identity. This is not a narrower alternative to root execution admission.
- Survey the existing bucket policy, IAM principals and lifecycle. Preserve native Barman/Forgejo principals and existing policy statements. Create two separate IAM applications; another key on an existing broad application does not establish isolation. Bind each caller to its exact application archive prefix with IAM plus bucket policy, including explicit effective denial where project-wide IAM would otherwise allow sibling access. Review the complete merged policy before its replacement; this packet supplies no blind overwrite.
- Admit each CCR with platform-owner and its named application-owner reviews, confirmed namespace/account/audience, and a reviewed structure change. Use railiance-platform's existing delegated metadata applier for policies/roles; ops-mason now surveys read-only under ops-mason-survey (MASON-IN-0004), and cannot apply structure. The existing kubernetes auth mount must use its admitted reviewer; no TokenReview authority is granted to these delivery accounts.
- Provision each provider pair atomically under an explicit platform custody act, initial KV CAS=0. Retain only its version receipt. The generic Warden paste-once desk currently runs a single-field KV PUT, replacing the record: two desk runs would discard the first field. It is unsuitable for this pair. A reviewed pair-aware custody child/front door is still required under T06; neither the node reader nor the administration-login lane provisions values.
- Verify positive reader identity and negative wrong namespace/account/audience, sibling GET, metadata GET, parent LIST, KV write and administration denials. Verify provider conditional multipart publication, version GET, foreign-prefix and retained-delete denial. These are contained owner proofs, not regression tests against production. Record native evidence before setting the CCR's delivery admission booleans and source_ref; do not infer them from code tests.
- Export the final admitted CCRs, review their hashes, create only the designated private node directories and stage public source/export artifacts. Run delivery at the pinned positive KV version; preserve the metadata receipt independently. Admission covers initial delivery, not capture, service activation or rotation.
Scaleway destination is s3://railiance-platform-pg-backup with endpoint https://s3.nl-ams.scw.cloud. Prefixes are platform-pg/application-archives/coulomb-social/ and platform-pg/application-archives/email-connect/. Publisher rights are conditional multipart create/parts/completion, abort of its own unfinished uploads, HEAD, version-pinned GET and prefix-constrained listing only if needed. Deny retained object/version deletion, native/sibling prefixes, bucket/IAM administration and escrow. Owner admission must also reconcile the existing 30-day lifecycle with 14 daily/4 weekly protected recovery points, capacity and independent receipts.
Scaleway's IAM/bucket policy guide explains the project-wide IAM boundary and granular bucket policy. No effective provider boundary is claimed before native proof under these specific callers.
Routing verification
Installed Warden 0.1.2 was rebuilt from the corrected checkout, preserving phase-memory. Bundled catalog hash 5e6b217aa1f6 matches current source. WARDEN-WP-0043 fixes keyword collisions without granting authority:
warden plan "attended OpenBao platform administration to configure read policies and auth roles for Coulomb and email backup delivery" --json
warden plan "provision a Scaleway object storage backup publisher key pair into OpenBao custody" --json
The first selects openbao-platform-admin-login, founder_required/oidc_login; survey still selects the read-only ops-mason ceremony. The second selects openbao-api-key, founder_required/paste_once_provision: this remains a generic owner pointer, not an admitted pair writer. Do not run the single-field desk for these pairs or use the administration identity as an unreviewed KV writer. An attended OIDC command must use Warden's contained child envelope, including its output and self-revocation requirements, for its exact reviewed operation.
Preview and admitted delivery shape
Public export (platform environment with the existing PyYAML validator):
python3 scripts/render_backup_credential_contract.py \
--application coulomb-social \
--ccr credential-change-requests/CCR-2026-0036-coulomb-social-backup-primary.yaml \
--output /tmp/coulomb-backup-reader-review.json
python3 scripts/application_backup_credentials.py \
--application coulomb-social --ccr /tmp/coulomb-backup-reader-review.json
Repeat with email-connect/CCR-2026-0037 and its own output. Default delivery preview has no network, TokenRequest or filesystem effects. --execute requires the exact reviewed export hash, an applied/verified/active CCR, confirmed bindings, named owner reviews with source references, native provider/reader proof and admitted node execution. The implementation does not authenticate these source statements; the owner must bind and approve the exact immutable export before the node run.
After those owner steps, the node command shape is:
sudo python3 /opt/railiance-platform/scripts/application_backup_credentials.py \
--application APPLICATION \
--ccr /etc/APPLICATION-backup/credential-reader.json \
--expected-ccr-sha256 REVIEWED_JSON_EXPORT_SHA256 \
--expected-kv-version APPROVED_POSITIVE_KV_VERSION --execute
This is not yet an executable activation instruction: neither installed source placement nor the approved values above exist. Source/export transfers contain no credentials. Do not transport provider pairs through scp, chat or /tmp files.
The reader pins kube-system UID a553c742-0115-43d4-99a4-a5ca56fe0786 before issuing a ten-minute TokenRequest JWT for backup-primary-delivery/openbao in its own namespace. Kubernetes has a ten-minute minimum; the resulting OpenBao token has a separate five-minute hard maximum and four-use limit, one policy and no default or identity policy. JWT and token stay in process memory. The helper checks the returned JWT binding/expiry, OpenBao token bounds and exact current KV version, revokes its token before file publication and verifies contained readback. Backend bodies, exception text and key hashes never enter receipts or outputs. Proxy environment and HTTP redirects are disabled for the OpenBao exchange.
Initial file publication uses a private temporary file, fsync and no-overwrite hard link. Symlink ancestors, unsafe target modes/owners, aliases and special files refuse. A lock excludes overlapping deliveries. SIGTERM unwinds through revocation; host loss/SIGKILL can leave a short-lived token until expiry and requires metadata reconciliation, never an automatic success claim. A crash after publication but before receipt can resume only by a new scoped read with exact file equality. Different existing bytes require a separate version-guarded rotation contract; this helper cannot overwrite them.
Evidence and remaining gates
Thirty synthetic delivery cases and four YAML/export cases pass, alongside thirty primary-archive/retention cases. They cover both profiles, draft/source/owner admission, narrower token checks, revocation failure, private-file attacks, payload injection, version changes, atomic failures and identical-file recovery. Current draft exports and policies validate without errors; the expected unconfirmed-binding warning blocks apply. Warden's complete regression gate passes, with the human stdout test now explicitly modelling a human independently of an agent session environment.
Shared security orientation was retrieved as emergent-security 0.2.6, digest 8d1d6a9d4d07fec7b619618de7dfe2be2254c1790f85f4198c7fe19db9751c02. It was withheld for source drift, so current ops-mason INTENT, custodian agent orientation and informed-decision README were read directly. No card was treated as authority.
No live credential delivery, provider upload or timer activation is evidenced. RPF-WP-0053-T02/T05/T06 retain the custody/admission work. T03/T04 retain the first publication, independent application recovery, schedule and monitoring/retention gates. CSOC-WP-0008 and CSOC-WP-0010 remain active; this preparation alone cannot complete either plan.