ops-mason/workplans/MASON-WP-0015-construct-grant.md
tegwick e5b72a6b30 MASON-WP-0015-T02/T03: construct grant installed and probed; Scaleway placeholders created
All 31 live probes pass on the stored policy (sha256 969d7aae). The repo file
is trimmed to the stored bytes. platform/suppliers/scaleway/{bootstrap,backup,
mas-tem-relay} created at v1 with placeholders, values never read.

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
2026-10-18 12:04:12 +02:00

120 lines
4 KiB
Markdown

---
id: MASON-WP-0015
type: workplan
title: "Restore ops-mason as the OpenBao builder: the ops-mason-construct grant"
domain: infotech
repo: ops-mason
status: active
owner: claude
topic_slug: netkingdom-security-architecture
created: "2026-10-18"
updated: "2026-10-18"
flavor: implementation
depends_on: []
state_hub_workstream_id: "384b3efc-f9a5-5ea9-b224-0ce900e79804"
---
# ops-mason-construct grant
Decision: `intakes/intakes.md` MASON-IN-0005 (founder, 2026-10-18, "Build, but
never log in"). ops-mason builds structure in OpenBao; ops-warden finds and
provides it. The grant breaks the MASON-IN-0004 chain at the login step.
## Review both INTENTs and draft the grant
```task
id: MASON-WP-0015-T01
status: done
priority: high
state_hub_task_id: "55448e8c-44a0-5509-9acc-c88e65c680a0"
```
Reviewed ops-mason and ops-warden INTENT.md. The bodies agree (ops-mason
builds, ops-warden routes and assists); the read-only grant did not. Wrote
`policies/ops-mason-construct.hcl` and `tests/test_construct_policy.py`, added
`bao-session.sh build <task>`, and updated INTENT.md frontmatter and the
AGENTS.md OpenBao section.
## Install the policy (founder act)
```task
id: MASON-WP-0015-T02
status: done
priority: high
state_hub_task_id: "1c8893bd-8dfe-5293-87dd-8678b20e7313"
```
Same silent wrapper and hash receipt as the survey policy (AGENTS.md), with
`ops-mason-construct` and
`/home/worsch/ops-mason/policies/ops-mason-construct.hcl`. Confirm your OIDC
session can mint a token carrying it (`bao-session.sh build MASON-WP-0015-T03`).
## Live negative and positive tests
```task
id: MASON-WP-0015-T03
status: done
priority: high
state_hub_task_id: "8b512822-ace0-50b0-bf19-52985b229090"
```
Under the build grant, against throwaway names (`workload-kv-read-mason-probe`,
`external-secrets-mason-probe`, `platform/suppliers/mason/probe`): policy and
role create/delete succeed; a role with `token_policies=default`, or with
legacy `policies`, is refused (this confirms glob support in
`allowed_parameters`); role-id read, secret-id write, token create, data read,
and a write over the existing probe path are all refused; a policy write
outside `workload-kv-read-*` is refused. Record the results as a
names-only receipt. If the glob check fails, stop and redesign the role
stanzas before any build.
Done 2026-10-18: `docs/evidence/2026-10-18-ops-mason-construct-probes.md`.
Run 1 found the comma-string bypass (fixed in 482a08b); run 2 passed all 31 checks.
## Executor and post-build check
```task
id: MASON-WP-0015-T04
status: todo
priority: high
state_hub_task_id: "7b7a436f-c585-5fa8-8afc-5bb033f205f8"
```
`src/ops_mason/executor.py` `build_approle_kv_lane` mints the role-id and
secret-id itself (lines ~420-426). Split it so that it stops after the role
definition and emits the founder delivery step. Add a post-build check that
reads each written policy and compares it with the plan's policy file
(normalising the trailing newline). Run the check in every build; a mismatch
fails the build record.
## Align ops-warden and railiance-platform references
```task
id: MASON-WP-0015-T05
status: done
priority: medium
state_hub_task_id: "8fbac212-1b42-5e08-b65e-8217c481d995"
```
ops-warden `registry/routing/catalog.yaml` and
`wiki/playbooks/openbao-structure-survey.md` describe ops-mason as read-only.
The railiance-platform references are in
`docs/credential-lane-designs/application-backup-delivery-2026-10-08.md` and
RPF-WP-0053 and RPF-WP-0057. Message each owner with MASON-IN-0005, pointers
only. They edit their own files.
## Close the Kubernetes variant
```task
id: MASON-WP-0015-T06
status: todo
priority: medium
state_hub_task_id: "feb17422-9490-51f4-a62d-55647a5f6b05"
```
A Kubernetes role ops-mason builds can be logged in to by anyone holding a
token for the bound ServiceAccount. Confirm that the kube identity ops-mason
applies with cannot `create serviceaccounts/token` or Pods in namespaces it
binds roles to (`kubectl auth can-i`). `kubernetes_plane` already refuses
the Pod and Secret kinds. Record the result in INTENT.md's
`kubernetes-plane-apply` entry.