Close CCR drift and high-risk policy gaps
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

This commit is contained in:
codex 2026-08-21 01:29:28 +02:00
parent 852a8ab661
commit 382f04412a
12 changed files with 577 additions and 68 deletions

View file

@ -0,0 +1,124 @@
---
id: RAILIANCE-WP-0022
type: workplan
title: "Close agent high-risk OpenBao boundary coverage"
domain: financials
repo: railiance-platform
status: blocked
owner: codex
topic_slug: railiance
created: "2026-08-21"
updated: "2026-08-21"
related:
- WARDEN-WP-0032
- RISK-F-0009
origin: routed
origin_ref: "State Hub message 828e4903-30fe-4903-acfd-cd2ecdda437d"
---
# RAILIANCE-WP-0022 — Agent high-risk boundary coverage
## Goal
Make the OpenBao `agent-high-risk-boundary` deny every concrete high-risk KV
data path in the ops-warden routing catalog, verify the deployed policy, and
establish whether any agent identity actually carries the boundary.
## Boundaries
- Read policy documents, token-role metadata and capabilities only; never read
a Secret value.
- A deny is added only for a concrete catalog path graded `risk: high`.
- Pattern-only and non-KV lanes are reported but do not produce invented paths.
- Operator identities do not receive this boundary; it is for coding-agent
identities where deny must override any coincident workload read policy.
## T01 — Reconcile catalog coverage
```task
id: RAILIANCE-WP-0022-T01
status: done
priority: high
```
Run the capabilities-only ops-warden audit against the policy. The 2026-08-21
reconciliation found 17 high-risk lanes: six covered, six concrete uncovered,
and five without a concrete KV address. No credential value was read.
## T02 — Close the concrete deny gaps
```task
id: RAILIANCE-WP-0022-T02
status: done
priority: high
```
Add deny-data/read-metadata pairs for the six catalog paths: whynot-design npm,
rapp-qonto Keycape client, agent-harness Forgejo deploy key, audit-core senders,
email-connect transactional, and Scaleway bootstrap. Add regression coverage
for every concrete path currently emitted by the catalog audit.
Completed 2026-08-21. The source policy covers all 12 unique concrete paths
(including the Core Hub path, which has no catalog lane), and the local
catalog audit reports all 12 catalog entries covered with none uncovered.
## T03 — Apply and verify live
```task
id: RAILIANCE-WP-0022-T03
status: done
priority: high
```
Under attended platform authority, upload the reviewed policy, read it back,
and rerun the catalog audit with `policy_source: server`. Inspect policy/token
role metadata to determine whether an agent identity carries the boundary and
whether any role combines it with a workload-read policy. Do not mint a token.
Completed 2026-08-21 under attended `platform-admin` OIDC. OpenBao accepted the
policy; normalized readback matched source, and the server-backed catalog audit
reported 17 high-risk lanes, 12 covered entries, zero uncovered, and five
pattern/non-KV lanes without a concrete address. Metadata-only inspection of
all discoverable netkingdom, Kubernetes, AppRole, and token roles found zero
attachments of `agent-high-risk-boundary` and therefore zero roles combining
it with a workload-read policy. No token was minted and no Secret was read.
## T04 — Route the result
```task
id: RAILIANCE-WP-0022-T04
status: done
priority: medium
```
Reply to ops-warden with the deployment evidence and remaining attachment
finding. Request a generated, versioned concrete-deny artifact so future policy
updates consume catalog output rather than relying on a hand-maintained list.
Completed 2026-08-21 via State Hub message
`fe727451-163a-4e14-8ce3-187fea8ce5b3`, including live audit counts, the zero-
attachment finding, the distinct-agent-identity blocker, and the requested
versioned generated artifact shape.
## T05 — Establish a distinct coding-agent identity
```task
id: RAILIANCE-WP-0022-T05
status: wait
priority: high
```
The policy is live but no role attaches it. Do not add the boundary to
`platform-admin`: that is an attended human/operator role whose legitimate
recovery work may require the protected values. The identity owner must define
a distinct coding-agent issuance path, attach this boundary there, and prove
deny-wins behavior when combined with an otherwise readable workload policy.
This is blocked on an identity-owner decision and is not invented here.
## Acceptance
- [x] Every concrete high-risk catalog path is denied in the source policy.
- [x] The live policy matches source and the server-backed audit passes.
- [x] Agent boundary attachment is established from metadata (currently zero).
- [x] Result and generated-artifact follow-up are routed to ops-warden.
- [ ] A distinct coding-agent identity actually attaches the boundary.

View file

@ -4,11 +4,11 @@ type: workplan
title: "Close CCR schema drift: one active lane unmigrated, one draft the suite cannot express"
domain: financials
repo: railiance-platform
status: proposed
status: finished
owner: codex
topic_slug: railiance
created: "2026-08-18"
updated: "2026-08-18"
updated: "2026-08-21"
related:
- RPF-WP-0014
origin: residual
@ -38,22 +38,22 @@ one makes the suite green first.
## The two problems
**P1 — an active credential lane is unmigrated.**
**P1 — an active credential lane uses an unrepresented auth mode.**
`credential-change-requests/CCR-2026-0010-email-connect-transactional.yaml`
carries `status: active` and `readiness: ready`, and is missing the entire
`openbao.auth` block: `method`, `mount`, `role`, `policies`, `bound_claims`.
The validator gained those requirements and this CCR was never brought
forward.
carries `status: active` and `readiness: ready`. It has always declared the
live transitional ESO token Secret, bootstrap script, policy and TTL, but the
validator understood only OIDC and Kubernetes auth and consequently reported
the role/bound-claim fields for those modes as missing.
This is the one that matters. A live lane whose declaration does not describe
how the workload authenticates is a governance gap, not a lint failure — the
document that is supposed to be the authority on the lane cannot answer the
first question anyone would ask of it. The lane itself is presumably working,
which is exactly what makes it easy to leave.
first question anyone would ask of it. The live lane is working, which is
exactly what made this representation gap easy to leave.
**P2 — a genuine in-flight draft the suite cannot express.**
**P2 — a genuine in-flight request the suite could not express.**
`CCR-2026-0011-scaleway-object-storage-bootstrap.yaml` carries
`status: apply_pending` and `readiness: waiting-on-ui-replace-of-xxx-placeholders`.
`status: apply_pending` and an out-of-enum placeholder readiness string.
It is a founder-bootstrap credential still holding placeholder values, and
`ops-warden` already tracks it as a draft lane. Its errors include a
`readiness` value outside the permitted enum, which is the file honestly
@ -76,7 +76,7 @@ draft and a real gap produce identical output.
```task
id: RPF-WP-0020-T01
status: todo
status: done
priority: high
state_hub_task_id: "3bf8bf9c-ac33-4ce7-8b3f-5b40135b227c"
```
@ -88,9 +88,18 @@ policy file, not by inventing plausible values. If the live configuration and
the declaration disagree, the live configuration is the fact and the
disagreement is the finding.
Completed 2026-08-21. Live read-only Kubernetes metadata showed
`ClusterSecretStore/openbao-email-connect` using
`external-secrets/openbao-email-connect-eso-token`, limited to namespace
`email-connect`, and reporting Valid; its ExternalSecret reported
SecretSynced. The schema now represents this transitional token mode directly,
requires the ESO policy artifact, Secret reference, bootstrap script, bounded
TTL and explicit Kubernetes-auth follow-up, and keeps delegated token creation
out of scope. No Secret value was read.
```task
id: RPF-WP-0020-T02
status: todo
status: done
priority: medium
state_hub_task_id: "12933d69-82a3-470d-b01c-0c40c28a7984"
```
@ -100,9 +109,16 @@ a `status` the validator recognises as not-yet-complete, with the test
asserting that such files are still well-formed in every other respect. An
allowlist of filenames would work today and rot on the next draft.
Completed 2026-08-21. Added the non-applyable `in_flight` status. It requires a
named owner, blocking reason and exact `missing_fields`; only
`openbao.policy_file` and `openbao.auth` may be declared incomplete, while all
other CCR structure remains validated. CCR-2026-0011 now uses this state and a
valid non-resolvable front-door readiness without inventing policy/auth
metadata or filling credential placeholders.
```task
id: RPF-WP-0020-T03
status: todo
status: done
priority: medium
state_hub_task_id: "da52b518-c6fb-40b8-acb9-c64724ca4eee"
```
@ -111,9 +127,15 @@ requirement was added without migrating existing active CCRs, other repos
carrying CCRs may have the same gap and no failing test to reveal it. Confirm
whether the requirement originated here or upstream, and notify accordingly.
Completed 2026-08-21. Git history traces the validator requirement to local
commit `815b124`; a filesystem-wide declaration search found CCR files and the
validator/schema implementation only in `railiance-platform`. There is no
upstream CCR implementation to migrate or notify. The migration obligation is
now documented locally.
```task
id: RPF-WP-0020-T04
status: todo
status: done
priority: low
state_hub_task_id: "2259ee69-4914-42c4-9175-8c61b2206888"
```
@ -122,6 +144,12 @@ suite passes. Record in `docs/credential-change-approval.md` that a new
required field obliges a migration pass over existing active CCRs — the
omission that produced P1.
Completed 2026-08-21. Regression coverage proves the live token-auth shape,
explicit in-flight omissions, rejection of undeclared omissions, and safe
status/summary rendering. The approval guide now requires a migration pass over
all existing CCRs whenever required fields are added or strengthened. The full
repository test suite passes.
## Risks
**T01 invents values to make the test pass.** The likeliest failure and the