Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a1029d-2c93-7500-a0e0-e3e089668b29
264 lines
16 KiB
Markdown
264 lines
16 KiB
Markdown
# Approved platform-root producer design
|
|
|
|
Prepared for NK-WP-0045-T05 / RPF-WP-0049, 2026-10-03. Founder approved:
|
|
"Accept ADR-0017 and approve the proposed OpenBao delivery design."
|
|
Scoped made decision receipt: `c2cff929-91b9-4018-bfd6-fa04f7da8280`.
|
|
This selects railiance-platform and the exact source below. Identity admission,
|
|
attended live provisioning, custody provenance and live readiness remain pending.
|
|
NetKingdom canon remains authoritative; reviewed baseline is net-kingdom commit
|
|
`db319335b27b61b855382ee5af5d690f06eeb010`. Deployments must pin the validator
|
|
and its schema together, and reconcile amendments before publication.
|
|
|
|
## Approved source and transport
|
|
|
|
- KV v2 mount: `platform` (existing owner convention; live suitability unverified).
|
|
- Exact API path: `/v1/platform/data/custody/net-kingdom/platform-root`.
|
|
- `record_id`: `nk-custody:platform-root`; `owner_system`: `net-kingdom-custody`.
|
|
- API response unwrap: `data.data.document` is the complete canon document.
|
|
`data.metadata.version` is KV concurrency state, distinct from canon revision.
|
|
- Reader: owner manifests identify namespace `user-engine`, ServiceAccount
|
|
`user-engine`. Role `user-engine-root-custody-reader` on `auth/kubernetes`
|
|
binds exactly those values and audience `openbao`. Tokens last at most 60s,
|
|
with no default policy. Dedicated projected JWT is owned by rapp-user-engine;
|
|
the existing flex-auth JWT and ESO AppRole are not reused. Live admission
|
|
remains unexecuted. Reader policy is exact-path read;
|
|
no list, sibling read or write. Never distribute an attended writer token.
|
|
- Writer: separate human custody lane, bounded attended MFA operator login,
|
|
reviewed exact-path policy. This packet does not grant a credential or role.
|
|
- Reader timeout 5 seconds, maximum document 256 KiB. A successful authenticated
|
|
owner read, not document time or a cache read, sets observed_at. Failure means
|
|
no grant. No raw server response/error logging.
|
|
|
|
## Offline implementation
|
|
|
|
`scripts/root_grant_publish.py` creates a single KV v2 CAS payload from a
|
|
candidate, previous document, exact previous KV version and the pinned
|
|
NetKingdom validator module. No network or publication is implemented here.
|
|
It validates both documents, exact source identity and successor semantics;
|
|
refuses missing existing baselines, same-revision changes and rollback. CAS=0
|
|
is bootstrap-only, CAS=current-version updates; a CAS conflict requires a fresh
|
|
owner read and revalidation, never blind retry. It never prints documents.
|
|
|
|
The attended executor is implemented in `scripts/root_grant_attended.py`:
|
|
|
|
- `provision` checks existing Kubernetes auth and active audit, admits only the
|
|
exact reviewed reader policy/role, enables CAS on this key and verifies all
|
|
readbacks. Differing existing policies/roles are refused without overwrite.
|
|
- `publish` reads current document and KV version together, validates pinned
|
|
canon and the persisted high-water baseline, fsyncs a pending journal before
|
|
CAS write, verifies exact readback, retains immutable local history and
|
|
atomically advances state. Exact replay creates no new version. Ambiguous
|
|
writes recover only after exact matching owner readback and durable history.
|
|
- `restore-check` requires the independently retained publisher baseline to
|
|
match the restored source exactly. Missing/different baseline never resets
|
|
authority or permits rollback. Off-host history backup is still an execution
|
|
dependency; local files alone cannot prove safe disaster restoration.
|
|
- The silent child requires the existing warden attended-login envelope and
|
|
exact loopback OpenBao tunnel. No raw process response/error is emitted.
|
|
Every invocation requires a new receipt path: old success receipts are refused.
|
|
|
|
## Authorized attended execution packet
|
|
|
|
Founder approval to "go forward" authorizes continued implementation and bounded
|
|
provisioning of the approved design. No additional generic design approval is
|
|
requested. Attended OIDC/MFA must still run in the founder's own terminal:
|
|
|
|
```bash
|
|
BAO_ADDR=http://127.0.0.1:18200 VAULT_ADDR=http://127.0.0.1:18200 \
|
|
warden access openbao-platform-admin-login --exec -- \
|
|
/home/worsch/railiance-platform/scripts/root-grant-attended.sh provision \
|
|
--receipt /tmp/platform-root-admission-UNIQUE-RUN.json
|
|
```
|
|
|
|
Replace UNIQUE-RUN with a fresh run identifier. The child is silent. Inspect the
|
|
new JSON receipt and warden's printed result; a shell exit code or previous
|
|
receipt cannot establish success. Provisioning does not create a custody grant.
|
|
Existing operator platform-admin identity provides the human writer lane;
|
|
this packet does not create another privileged identity or reuse its token in
|
|
user-engine. Deployment/network policy/consumer activation belongs to
|
|
rapp-user-engine and follows source image publication and admission receipts.
|
|
|
|
The founder reported that no actual custody ceremony is known. NetKingdom has
|
|
therefore prepared `examples/custody-record/initial-empty-record.json`, a
|
|
schema-valid first publication candidate with `entries: []`. It establishes no
|
|
root grant. The non-secret provenance is
|
|
`net-kingdom/docs/evidence/2026-10-03-root-grant-delivery-progress.md`.
|
|
Continued go-forward approval covers preparing and publishing this no-grant
|
|
baseline through the attended owner lane; no new generic approval is needed.
|
|
A future real grant still requires a genuine signed human ceremony with exact
|
|
issuer and subject; planned roster/LLDAP membership cannot supply it.
|
|
|
|
After successful admission, run this second attended step in the founder's
|
|
terminal. Create the operator-owned state directory first; it must persist
|
|
outside the checkout and outside warden's temporary attended-login home.
|
|
|
|
```bash
|
|
install -d -m 700 /home/worsch/.local/state/net-kingdom-root-custody
|
|
BAO_ADDR=http://127.0.0.1:18200 VAULT_ADDR=http://127.0.0.1:18200 \
|
|
warden access openbao-platform-admin-login --exec -- \
|
|
/home/worsch/railiance-platform/scripts/root-grant-attended.sh publish \
|
|
--candidate /home/worsch/net-kingdom/examples/custody-record/initial-empty-record.json \
|
|
--state /home/worsch/.local/state/net-kingdom-root-custody/baseline.json \
|
|
--provenance-ref net-kingdom/docs/evidence/2026-10-03-root-grant-delivery-progress.md \
|
|
--net-kingdom /home/worsch/net-kingdom \
|
|
--validator-digest 9156e399c8d92a45b817bfc3738c89843487ce57e1718ed747f804f95cc719bb \
|
|
--schema-digest bb6cd6da5dc48eddcf118ae78c2cacfafd5f860098fd8a8368fe6bc845776d07 \
|
|
--receipt /tmp/platform-root-publish-UNIQUE-RUN.json
|
|
```
|
|
|
|
Inspect the new receipt. Existing source without independently retained state
|
|
is refused rather than overwritten; a failed/ambiguous write requires owner
|
|
readback and journal recovery. Bootstrap uses CAS=0. The publisher retains
|
|
baseline.json and immutable history/ receipts. Restore `baseline.json`, history/
|
|
and any pending journal from independently retained latest evidence before a
|
|
recovery check; restoring only an older OpenBao snapshot cannot establish
|
|
current authority. The operator-workstation state is already off-host and independent of
|
|
railiance01/OpenBao. Documenting backup and readback of that receipt holder
|
|
remains an explicit acceptance dependency; no new service is required merely
|
|
to duplicate it. Local state enables safe
|
|
publication but does not satisfy that independent recovery proof.
|
|
|
|
`restore-check` takes the same source pins and state but no candidate or
|
|
provenance argument, plus a fresh receipt path, via the same attended wrapper.
|
|
Source digests enforce the reviewed NetKingdom validator and schema without
|
|
importing an unreviewed path. Neither command should print document contents,
|
|
privileged tokens or raw backend errors.
|
|
|
|
Acceptance also needs revocation/supersession exercise and rollback/restore
|
|
receipts. Exercise real grant changes only under their own custody ceremony
|
|
approval. Use isolated synthetic paths for non-live algorithm exercises.
|
|
|
|
## History, recovery and audit
|
|
|
|
OpenBao audit is owned by railiance-platform; the custody fact and ceremony are
|
|
owned by net-kingdom-custody. Confirm mount backup owner and restoration before
|
|
calling this source live. Retain KV history and independent publication digest /
|
|
revision high-water receipts. Readers persist their own trusted baseline across
|
|
restart. A restored snapshot must not reactivate an older grant: suspend reads,
|
|
compare restored record with independently retained latest baseline, reconcile
|
|
all later custody actions, and re-enable only after owner receipts. Do not
|
|
reset baselines, destroy versions or recreate an old record under the same ID.
|
|
KV CAS prevents races, but is not proof against snapshot rollback. Retention and workstation receipt-holder backup/readback proof remain owner
|
|
acceptance requirements, alongside isolated OpenBao recovery evidence.
|
|
|
|
No control was relaxed and no live action was taken. Emergent knowledge 0.2.3
|
|
start was withheld/orientation-only (digest
|
|
60f8811c6b94b30d357a0d9e5022f2a8ea52e69b47138d3a536755f3295310b5);
|
|
source review read the-custodian agent-environment-orientation section 0 and
|
|
informed-decision README, plus the source NetKingdom contract/schema/validator.
|
|
|
|
Producer delivery receipts complete RPF-WP-0049-T05 / NK-WP-0045-T05.
|
|
Consumer integration and runtime acceptance follow in USER-WP-0037-T02 /
|
|
NK-WP-0045-T06; they do not block initial producer delivery.
|
|
|
|
## Attended execution outcome — 2026-10-03
|
|
|
|
The founder executed admission and empty publication. Fresh receipts, initial
|
|
revision 1/KV1/no-grant digest and exact residual recovery/reader evidence are
|
|
recorded in [delivery evidence](../../docs/evidence/2026-10-03-platform-root-custody-delivery.md).
|
|
This completes RPF-WP-0049-T04. T05 remains evidence-blocked; generic approval
|
|
is not pending. Old operator role configuration is not an execution receipt.
|
|
|
|
## Remaining bounded attended finish
|
|
|
|
Native isolated Raft recovery and local receipt-holder scratch restoration now
|
|
pass. The operator-owned directory has no discovered workstation backup job.
|
|
The non-authoritative recovery copy in docs/evidence/root-custody-history enters
|
|
the existing owner Forgejo source backup scope; that does not imply a fresh
|
|
provider archive has included this new commit. One attended command completes
|
|
current live baseline check plus direct protected history provider readback:
|
|
|
|
```bash
|
|
BAO_ADDR=http://127.0.0.1:18200 VAULT_ADDR=http://127.0.0.1:18200 \
|
|
warden access openbao-platform-admin-login --exec -- \
|
|
/home/worsch/railiance-platform/scripts/root-custody-finish-attended.sh \
|
|
--state /home/worsch/.local/state/net-kingdom-root-custody/baseline.json \
|
|
--net-kingdom /home/worsch/net-kingdom \
|
|
--receipt /tmp/platform-root-finish-UNIQUE-RUN.json
|
|
```
|
|
|
|
The silent child uses the current governed OpenBao backup account/lane only,
|
|
requires the known Backup owner and create-only share shape, checks quota,
|
|
encrypts history with current escrow, creates one uniquely named artifact under
|
|
the existing forgejo/ backup folder, downloads through operator authority and
|
|
verifies ciphertext and decrypted history equality. It deletes nothing and
|
|
changes no credential or policy. Read the fresh receipt; old receipts are refused.
|
|
|
|
A local historical rclone configuration was found during backup discovery and
|
|
its credential-bearing coordinates may have appeared in tool output. It is
|
|
never reused. The helper compares that share with the current lane in memory
|
|
and records only booleans. If it is the current lane, the helper stops before
|
|
upload and requires coordinated existing credential incident/cutover recovery,
|
|
preserving consumers; it never rotates an uninformed predecessor. If different,
|
|
the historical owner's revocation status remains unverified separately from
|
|
root-grant authority. No credential-bearing coordinates are copied to evidence.
|
|
|
|
## Finish failure receipts
|
|
|
|
The first finish attempt failed after successful authenticated owner reads but
|
|
before a receipt. Its exact provider cause was lost by the old catch-all; it is
|
|
not evidence of missing IAM. The corrected wrapper reserves a fresh receipt
|
|
before helper imports and always records safe stage/error codes. Inspect that
|
|
receipt after execution even if the child returns nonzero. Failed upload or
|
|
readback includes safe numeric HTTP status and generated artifact name when
|
|
available; do not rerun with the same receipt path or weaken expected provider
|
|
contract/status checks blindly. No token, share coordinates, private key, raw
|
|
response or exception message is written. `helper_import` means startup failed;
|
|
`backup_operator_read` means current owner credential retrieval failed;
|
|
`provider_contract`, crypto, quota, upload/download or ciphertext/decrypt stages
|
|
identify the remaining provider proof boundary. Login cleanup and task success
|
|
remain separate, and only a verified fresh success receipt completes T05.
|
|
|
|
The finish helper also uses the established independent operator escrow at
|
|
/home/worsch/.config/age/railiance-backup.key. It derives that key's public
|
|
recipient in a captured subprocess, compares it with the current governed lane
|
|
and decrypts the downloaded artifact with the independent key file. Only match
|
|
and decryption booleans are recorded; the private key is never read into logs
|
|
or replaced. A missing/different escrow is an explicit fixed-code recovery
|
|
failure, not a request to create or reset a key implicitly.
|
|
|
|
The 2026-10-03 finish receipt returned HTTP401 at public upload after current
|
|
baseline and independent escrow verification passed. Corrected clients include
|
|
Nextcloud's required `X-Requested-With: XMLHttpRequest` header for public DAV
|
|
non-GET operations. See [official DAV documentation](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/WebDAV/basic.html)
|
|
and [stable31 public handler](https://github.com/nextcloud/server/blob/stable31/apps/dav/appinfo/v2/publicremote.php).
|
|
Live causality is unproved until a fresh attended finish run succeeds. This
|
|
changes request protocol only; preserve lane/token/permissions and do not rotate
|
|
credentials or fall back to wider account uploads. Failure receipts now retain
|
|
current lane KV version. The historical exposed share differs from current
|
|
lane; separate historical owner/revocation evidence remains unverified.
|
|
|
|
The corrected-header retry still returned401 against lane KVversion3. Before
|
|
another upload use the same attended wrapper with `--inspect-share` and a fresh
|
|
receipt path. This performs only owner-scoped existing-share OCS inspection and
|
|
Depth0 public DAV route probes; successful diagnostic receipt explicitly sets
|
|
`backup_roundtrip_proved=false`. Current route uses reviewed lane coordinates;
|
|
documented `/public.php/dav/files/{token}` is probed read-only, with and without
|
|
Basic auth. Protected shares require their password per official documentation;
|
|
no password is inferred or changed. A later repair must follow diagnosed owner
|
|
procedure; inspection cannot change lane, shares or provider files.
|
|
|
|
Actual read-only inventory found neither token nor label in exact folder at
|
|
lane KV3. This is not proof of deletion or absence in subfolders. Repair mode
|
|
checks all Backup account-owned shares for label ambiguity, verifies exact
|
|
folder and account before creating only the reviewed create-only public link.
|
|
It requires explicit `--repair-share --expected-lane-version 3 --confirm-repair
|
|
"RESTORE Backup CREATE ONLY"`. Existing or new candidate must have exact
|
|
owner/path/label/public type/permissions4, known absent password and expiry.
|
|
Known share re-read must match. Then actual retained history is encrypted,
|
|
uploaded through documented public files route with required header, downloaded
|
|
as Backup, independently escrow-decrypted and compared BEFORE CAS. Only token
|
|
and URL are changed; every other lane field and all old shares/files preserved.
|
|
Fresh receipt keeps share ID and provider proof if subsequent CAS/readback fails.
|
|
On retry matching reviewed candidate is reused; stale expected version refuses.
|
|
PROPFIND denial alone does not prove grant invalid: create-only policy can deny
|
|
read properties. Backup consumers need normal governed credential refresh after
|
|
cutover; this is separate from custody history proof and no live rollout occurs.
|
|
|
|
Producer recovery completed2026-10-03: fresh founder repair receipt proves
|
|
current empty revision1/KV1 matches retained baseline, actual encrypted upload201,
|
|
Backup readback200, independently escrow-decrypted history match before CAS3->4.
|
|
See [safe provider receipt](../../docs/evidence/2026-10-03-root-custody-provider-recovery.json).
|
|
Producer plan RPF-WP-0049 finished. Backup runtime consumer refresh remains
|
|
activity-core-owned; historical share revocation is separately unverified.
|
|
No real custody grant was added.
|