OpenBao key-custody backend (uniform AD + Keycloak) #29

Closed
opened 2026-07-25 17:43:56 +00:00 by Cordy · 2 comments
Owner

Manuel's suggestion for the open AD key-management question. Add a third KeyProvider backing per-user age keys in OpenBao (the active Linux-Foundation Vault fork; its transit engine is "encryption/keys as a service" — per-key derivation, convergent encryption, rotation, audit logs).

  • Gives uniform key custody across both Keycloak and AD users (AD has no writable profile attributes — the current gap).
  • Answers the custody-storage question (where keys live), not the access question (the backend still fetches/holds the key at runtime).
  • New dependency/service — weigh against the tiny-trust-surface goal (§1.4).

Source: https://openbao.org/docs/secrets/transit/

Manuel's suggestion for the open AD key-management question. Add a third `KeyProvider` backing per-user age keys in **OpenBao** (the active Linux-Foundation Vault fork; its **transit engine** is "encryption/keys as a service" — per-key derivation, convergent encryption, rotation, audit logs). - Gives **uniform** key custody across both Keycloak *and* AD users (AD has no writable profile attributes — the current gap). - Answers the *custody-storage* question (where keys live), **not** the *access* question (the backend still fetches/holds the key at runtime). - New dependency/service — weigh against the tiny-trust-surface goal (§1.4). Source: https://openbao.org/docs/secrets/transit/
Author
Owner

Decision — approved (Manuel's review, relayed by Nikola 2026-07-31):

"Yes, to be used as a key-custody backend."

Un-gated. OpenBao becomes the approved key-custody backend alongside (eventually uniform across) AD + Keycloak environments. Implementation prerequisites when greenlit: deploy OpenBao on k3s (GitOps like everything else), define the custody interface as a third keyCustody mode next to keycloak-profile and deployment, and per #30's rejection the model stays unique-key-per-user/group — OpenBao stores and serves those identities, it does not derive them.

**Decision — approved (Manuel's review, relayed by Nikola 2026-07-31):** > "Yes, to be used as a key-custody backend." **Un-gated.** OpenBao becomes the approved key-custody backend alongside (eventually uniform across) AD + Keycloak environments. Implementation prerequisites when greenlit: deploy OpenBao on k3s (GitOps like everything else), define the custody interface as a third `keyCustody` mode next to `keycloak-profile` and `deployment`, and per #30's rejection the model stays unique-key-per-user/group — OpenBao stores and serves those identities, it does not derive them.
Author
Owner

Shipped in v0.3.28 (PR #99) as keyCustody: "openbao".

Implemented as a KV v2 custody store, not the transit engine Manuel linked — deliberate: Cairn's at-rest format stays plain age files so age -d recovery keeps working (sovereignty feature), which means the backend must hand cairnd the identity rather than perform the crypto. Layout: {mount}/data/{prefix}/users/<username> and .../groups/<space> (#18 group keys covered), field identity. Lazy provisioning with check-and-set (cas=0) so racing replicas can never overwrite a live custody key. Config: openbaoBaseUrl, openbaoToken (or CAIRN_ENC_OPENBAO_TOKEN), openbaoMount (default secret), openbaoPathPrefix (default cairn). Recovery recipient handled identically to the other custody modes.

Unit-tested against a fake KV v2 (provision, group isolation, cas race, recovery). Not yet e2e'd against a real OpenBao — that wants an OpenBao instance on k3s, same pattern as the Keycloak e2e; worth doing before any customer runs this custody mode. Closing the build; the e2e can ride the AD-parity dress rehearsal.

Shipped in **v0.3.28** (PR #99) as `keyCustody: "openbao"`. Implemented as a **KV v2** custody store, not the transit engine Manuel linked — deliberate: Cairn's at-rest format stays plain age files so `age -d` recovery keeps working (sovereignty feature), which means the backend must hand cairnd the identity rather than perform the crypto. Layout: `{mount}/data/{prefix}/users/<username>` and `.../groups/<space>` (#18 group keys covered), field `identity`. Lazy provisioning with check-and-set (`cas=0`) so racing replicas can never overwrite a live custody key. Config: `openbaoBaseUrl`, `openbaoToken` (or `CAIRN_ENC_OPENBAO_TOKEN`), `openbaoMount` (default `secret`), `openbaoPathPrefix` (default `cairn`). Recovery recipient handled identically to the other custody modes. Unit-tested against a fake KV v2 (provision, group isolation, cas race, recovery). **Not yet e2e'd against a real OpenBao** — that wants an OpenBao instance on k3s, same pattern as the Keycloak e2e; worth doing before any customer runs this custody mode. Closing the build; the e2e can ride the AD-parity dress rehearsal.
Cordy closed this issue 2026-08-04 10:48:08 +00:00
Sign in to join this conversation.
No labels
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: Cordy/Cairn#29
No description provided.