feat: admit existing OpenBao catalog lanes
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s

This commit is contained in:
tegwick 2026-08-21 08:20:33 +02:00
parent 9d383442c8
commit 784be978bf
29 changed files with 1490 additions and 79 deletions

121
docs/catalog-admission.md Normal file
View file

@ -0,0 +1,121 @@
# Catalog Admission for Existing OpenBao Lanes
Catalog admission and infrastructure ownership are separate decisions. A lane
may already exist on a shared OpenBao mount and already reach its workload
through External Secrets Operator or Kubernetes auth. Adding that lane to the
secrets-engine catalog must not imply that secrets-engine may create the mount,
replace workload delivery, or broaden an existing role.
## Admission dimensions
### Mount management
`mount_management` describes only who creates the OpenBao secrets-engine mount.
| Value | Plan and apply behavior |
| --- | --- |
| `engine` | The guarded plan may include a `kv-mount` action; apply ensures the mount exists. This is the compatibility default for existing catalog entries. |
| `existing` | The plan emits a non-mutating `kv-mount-check`; apply never calls mount creation. Provisioning may still update the exact cataloged KV path after approval. |
Shared production mounts such as `platform` must use `existing` unless a
separate infrastructure decision explicitly delegates mount administration.
### Native delivery authentication
`delivery_auth` describes how secrets-engine itself obtains a scoped token for
positive verification and exec-time delivery. It does not describe or replace
workload authentication.
```yaml
delivery_auth:
method: approle
management: engine
# Optional safe overrides when the catalog id contains an admin-like term.
policy_name: se-prod-forgejo-operator-token
role_name: se-prod-forgejo-operator-token
```
| Management | Meaning |
| --- | --- |
| `engine` | A reviewed apply may create/update the exact read policy and AppRole for this lane. |
| `existing` | Policy and AppRole are externally managed. `role_name` is mandatory; plan/apply emit checks only and never mutate either object. |
| `none` | No native verification or exec delivery is available. Use only for catalog-only metadata without native delivery modes. |
The current native implementation supports AppRole. An entry that declares
`exec-env`, `exec-file`, `npm-config`, `read-check`, or `wrapped` must therefore
declare delivery auth. `exec-file` and `wrapped` remain reserved schema modes;
they are not implemented by `secrets-engine exec` yet.
Engine-managed AppRoles may bound `token_ttl`, `token_max_ttl`,
`secret_id_ttl`, `secret_id_num_uses`, and `token_num_uses`. The admitted
high-risk drafts use 15-minute tokens, a 30-minute maximum, single-use
`secret_id` values, and eight token uses.
### Existing workload delivery
`workload_delivery` records non-secret facts about delivery already operated by
another repository. Every item names both the mechanism and its owner.
```yaml
workload_delivery:
- mode: external-secrets
owner: rapp-example
```
This metadata is evidence and review context. `apply`, `provision`, `verify`,
and `exec` do not change ESO objects, Kubernetes auth roles, deployments, or
provider accounts.
## Example: existing production mount plus native exec adapter
```yaml
id: example-runtime-api-key
kind: kv
org: coulomb
repo: example-service
stage: prod
mount: platform
path: workloads/example-service/runtime
mount_management: existing
fields: [EXAMPLE_API_KEY]
consumers:
- name: example-service-runtime
auth: kubernetes
claim: system:serviceaccount:example:example-service
purpose: production runtime access through ESO
workload_delivery:
- mode: external-secrets
owner: rapp-example-service
delivery_modes: [exec-env, read-check]
delivery_auth:
method: approle
management: engine
# approval, verification, rotation, deactivation, and audit remain required.
```
The guarded plan may propose a new exact-path delivery policy and AppRole after
approval, but it emits only a check for the shared `platform` mount. The
existing Kubernetes/ESO delivery remains untouched.
## Admission checklist
Before accepting an existing production lane:
1. Confirm exact mount, path, and field names from the current owner.
2. Set `mount_management: existing` for shared or pre-provisioned mounts.
3. Record existing workload delivery and its repository owner.
4. Decide separately whether native delivery auth is engine-managed, existing,
or absent.
5. Use exact policy/role overrides when the catalog id would trip broad-admin
name guards; never weaken path or capability guards to accommodate a name.
6. Mark high-risk lanes explicitly; they require named rotation and
deactivation owners and cannot use bootstrap-only approval.
7. Link a resolved approval before live apply, provisioning, verification,
rotation, revoke, or exec. Every privileged live command fails closed when
that approval cannot be resolved.
8. Preserve the interim route until native positive and negative verification
passes without exposing a value.

View file

@ -15,6 +15,12 @@ npm registry/scope live in `delivery_config.npm` as data — the engine never
hardcodes a registry. The pilot publishes `@whynot/design` from the
`coulomb/whynot-design` repo to `https://forgejo.coulomb.social/api/packages/coulomb/npm/`.
Existing production lanes additionally distinguish mount ownership, native
delivery auth, and workload delivery. See
[catalog-admission.md](catalog-admission.md). In particular,
`mount_management: existing` makes mount handling non-mutating; it does not
authorize secrets-engine to replace an existing ESO/Kubernetes delivery path.
## Install
```bash