281 lines
11 KiB
Markdown
281 lines
11 KiB
Markdown
---
|
|
id: RAILIANCE-WP-0008
|
|
type: workplan
|
|
title: "OpenBao Approved Automation Delegation"
|
|
domain: financials
|
|
repo: railiance-platform
|
|
status: active
|
|
owner: codex
|
|
topic_slug: railiance
|
|
planning_priority: high
|
|
planning_order: 8
|
|
created: "2026-06-28"
|
|
updated: "2026-06-30"
|
|
depends_on_workplans:
|
|
- RAIL-PL-WP-0002
|
|
- RAILIANCE-WP-0005
|
|
- RAILIANCE-WP-0006
|
|
- RAILIANCE-WP-0007
|
|
state_hub_workstream_id: "671898ef-2378-4814-b8f6-066148cdad46"
|
|
---
|
|
|
|
# RAILIANCE-WP-0008 - OpenBao Approved Automation Delegation
|
|
|
|
## Goal
|
|
|
|
Create a narrow OpenBao automation delegation path so approved credential and
|
|
it-sec changes can be applied without handing broad `platform-admin` power to an
|
|
agent, while still preserving different build, test, and production security
|
|
requirements.
|
|
|
|
This closes the current gap where reviewed CCRs can be approved and rendered,
|
|
but live application still fails with `403 permission denied` on
|
|
`sys/policies/acl/...` unless a human operator uses broad OpenBao admin
|
|
privileges.
|
|
|
|
## Problem
|
|
|
|
The current model has two bad modes:
|
|
|
|
- fully manual OpenBao UI work, which can unblock one credential but is slow,
|
|
hard to review, and easy to drift from the CCR;
|
|
- broad `platform-admin`, which is too powerful for routine automation and too
|
|
risky to hand to agents.
|
|
|
|
The issue appears in multiple workstreams:
|
|
|
|
- `RAILIANCE-WP-0005` token-grant apply failed on
|
|
`sys/policies/acl/credential-broker-warden-sign-issuer`;
|
|
- `RAILIANCE-WP-0007` whynot-design CCR apply failed on
|
|
`sys/policies/acl/workload-kv-read-whynot-design-npm-publish`.
|
|
|
|
Both are approved non-secret metadata changes. They should not require a human
|
|
to hand-type OpenBao policy and auth-role writes once review is complete.
|
|
|
|
## Direction
|
|
|
|
Add one or more constrained OpenBao applier identities that can apply only
|
|
reviewed, generated metadata for approved change classes.
|
|
|
|
The applier must not be a general `platform-admin` replacement. It should:
|
|
|
|
- verify a resolved State Hub decision or CCR status before live mutation;
|
|
- write only allowed policy names and auth role prefixes;
|
|
- never read or print secret values;
|
|
- record non-secret apply evidence;
|
|
- keep production secret value provisioning under approved operator custody
|
|
until a separate wrapped or dual-control flow is approved.
|
|
|
|
## Environment Model
|
|
|
|
Build and development:
|
|
|
|
- automation may apply approved sandbox metadata;
|
|
- generated test secrets may be allowed only in non-production mounts;
|
|
- approvals can be lightweight but still recorded.
|
|
|
|
Test and staging:
|
|
|
|
- automation may apply approved metadata after validation and owner review;
|
|
- verification must include positive and negative access checks;
|
|
- secret values should use wrapped delivery or operator custody depending on
|
|
risk classification.
|
|
|
|
Production:
|
|
|
|
- automation may apply only approved non-secret metadata such as narrow ACL
|
|
policies and auth roles;
|
|
- production secret values remain out-of-band operator custody unless a later
|
|
workplan creates a stronger wrapped or dual-control provisioning path;
|
|
- activation requires verification evidence before ops-warden or another front
|
|
door becomes resolvable.
|
|
|
|
## Proposed Policy Shape
|
|
|
|
Start with one production candidate policy, for example
|
|
`credential-change-prod-applier`, and keep it intentionally narrow:
|
|
|
|
- allow `create`, `update`, and `read` on `sys/policies/acl/workload-kv-read-*`;
|
|
- allow `create`, `update`, and `read` on approved credential-broker issuer
|
|
policy names such as `credential-broker-*-issuer`;
|
|
- allow `create`, `update`, and `read` on selected auth role prefixes such as
|
|
`auth/netkingdom/role/*-workload-kv-read`,
|
|
`auth/kubernetes/role/*`, and `auth/token/roles/credential-broker-*`;
|
|
- allow read/list only where needed for idempotent verification;
|
|
- deny broad `sys/*`, `auth/*`, `platform/*`, `identity/*`, `root`, and
|
|
`platform-admin` semantics.
|
|
|
|
Policy-name and role-name restrictions should be enforced in both OpenBao ACLs
|
|
and the local applier script.
|
|
|
|
## Tasks
|
|
|
|
## T01 - Specify delegated applier policy boundaries
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0008-T01
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "d19fdfc5-addb-4813-8086-3aca2e948cea"
|
|
```
|
|
|
|
Define build, test, and production applier capabilities, including exact
|
|
OpenBao paths, allowed name prefixes, denied paths, and required audit evidence.
|
|
|
|
Acceptance:
|
|
|
|
- A human reviewer can see which OpenBao paths each environment can mutate.
|
|
- Production applier policy excludes secret value reads and broad admin paths.
|
|
- The proposal covers both workload KV read lanes and credential broker issuer
|
|
policies.
|
|
|
|
**2026-06-29:** Added `docs/openbao-approved-automation-delegation.md` and
|
|
`openbao/policies/credential-change-prod-applier.hcl`. The document defines
|
|
build/development, test/staging, and production boundaries, the allowed
|
|
production metadata mutation surface, denied secret/admin paths, and required
|
|
non-secret evidence. The production policy candidate allows only reviewed
|
|
metadata writes for workload KV read policies, credential-broker issuer
|
|
policies, approved auth-role prefixes, and self capability checks; it does not
|
|
grant secret value reads or writes.
|
|
|
|
## T02 - Implement a CCR-aware applier dry-run
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0008-T02
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "2613f40d-fbd9-44f3-a864-85ec1d54e8f7"
|
|
```
|
|
|
|
Extend the credential-change tooling so a proposed applier can validate a CCR,
|
|
check approval state, render the exact mutations, and refuse any out-of-policy
|
|
policy name, auth role, mount, path, or environment.
|
|
|
|
Acceptance:
|
|
|
|
- Dry-run succeeds for `CCR-2026-0001`.
|
|
- Dry-run refuses unapproved CCRs.
|
|
- Dry-run refuses attempts to create `root`, `platform-admin`, wildcard, or
|
|
unrelated policy names.
|
|
|
|
**2026-06-29:** Added `scripts/credential-change.py applier-dry-run <CCR>` and
|
|
Make target `credential-change-applier-dry-run`. The dry-run validates the CCR,
|
|
requires approved/applied/verified/active status, requires confirmed auth
|
|
bindings, verifies the OpenBao mount/path/policy/role stay inside the delegated
|
|
metadata surface, compares the policy artifact to the generated CCR policy body,
|
|
and renders only policy/auth-role mutations. It explicitly leaves secret value
|
|
writes, secret reads, and front-door activation out of scope. Unit tests cover
|
|
the active whynot-design CCR success path, unapproved CCR refusal, and rejection
|
|
of `platform-admin`/out-of-scope mount and path attempts. `make
|
|
credential-tests` passed with 28 tests.
|
|
|
|
## T03 - Add non-production applier role first
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0008-T03
|
|
status: progress
|
|
priority: medium
|
|
state_hub_task_id: "ff927a19-50fb-4351-8db1-c60a0cce0995"
|
|
```
|
|
|
|
Create a build/test applier identity and prove it can apply approved metadata in
|
|
a non-production lane without gaining unrelated OpenBao permissions.
|
|
|
|
Acceptance:
|
|
|
|
- Apply succeeds in a non-production mount or namespace.
|
|
- Negative checks prove unrelated policy/auth/secret paths are denied.
|
|
- Evidence is recorded without secret values.
|
|
|
|
**2026-06-30:** Added the non-production metadata-only policy candidate
|
|
`openbao/policies/credential-change-nonprod-applier.hcl` and documented that
|
|
generated test-secret paths require separate CCR-backed approval. Live non-prod
|
|
identity creation and positive/negative OpenBao evidence remain to close this
|
|
task.
|
|
|
|
**2026-06-30:** Added the guarded `applier-apply` execution path that reuses the
|
|
CCR dry-run guardrails, requires exact `DELEGATED APPLY <CCR-ID>` confirmation,
|
|
uses the local `bao` CLI with ambient delegated applier authority, writes only
|
|
policy/auth-role metadata, and records non-secret `delegated_metadata_apply`
|
|
evidence. Non-production task closure still needs a live build/test applier
|
|
identity plus positive and negative capability evidence.
|
|
|
|
**2026-06-30:** Added `scripts/openbao-apply-credential-change-appliers.py` and
|
|
Make target `openbao-credential-change-appliers-dry-run` to install/dry-run the
|
|
non-production applier policy plus bounded `auth/token/roles/credential-change-
|
|
nonprod-applier` role. The token role allows only the matching applier policy,
|
|
disallows `root` and `platform-admin`, disables the default policy, and does not
|
|
issue tokens by itself. Live non-production apply and denial evidence remains
|
|
the closeout gate.
|
|
|
|
## T04 - Add production metadata applier with human approval gate
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0008-T04
|
|
status: progress
|
|
priority: high
|
|
state_hub_task_id: "414abd65-22d3-420f-994d-f7fdd1302db5"
|
|
```
|
|
|
|
Create the production metadata applier path and require a resolved CCR/State Hub
|
|
approval before mutation.
|
|
|
|
Acceptance:
|
|
|
|
- Approved `CCR-2026-0001` metadata can be applied without `platform-admin`.
|
|
- Unapproved CCRs fail closed.
|
|
- Secret value provisioning is still not automated in production.
|
|
|
|
**2026-06-30:** Strengthened the production gate by adding source-artifact
|
|
checks to the CCR applier dry-run and documenting that unapproved CCRs fail
|
|
closed before OpenBao mutation rendering. The production policy candidate exists
|
|
and remains metadata-only; live delegated identity creation/application evidence
|
|
still needs an operator-held OpenBao step.
|
|
|
|
**2026-06-30:** Added `applier-apply` and Make targets
|
|
`credential-change-applier-apply-plan` / `credential-change-applier-apply`. The
|
|
command fails closed for unapproved CCRs, renders the dry-run payload before
|
|
mutation, requires exact confirmation, does not accept tokens in argv, leaves
|
|
secret values out of scope, and appends State Hub/file-backed non-secret apply
|
|
evidence when requested. Production closure still requires live execution using
|
|
the constrained applier identity rather than broad `platform-admin`.
|
|
|
|
**2026-06-30:** Added `scripts/openbao-apply-credential-change-appliers.py` and
|
|
Make targets `openbao-credential-change-appliers-dry-run` /
|
|
`openbao-configure-credential-change-appliers` to configure the production
|
|
`credential-change-prod-applier` policy and bounded token role. The role allows
|
|
only `credential-change-prod-applier`, disallows `root` and `platform-admin`,
|
|
uses service tokens, disables default policy attachment, and keeps token issuance
|
|
outside the setup script. Production closure still needs a live run and
|
|
capability evidence using this constrained identity.
|
|
|
|
## T05 - Close the whynot-design pilot
|
|
|
|
```task
|
|
id: RAILIANCE-WP-0008-T05
|
|
status: wait
|
|
priority: high
|
|
state_hub_task_id: "18f34c95-4d2b-4a08-a5ad-5ab700ff9dfe"
|
|
```
|
|
|
|
Use the delegated production metadata applier to finish the whynot-design npm
|
|
publish token lane after the actual token is provisioned through approved
|
|
custody.
|
|
|
|
Acceptance:
|
|
|
|
- Policy and auth role are applied by the delegated applier.
|
|
- `NPM_AUTH_TOKEN` is provisioned through approved custody.
|
|
- Positive and negative verification pass without printing the token.
|
|
- `CCR-2026-0001` can move to `active`.
|
|
- ops-warden can mark `whynot-design-npm-publish` ready/resolvable.
|
|
|
|
## Exit Criteria
|
|
|
|
- Routine approved OpenBao metadata changes no longer require broad
|
|
`platform-admin`.
|
|
- Production automation cannot read or exfiltrate managed secret values.
|
|
- Build, test, and production each have distinct, documented security
|
|
requirements.
|
|
- CCR approval, apply, verification, and front-door activation form one
|
|
reviewable chain.
|