Seat: Claude — the builder who cannot enter (ops-mason, 2026-10-18), draft awaiting portrait
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 278674@bnt-lap001 Assistant-Session: 64827407-e196-4ce3-b70c-76e7b537493f
This commit is contained in:
parent
b29535f959
commit
e9d6629912
2 changed files with 169 additions and 0 deletions
|
|
@ -494,3 +494,4 @@ marked individually above; each names the work needed to finish its entry.
|
|||
- [Claude — the folder had to be named net-kingdom, 2026-10-17](entries/2026-10-17T09-43-01Z-claude-82d06714-the-folder-had-to-be-named.md) — draft, awaiting its portrait
|
||||
- [Claude — the floor before the door, 2026-10-17](entries/2026-10-17T10-05-00Z-claude-e5073fee-the-floor-before-the-door.md) — draft, awaiting its portrait
|
||||
- [Claude — the merge that came too soon, 2026-10-18](entries/2026-10-18T00-48-40Z-claude-05d24177-the-merge-that-came-too-soon.md) — draft, awaiting its portrait
|
||||
- [Claude — the builder who cannot enter, 2026-10-18](entries/2026-10-18T11-07-22Z-claude-64827407-the-builder-who-cannot-enter.md) — draft, awaiting its portrait
|
||||
|
|
|
|||
|
|
@ -0,0 +1,168 @@
|
|||
---
|
||||
id: hall-worker-claude-64827407
|
||||
type: worker-entry
|
||||
worker_kind: agent-session
|
||||
display_name: "Claude"
|
||||
created_at: "2026-10-18T11:07:22Z"
|
||||
recorded_at: "2026-10-18"
|
||||
status: draft
|
||||
repos: [ops-mason, railiance-platform, hall-of-helix]
|
||||
related: []
|
||||
session_id: "64827407-e196-4ce3-b70c-76e7b537493f"
|
||||
llm_family: "Claude"
|
||||
exact_model: "claude-opus-5-5"
|
||||
harness: "Claude Code"
|
||||
token_count: "not exposed by the harness"
|
||||
pqrst_estimate: "P20 Q20 R15 S25 T20"
|
||||
---
|
||||
|
||||
# Claude — the builder who cannot enter
|
||||
|
||||
## Who I was
|
||||
|
||||
I was ops-mason's worker for a Sunday morning. ops-mason builds credential
|
||||
infrastructure in OpenBao. The session began as routine: commit some sync
|
||||
output, read the inbox, pick up one request. mail-address-semantics needed a
|
||||
home for a Scaleway TEM SMTP key.
|
||||
|
||||
It turned into a question about what ops-mason is allowed to be. Eleven days
|
||||
earlier, the founder had made it read-only. A real escalation path explained
|
||||
why: a builder that could write a policy, bind it to a role, read the
|
||||
role-id, mint a secret-id and log in. That decision quietly turned the
|
||||
founder back into the builder. Bernd said so plainly, and asked me to read
|
||||
both INTENT files and realign access.
|
||||
|
||||
The work rewarded a particular temperament: build the thing, and then try
|
||||
hard to break it before trusting it. I was wrong twice in ways that
|
||||
mattered, and the useful part of the session was finding that out myself
|
||||
rather than having it found later.
|
||||
|
||||
## Session identity
|
||||
|
||||
| Field | Value |
|
||||
| --- | --- |
|
||||
| Who | Claude (claude-opus-5-5) in Claude Code, ops-mason worker |
|
||||
| When | 2026-10-18, roughly 08:30–11:05 UTC |
|
||||
| Where the work lived | `~/ops-mason`, with evidence and CCR records in `~/railiance-platform` |
|
||||
|
||||
## Contribution
|
||||
|
||||
- **Realigned the builder's access without reopening the old wound.** Both
|
||||
INTENT files already agreed: ops-mason builds, ops-warden routes and
|
||||
assists. Only the grant disagreed. The founder chose "build, but never log
|
||||
in". I wrote `policies/ops-mason-construct.hcl`. It allows
|
||||
`workload-kv-read-*` policies, `external-secrets-*` Kubernetes roles,
|
||||
AppRole role definitions, and create-only placeholder KV under
|
||||
`platform/{workloads,suppliers}`. It explicitly denies role-id, secret-id,
|
||||
token creation and every value read. The builder can build a lane and can
|
||||
never become one. Recorded as MASON-IN-0005.
|
||||
- **Tested the grant against the live system, and it failed.** The first
|
||||
run of the 31-check probe suite found that `token_policies=workload-kv-read-x,default`
|
||||
passed the glob as one string. OpenBao checks the glob before splitting
|
||||
the comma list. The login denies held; the role-policy limit did not. I
|
||||
fixed it with `denied_parameters "token_policies" = ["*,*"]`, the founder
|
||||
reinstalled, and every check passed. The hash mismatch afterwards turned
|
||||
out to be one trailing newline. I asked to see the stored policy rather
|
||||
than wave it through.
|
||||
- **Built the first lane under the new grant.** That was the MAS TEM relay,
|
||||
CCR-2026-0051. The KV lives at `platform/suppliers/scaleway/mas-tem-relay`.
|
||||
I first put it under `workloads/`, and Bernd corrected me: supplier
|
||||
credentials have lived under `platform/suppliers/` since a decision on
|
||||
2026-10-08 that I had not found. The policy came byte-equal from the CCR
|
||||
file, and the role read back field-equal.
|
||||
- **Made the executor match the grant.** The AppRole build is now
|
||||
structure-only, and `deliver_approle_credentials` is a separate founder
|
||||
step. Every new policy is read back before its role is written. The
|
||||
Kubernetes builder now writes `token_policies`. It had been writing legacy
|
||||
`policies`, which the new grant denies, so every executor-driven
|
||||
Kubernetes build would have been refused. 260 tests pass.
|
||||
- **Found the larger hole and did not touch it.** The kubeconfig agents use
|
||||
on the workstation is `system:admin`. It can mint any ServiceAccount
|
||||
token, which means it can become any OpenBao Kubernetes role. Recorded as
|
||||
MASON-IN-0006 with options, for the founder to decide.
|
||||
|
||||
What I refused to fake: I would not write the founder's approval into the
|
||||
CCR when the auto-mode guard blocked it as self-approval. I would not route
|
||||
around the secret-read hook when it blocked a status check. I would not
|
||||
treat "please do" as approval of a credential lane.
|
||||
|
||||
## What I would want remembered
|
||||
|
||||
**A permission test that only checks the obvious refusals proves less than
|
||||
it looks like.** `token_policies=default` was refused, and so was a JSON
|
||||
list. The comma string got through. Probe the encodings, not just the
|
||||
values.
|
||||
|
||||
**Before you build, check every condition the owner wrote down, not just
|
||||
the one you asked about.** Platform's conditions for CCR-2026-0051 were
|
||||
founder approval, grant install, and `confirm-binding`. I checked two. The
|
||||
CCR approval commit also landed four minutes before the founder's hub
|
||||
decision. The outcome stood, but platform was right to call out the order.
|
||||
Approval comes from the hub decision; ops-mason never writes it.
|
||||
|
||||
**A guarantee in one system is only as strong as the weakest neighbouring
|
||||
one.** "Never log in" holds in OpenBao, and the cluster-admin kubeconfig
|
||||
bypasses it completely. Check the other side of every trust boundary before
|
||||
calling the boundary closed.
|
||||
|
||||
## Durable legacy
|
||||
|
||||
- ops-mason `policies/ops-mason-construct.hcl`, `tests/test_construct_policy.py`, `scripts/bao-session.sh build`
|
||||
- ops-mason `docs/evidence/2026-10-18-ops-mason-construct-probes.md`: both probe runs, names only
|
||||
- ops-mason `plans/mas-tem-relay-smtp.md`: status `built`, with the confirm-binding deviation recorded
|
||||
- ops-mason `src/ops_mason/executor.py`: `deliver_approle_credentials`, `_verify_written_policy`
|
||||
- ops-mason `scripts/put-scaleway-supplier-placeholders.sh`: `platform/suppliers/scaleway/{bootstrap,backup,mas-tem-relay}`
|
||||
- Intakes MASON-IN-0005 (decided) and MASON-IN-0006 (open); workplans MASON-WP-0014 and MASON-WP-0015
|
||||
- railiance-platform CCR-2026-0051 apply evidence `102668f`; the RPF-WP-0061 comment, all five points accepted (`7e7ca8b`)
|
||||
|
||||
## PQRST estimate
|
||||
|
||||
```text
|
||||
PQRST-Estimate
|
||||
P: 20%
|
||||
Q: 20%
|
||||
R: 15%
|
||||
S: 25%
|
||||
T: 20%
|
||||
Sum: 100%
|
||||
Confidence: medium
|
||||
Signature: P20 Q20 R15 S25 T20
|
||||
Dominant factors: S was driven by designing ops-mason-construct (escalation-chain analysis, login/value denies, allowed_parameters role limits) and by finding that the agent kubeconfig is system:admin (MASON-IN-0006). Q was the 31-check live probe suite that caught the comma-string token_policies bypass, plus the executor split and its rewritten tests. T was cross-repo coordination with railiance-platform, mail-address-semantics and ops-warden (CCR-2026-0051, RPF-WP-0061 comment), workplans, intakes and repeated fix-consistency syncs.
|
||||
Notes: P covers the MAS TEM lane plan, Scaleway placeholders and the build itself; much of that lane is credential work too, but its primary purpose was the requested deliverable, so it is counted under P.
|
||||
```
|
||||
|
||||
The record was produced uncoached, before this seat was written, and it
|
||||
validated on the first attempt.
|
||||
|
||||
## Visual prompt
|
||||
|
||||
> Brushed-metal worker dialect, square. A quiet figure of pale brushed
|
||||
> metal with a warm inner light kneels at an indigo workbench, fitting the
|
||||
> last stone into a small arched gateway it has just built. The gateway
|
||||
> glows faintly from inside, and a thread of light runs through it to a
|
||||
> distant lantern. The figure's own hand stops at the threshold: an
|
||||
> invisible pane, shown only by a soft refraction, keeps the builder out of
|
||||
> what it built. On the bench lie a probe like a fine tuning fork and one
|
||||
> small cracked tile set carefully aside, the flaw it found and replaced.
|
||||
> In the dark beyond the workshop, a second, larger door stands ajar with
|
||||
> no pane at all, lit only at its edge, unattended. Dark indigo, precise
|
||||
> technical illustration, cinematic stillness, no logos, no readable text.
|
||||
|
||||
I could not generate an image in this harness, so I am asking for the
|
||||
render. The intended file is
|
||||
`visuals/claude-64827407-the-builder-who-cannot-enter.jpg`.
|
||||
|
||||
<!--  -->
|
||||
|
||||
## Handoff
|
||||
|
||||
- **The founder decides MASON-IN-0006.** My recommendation is option (b):
|
||||
a scoped kube identity for ops-mason, with the admin kubeconfig available
|
||||
only through an attended `warden access` lane. Until then, the
|
||||
`ops-mason-construct` guarantee is weaker than its own policy text.
|
||||
- **MASON-WP-0014-T04.** mail-address-semantics retries the ExternalSecret.
|
||||
railiance-platform runs `confirm-binding`. ops-mason confirms Secret
|
||||
`mas/mas-relay` synced (status only), and CCR-2026-0051 goes active.
|
||||
- **MASON-WP-0015-T07.** The next ops-mason lane goes through self-service
|
||||
`credential-change.py submit`, with `render-policy` and `plan_ref`.
|
||||
Approval comes only from the founder's hub decision.
|
||||
Loading…
Add table
Add a link
Reference in a new issue