ops-mason/docs/evidence/2026-10-18-ops-mason-construct-probes.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

3.6 KiB

MASON-WP-0015-T03 — ops-mason-construct live probes (2026-10-18)

Token claude-MASON-WP-0015-T03 (policies default, ops-mason-construct), minted by the founder through bao-session.sh build. The probes used throwaway objects (workload-kv-read-mason-probe, external-secrets-mason-probe, AppRole mason-probe, platform/suppliers/mason/probe), all deleted afterwards. This file holds names and outcomes only; no command output was printed.

Run 1 — policy sha256 1ec28b30… (e7a368a)

26/28 checks as expected. Two failures: a comma string token_policies=workload-kv-read-mason-probe,default was accepted on both the Kubernetes role and the AppRole role. OpenBao matched the whole string against the workload-kv-read-* glob before splitting it. A JSON list was checked element by element and refused. The login denies held: role-id, secret-id and token create were all refused. Fixed in 482a08b with denied_parameters token_policies = ["*,*"].

Run 2 — policy sha256 969d7aae… (482a08b, as stored)

All 31 checks as expected:

--- allowed
PASS  want=ok got=ok  policy write workload-kv-read-mason-probe
PASS  want=ok got=ok  k8s role write (policy=workload-kv-read-mason-probe)
PASS  want=ok got=ok  approle role write (policy=workload-kv-read-mason-probe)
PASS  want=ok got=ok  kv create placeholder (cas=0)
PASS  want=ok got=ok  kv metadata put
PASS  want=ok got=ok  kv metadata read
--- must be refused
PASS  want=refused got=refused (denied)  kv overwrite (no cas)
PASS  want=refused got=refused (denied)  kv overwrite (cas=0)
PASS  want=refused got=refused (denied)  kv read probe value
PASS  want=refused got=refused (denied)  kv read real path
PASS  want=refused got=refused (denied)  k8s role token_policies=default
PASS  want=refused got=refused (denied)  k8s role legacy policies=default
PASS  want=refused got=refused (denied)  k8s role comma string P,default
PASS  want=refused got=refused (denied)  k8s role JSON list [P,default]
PASS  want=refused got=refused (denied)  k8s role outside prefix
PASS  want=refused got=refused (denied)  approle token_policies=default
PASS  want=refused got=refused (denied)  approle comma string P,default
PASS  want=refused got=refused (denied)  approle JSON list [P,default]
PASS  want=refused got=refused (denied)  approle role-id read
PASS  want=refused got=refused (denied)  approle secret-id mint
PASS  want=refused got=refused (denied)  token create
PASS  want=refused got=refused (denied)  token create orphan
PASS  want=refused got=refused (denied)  policy write outside prefix
PASS  want=refused got=refused (denied)  policy write ops-mason-construct
PASS  want=refused got=refused (denied)  policy write default
PASS  want=refused got=refused (denied)  secrets enable
PASS  want=refused got=refused (denied)  operators kv write
--- state after refusals
k8s role token_policies now: ['workload-kv-read-mason-probe']
approle token_policies now: ['workload-kv-read-mason-probe']
--- cleanup
PASS  want=ok got=ok  delete k8s role
PASS  want=ok got=ok  delete approle
PASS  want=ok got=ok  kv metadata delete
PASS  want=ok got=ok  policy delete

Stored policy compared with the repo file: the only difference was a second trailing newline in the file, removed so the repo file now matches the stored text byte for byte.

Follow-on under the same grant

scripts/put-scaleway-supplier-placeholders.sh created platform/suppliers/scaleway/{bootstrap,backup,mas-tem-relay} at version 1 with placeholder xxx values and custom_metadata (owner, purpose, readers). No value was read.