feat(sessions): relocatable private capabilities via OpenBao (PR 2/9) #653
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/session-private-openbao"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Session rows can survive a Postgres-backed cold restart while their MCP tokens, delegation grants and Sokar capabilities remain stranded in a pod's private files. This PR adds an opt-in OpenBao KV v2 backend and reconstructs verified private projections on a new data directory. Existing configurations continue to use local files.
This is PR 2/9, based on merged #652 and the design in #651. It is code/CI preparation only: no production enrollment, import, deployment, manifest change or volume switch. PRs 7–9 still require the disposition ledger and a separate operator GO. Please review and merge; no automatic merge is requested.
Implementation
akh-session-services: typedprivate_slotsconfiguration, scoped opaque KV paths, CAS, exact-intent reconciliation after a lost write acknowledgement, retained revocation tombstones, bounded verified-TLS requests and fixed secret-free failures. Remote mode requires exclusive Postgres service ownership. Bootstrap credentials are reread from a private mounted token file for rotation.akh-private-slots: offline per-session plan/apply importer. Requires quiescence, exclusive PG ownership and a verified migration receipt; validates source receipts/hash ledger, checks the complete reviewed manifest before CAS writes, and verifies exact retries. No archive extraction or PG row mutation. Import identity is independent of the destination pod's projection directory.scripts/platform-storage/PRIVATE-SLOTS.md: enrollment/configuration, crash ordering, private-source staging, rollback and remaining cutover gates. CI now runs a disposable OpenBao/Postgres contract harness.Validation
cargo test --locked -p akh-session-services --lib --test sessions: 139 unit tests and 29 session integration tests passed; the real-service test is intentionally ignored in this command and run by the harness below.AKH_STORE_TEST_DOCKER_CONTEXT=colima python3 scripts/platform-storage/test-private-slots.py: all 11 tests passed, including real OpenBao + exclusively owned Postgres cold restart/revocation, immutable retry/lost acknowledgement, conflicting bytes, private-write/PG-rollback recovery, missing/tampered/revoked authority, Sokar child retention/retirement/unknown outcomes/expiry, and hash-guarded import/repeat on another projection directory.--all-targetscheck and independent session/runtime profile checks passed. Formatting and whitespace checks passed. Clippy completed; existing warnings remain in unrelated code, with no diagnostics in the new private-slot modules.openbao/openbao@sha256:6d2b93856e3fcf7b18ad855a0b51eaba474dc8b79cf554379ea32034797d2acf) and PostgreSQL 18.6 (postgres@sha256:74935e72241653ca55e0414067e6d8763aceb8a810eb51b452253ec3dcfc4336). These digests record test provenance, not deployment pins. No provider tooling/image build was performed.Boundaries for the later cutover
PR 6 must reuse the houses migration #208/#212 SecretStore and Postgres-delivery patterns. It must deliver a narrowly scoped dynamic OpenBao writer; the daemon must not receive the ESO reader or operator identity. This PR creates no store, database role or production policy.
Sokar retains its existing file-path consumer contract. This PR reconstructs session-side files and journals broker-mediated child publication; it does not provide cross-pod file sharing or instrument direct CLI writes. Before enabling Sokar in the relocated platform, the core/workspace and manifest PRs must establish consumer-side delivery and audit every child-issuance path. Ambiguous external issuance/use still needs issuer/core evidence and operator disposition; the issuer lacks request-ID deduplication. The inspected platform configuration does not enable Sokar today.
The private importer does not claim to consume an entire backup. Unmatched files/uncommitted intents and the separate
sessions-privatebackup must be accounted for in the disposition ledger. The protected wk01 archive was not accessed. No Board use, production credentials, cluster writes or deployment were involved.Review fixes
rehydrate_private_slots()coverage exercisesissuing,using,retiringandrevoked, verifies healthy sessions still hydrate, and keeps ambiguous dispatch fenced.invalid_request, attempts private completion.transportandunknown_outcomestill retainusingwithout completing or replaying the effect.private_sokar_finish_errorcode. Duplicate calls return that saved response without a second core request, even during an OpenBao outage; pending private reconciliation remains explicit.0440/fsGroup: 10001projected Secret must be copied using the existing private-state init pattern to a UID/GID 10001-owned0600file in a0700private directory. The runbook also requires restart-on-rotation or a trusted atomic-copy mechanism; an init-only copy cannot follow ESO rotation.Optional minor observations (stale-CAS diagnostic classification, create-intent retention and tombstones for never-provisioned MCP slots) are unchanged in this focused correction. No merge, production import, deployment or manifest change.