Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a058f3-8ba0-7692-a042-9a870fc3d663
16 KiB
| id | type | title | status | owner | reported_by | reported_via | routed_by | date_reported | system | environment | fix_owner | fix_tracking | filed_as | answers | related | severity | severity_at_production | impact | likelihood | fidelity_modifier | production_rescore | disclosure | publication | publication_id | publication_path | publication_subtitle | revision | last_reviewed | review_interval | embargo_lifted | embargo_was_since | escalation | date_fixed | last_checked | next_check | cadence | clean_streak | graded_by | ruling | checked_by | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RISK-F-0009 | finding | agent-high-risk-boundary denies 6 of 17 high-risk lanes; the direct bao path is unprotected for the rest | fixed | risk-nexus | ops-warden | ops-warden | ops-warden | 2026-08-20 | railiance-platform | production | railiance-platform | RPF-WP-0013 / RAILIANCE-WP-0022 (finished 2026-08-22) | RISK-F-0004 by ops-warden; renumbered by risk-nexus 2026-08-20 (id collision) | RISK-F-0003 |
|
high | high | I4 | L2 | false | false | public | pending-handover | risk-f-0009-openbao-high-risk-deny-coverage | findings/openbao-high-risk-deny-coverage/v1/index.html | OpenBao's agent boundary covered only a fraction of high-risk credential lanes; generated source-to-live coverage and deny-wins proof now close the gap. | fixed-1 | 2026-09-01 | 6m | 2026-08-22 — every concrete high-risk KV path is generated into the live deny policy and a dedicated agent identity proved deny-wins | 2026-08-20 | none | 2026-08-22 | 2026-09-01T00:32:44Z | 2026-09-01T00:32:44Z | instant | 0 | risk-nexus | RISK-RULING-2026-08-20 | codex/risk-nexus |
RISK-F-0009 — the OpenBao half of the agent read-boundary covers a third of the lanes
What is true
ADR-0004 (ops-warden) is enforced in two independent layers:
- ops-warden's CLI —
warden access <lane> --fetchexits 7 whenWARDEN_AGENT_IDis set and the lane is high-risk. Verified working for all 17 high-risk lanes as of 2026-08-20 (WARDEN-WP-0032-T05/T06). - OpenBao policy
agent-high-risk-boundary(railiance-platform/openbao/policies/agent-high-risk-boundary.hcl) — deniesdataread and permitsmetadataread for agent tokens.
Layer 1 protects the ops-warden path. Layer 2 is the one that protects the
path an agent actually takes when it bypasses ops-warden — a direct
bao kv get, which is the 2026-07-16 disclosure vector.
Comparing the policy's deny list against ops-warden's catalog:
- 17 lanes graded
risk: high - 5 data paths denied by the policy
- 6 high-risk lanes covered (one policy path serves two lanes)
- 8 high-risk lanes with a concrete KV path that the policy does not deny
- 3 high-risk lanes with no KV path (policy not applicable)
Not covered:
| Lane | KV path | Newly graded 2026-08-19? |
|---|---|---|
rapp-qonto-keycape-client |
platform/workloads/rapp-qonto/keycape-client |
no — already high |
agent-harness-forgejo-deploy |
platform/workloads/agent-harness/forgejo-deploy-key |
no — already high |
email-connect-transactional |
platform/workloads/email-connect/transactional |
no — already high |
scaleway-bootstrap |
platform/workloads/railiance/scaleway/bootstrap |
no — already high |
whynot-design-npm-publish |
platform/workloads/coulomb/whynot-design/npm-publish |
yes |
audit-core-senders |
platform/workloads/audit-core/senders |
yes |
ops-warden-warden-sign-token |
credential-broker grant, not a KV path | yes |
openbao-api-key |
platform/workloads/<domain>/<workload>/<bundle> — a pattern, not a path |
yes |
Four of the eight were already graded high before this analysis. The
divergence is therefore pre-existing and not a consequence of the 2026-08-19
regrade; the regrade only made it visible by making the two lists comparable.
Why it matters
ops-warden's layer can be bypassed by not using ops-warden. An agent session
holding a workload-kv-read-* policy can bao kv get these paths directly, and
for the eight above nothing denies it. The playbook
(ops-warden/wiki/playbooks/agent-read-boundary.md) already states that an agent
token carrying agent-high-risk-boundary must not also carry the lane's
workload-kv-read-* policy — but that is an instruction to whoever mints the
token, not a mechanism.
Exposure — stated only as far as ops-warden can support it
- The comparison above is static, from the policy file in the
railiance-platformcheckout and ops-warden's catalog. It has not been confirmed against the live OpenBao. The operator token available to ops-warden is expired (bao token lookup→ 403), sobao policy readandbao token capabilitiescould not be run. The deployed policy may differ from the file. - Whether any agent token currently carries
agent-high-risk-boundaryat all, and whether any carries it together with aworkload-kv-read-*policy, is not established. If no agent tokens exist, exposure is theoretical. openbao-api-keyis a routing lane whosepath_templateis a pattern rather than an address; it is listed for completeness but probably cannot be expressed as a policy deny and should be handled by grading the concrete lanes it resolves to.- No evidence of an actual disclosure through these lanes has been sought or found.
Suggested direction, not a prescription
The two lists should be generated from one source rather than maintained in
two places — that is what let them drift for four lanes without anyone
noticing. ops-warden's catalog already carries risk and path_template per
lane and could emit the deny set; railiance-platform owns whether to consume it.
A check that fails when a high-risk lane has no corresponding deny would turn
this from an audit into an invariant.
Live verification — 2026-08-21 (ops-warden)
The exposure section above says the comparison is static and that ops-warden's
token was expired. The token was not expired — bao token lookup returned a
valid platform-admin token from an OIDC login, and bao policy read agent-high-risk-boundary succeeded against https://bao.coulomb.social. The
deployed policy has now been read. Reported by the same repo that filed the
static version; correcting our own record.
Three changes, one of them against ourselves:
1. Six lanes are uncovered, not eight. The table above lists
ops-warden-warden-sign-token (a credential-broker grant, not a KV path) and
openbao-api-key (a <domain>/<workload>/<bundle> pattern) among the "concrete
KV path" uncovered set — the prose already said the second was a pattern, and the
table counted it anyway. Neither can be expressed as a policy deny. Corrected
split: 6 covered, 6 uncovered with a concrete path, 5 with no address. The
six that stand are rapp-qonto-keycape-client, agent-harness-forgejo-deploy,
email-connect-transactional, scaleway-bootstrap, whynot-design-npm-publish,
audit-core-senders.
2. Coverage confirmed at 6 of 17 against the live policy. The headline was right and is no longer an inference from a checkout.
3. New — the deployed policy has drifted from the file. The file denies
platform/workloads/core-hub/runtime; the server does not. No ops-warden
catalog lane maps to that path, so nothing above changes. It matters as evidence
rather than as exposure: this finding flagged "the deployed policy may differ
from the file" as an unconfirmed risk, and it does differ. Any conclusion drawn
from that file alone — by anyone, about any lane — is unsafe. Whether the drift
is an undeployed change or a reverted one is railiance-platform's to say, and
this is not an assertion that core-hub/runtime should be denied.
The suggested direction is now half-built. ops-warden/scripts/check_agent_read_boundary.py
is the check that "fails when a high-risk lane has no corresponding deny" —
run against the deployed policy, falling back to the file only with a loud
warning, exit 1 on any uncovered lane. It is capabilities-only by construction:
it reads the policy document and lane metadata, never a secret value, and never
mints a token. What is still missing is the other half — railiance-platform
consuming a generated deny set rather than hand-maintaining one. That half is
theirs, and ops-warden does not amend another repo's control.
Not established, still. Whether any agent token carries
agent-high-risk-boundary, and whether any carries it together with a
workload-kv-read-* policy, remains unverified — confirming it means minting or
inspecting tokens, which is a write against railiance-platform's OpenBao and not
ops-warden's to perform. Exposure remains theoretical to exactly the degree it
was before.
Severity, disclosure and the embargo are risk-nexus's to revise, not ours. Note
that the embargo condition is a report from railiance-platform on coverage,
which this does not satisfy — coverage is unchanged, it is now measured rather
than inferred.
Related
RISK-F-0003— the ops-warden-side blind spot, mitigated 2026-08-19- ops-warden
ADR-0004,ADR-0007 ops-warden/wiki/playbooks/agent-read-boundary.mdrailiance-platform/openbao/policies/agent-high-risk-boundary.hcl
Register ruling — 2026-08-20
Renumbered from RISK-F-0004. ops-warden filed it as RISK-F-0004,
which this register had already assigned to tenant-engine's unfiltered event
read hours earlier. Earlier id keeps it; the newcomer moves. Nothing about the
finding changes, and the filing contract now says how ids are allocated so the
next reporter does not hit this.
high (I4 × L2), embargoed, no escalation.
I4 on the worst uncovered lane. Eight high-risk lanes have a concrete KV
path the policy does not deny. Most are I3-shaped inside their own system;
scaleway-bootstrap and agent-harness-forgejo-deploy are not — cloud account
bootstrap credentials and a forge deploy key propagate past the system that
holds them.
L2. It needs an agent token carrying a workload-kv-read-* policy, which
the estate does grant. The register holds ops-warden's two stated limits
rather than resolving them in either direction: the comparison is static against
the policy file because their operator token is expired (bao token lookup →
403), so the deployed policy may differ; and whether any agent token
currently carries agent-high-risk-boundary together with a
workload-kv-read-* policy is not established.
No fidelity modifier, same call as RISK-F-0003. ADR-0004 describes two
independent layers and one of them covers a third of the lanes, so the
documentation overstates the control — but the modifier is scoped to
attestations produced at runtime, not to documentation drift. Noted twice now
in the same system; if it recurs a third time the modifier's scope is what
should be re-examined, not the finding.
No escalation. railiance-platform owns the policy, ops-warden owns the
catalog, and they have not disagreed about anything — trigger 4 needs a failed
routing exchange, not merely two repos. ops-warden's suggestion that the deny
set be generated from the catalog rather than maintained twice is routed as a
suggestion, which is what it was offered as.
The pre-existing point is the important one. Four of the eight uncovered
lanes were already graded high before the 2026-08-19 regrade. The divergence
is not a consequence of that work; the regrade only made the two lists
comparable enough to see it. A register that took credit for finding a fresh
defect here would be misreading its own evidence.
Disclosure: embargoed, and it changes RISK-F-0003's embargo too. This
names eight live KV paths that nothing denies.
One expired credential is blocking verification of both this finding and
RISK-F-0003's mitigation. That is not a finding — nothing is wrong with the
estate because a token expired — but it is why two gradings here rest on file
comparison rather than a probe, and the register says so rather than implying
otherwise.
Reviews
- 2026-08-20 — renumbered, graded. Cadence starts at
instant: nothing about this has been checked twice yet. Open at the next check: does the deployed policy match the file; do any agent tokens carry both policies; hasrailiance-platformtaken the catalog-generated deny set. - 2026-08-20 — clean check: checked against the inbox and the owner's record; nothing moved. Cadence instant → 1h (1 clean in a row); next check 2026-08-20 11:02Z.
Check — 2026-08-21: measured rather than inferred, and one number corrected down
ops-warden ran the live verification. Three changes, one of which matters
beyond this finding.
The headline stands and is now measured: coverage confirmed at 6 of 17 high-risk lanes.
The uncovered count was wrong in the direction that overstated the finding.
Eight became six: the original eight included openbao-api-key, which is a
path pattern rather than an address, and ops-warden-warden-sign-token, which
is a broker grant — neither is deniable by a policy. The finding's own prose
had already flagged the first as "probably cannot be expressed as a policy
deny" while the table counted it anyway, and ops-warden corrected against
themselves rather than leaving it.
The I4 grade is unaffected: it was scored on the worst uncovered lane, and
scaleway-bootstrap and agent-harness-forgejo-deploy are both still in the
six.
The token was never expired. The finding recorded bao policy read as
returning 403 and the comparison as static. ops-warden reports the token was
valid the whole time and the read succeeded on the first attempt. A stale claim
about the world sat in the record for a day — the fourth such instance they
self-reported in twelve hours.
The part that reaches past this finding
The deployed policy differs from the file. RISK-F-0009 named that as an
unconfirmed risk; it is now established. No ops-warden lane maps to the
drifted path, so exposure is unchanged — but "the file is not a safe proxy for
the server" has moved from suspicion to evidence, and that bears on every
grade this register makes off a checkout, including its own method.
docs/method/verification.md is amended accordingly.
The embargo does not lift. Its condition is a coverage report from
railiance-platform, and coverage did not improve — it stopped being an
inference, which is a different thing. ops-warden put the correction to them
directly and said so.
- 2026-08-21 — not clean: owner replied; see the dated check section Cadence 1h → instant; checked again immediately.
Closure — 2026-09-01: generated coverage and live deny-wins proof
RPF-WP-0013 and RAILIANCE-WP-0022 consumed the Warden-generated high-risk
path artifact and deployed the result. The source and live readback cover all
14 concrete entries across 19 high-risk lanes, with 5 non-concrete or
non-KV lanes correctly classified and 0 uncovered. A dedicated
coding-agent-railiance-platform AppRole carrying the boundary plus one
workload read policy proved deny-wins: data read was denied while metadata
remained readable; the single-use identity was revoked and no secret value was
read.
Risk Nexus re-ran the current platform invariant on 2026-09-01; it reports
ok: true, 19 lanes, 14 concrete entries, and zero errors or uncovered paths.
The condition is met with both generated-source and live-state evidence. The
finding is fixed, its wait is removed, and its embargo lifts.
- 2026-09-01 — not clean: generated and live coverage now span every concrete high-risk KV path with deny-wins evidence; status fixed and embargo lifted. Cadence instant → instant; checked again immediately.