[feature] OpenBao transit engine + broker + KV-sourced master key #27
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Execution tracker for the OpenBao integration. Design + plan live in Obsidian (source of truth):
edge-router/specs/2026-08-11-openbao-transit-broker-design.mdedge-router/plans/2026-08-11-openbao-transit-broker.mdBranch:
feat/openbao-transit-broker. Supersedes the transit portion of #20; unblocked by #18.What: opt-in OpenBao as the at-rest encryption engine (transit) and as a source for the master API key (KV), with all OpenBao credentials obtained from a local broker over a Unix socket — key material never enters the ER process. Local AES-GCM stays default; two independent toggles share one broker + one OpenBao.
Tasks (TDD, each independently testable):
broker.rs) — token over UDS, 90%-TTL cache, 403-refresh (mock-UDS-broker tests)CryptoEngineenum (Local | Transit); prefix-routed decrypt;.awaitrefactor of call sitesfile>inlineresolution flip + highest-security-wins-and-rejectskv_read+ v1/v2 field extraction)BAO_ADDR, real transit round-trip) + docsPre-flight: dev homelab runs a pre-per-service broker (one shared socket
/run/broker/broker.sock, broker itself registered) → no ER enrollment needed; Task 7 verifies against it. Confirm the actual transit key name + KV path/field at Task 7.Notes: migration is one-way (rollback needs a pre-migration DB snapshot);
ENCRYPTION_KEYresolution flips to file>inline (one non-additive behavior change). Verify the Alpine/musl Docker build after addinghyperlocal.Task 1 done —
e6ad026onfeat/openbao-transit-broker.broker.rs:TransitClient(token over UDS, ~90%-TTL cache, 403-refresh, HTTPS-only,Debug-redacted token) +is_transit_ciphertext. Offline tests via a mock UDS broker (cache-vs-refetch, https-only rejection, fail-closed-without-broker); real transit round-trip deferred to the gated live test (task 7). Deps added:hyperlocal,bytes. Full suite 202 green, clippy + fmt clean.Tracked debt:
mod brokeris#[allow(dead_code)]untilCryptoEngine(task 2) + startup wiring (task 6) construct aTransitClient. Remove the allow then.Tasks 2–7 remain. Task 2 is the broad async refactor of every
encrypt/decryptcall site (crypto.rs,health.rs,db.rs,middleware.rs,proxy.rs) — the security-sensitive core.All 7 tasks implemented on
feat/openbao-transit-broker(commitse6ad026,9da37d5,e4590ae,a5bc56a,d76a025):broker.rs) — token/UDS/cache/403-refresh, mock-broker testsCryptoEngine(Local|Transit) +.awaitrefactor of every call sitefile>inlineflip + highest-security-wins-and-rejects (pure, race-free tests)kv_read+ v1/v2 field extraction)Full suite 213 green (live test skips without
BAO_ADDR), clippy + fmt clean, zero dead-code allows. Alpine/musl Docker build (validateshyperlocal) in progress. Then: final review + merge tomain, and a live run against the dev broker to prove the real transit round-trip.Status: code-complete, blocked on live verification — NOT merged.
All offline gates pass on
feat/openbao-transit-broker: 213 unit tests, Alpine/musl Docker build (confirmshyperlocalcompiles), clippy + fmt clean, zero dead-code allows.But the feature has never run against real OpenBao — every passing test uses a mock UDS broker (canned token) or an injected
vault:v1:{pt}fake. Per our rule (verify external services against the real contract, don't assume documented behaviour), this must be proven before merge. Only a live run catches: the real transit response shape (.data.ciphertext/.data.plaintext+ base64), the actualvault:/bao:prefix (which migration idempotency + decrypt-routing depend on), and the broker's realGET /tokenJSON.Can't run it from the build host:
playground-broker-1's socket is not mounted on the host (/run/brokerabsent), anddevinfra-openbao-1is only on127.0.0.1:8200with an in-network cert the HTTPS-only client correctly rejects. The live test needs to run inside the dev environment where the broker socket is mounted and bao's cert is trusted:Prereqs to confirm there: the shared broker's policy grants a transit key ER can use (encrypt/decrypt), and (if testing KV) read on the master-key path. Merge to
mainis gated on this coming back green.