Replace ops-mason-build with read-only ops-mason-survey grant (MASON-IN-0004)

Founder decision 2026-10-07, option (c)+(a): ops-mason surveys and verifies
only. Policy/role writes, secret-id minting and token creation go through the
founder-attended railiance-platform delegated applier. ops-mason-build retired
to policies/retired/ (never installed).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 132360@bnt-lap001
Assistant-Session: 769b1afd-4330-4c86-96b2-e510e26db42b
This commit is contained in:
tegwick 2026-10-07 10:44:24 +02:00
parent 47171385ce
commit 6b177270d3
10 changed files with 261 additions and 40 deletions

View file

@ -12,10 +12,12 @@
# for as long as you have it, indistinguishable from you in the audit log. The
# grant path instead mints a separate token that is:
#
# * scoped — carries the ops-mason-build policy, which can create policies,
# auth roles and KV *structure* but cannot read secret values.
# SCOPE.md's "never touch secret values" stops being a promise in
# a document and becomes something OpenBao enforces.
# * scoped — carries the read-only ops-mason-survey policy: it can list
# and read mounts, auth methods, policies, auth role definitions
# and KV *metadata*, and query capabilities. It cannot write a
# policy or role, mint a secret-id or a token, or read a secret
# value (MASON-IN-0004, founder decision 2026-10-07). Builds go
# through the founder-attended railiance-platform applier.
# * bounded — 45 minutes, no renewal past one hour.
# * named — display_name claude-<task>, so the audit log says which task an
# action belonged to, not just that platform-root did it.
@ -30,7 +32,7 @@ set -euo pipefail
export BAO_ADDR="${BAO_ADDR:-http://127.0.0.1:18200}"
GRANT_FILE="${GRANT_FILE:-$HOME/.claude-bao-token}"
GRANT_POLICY="${GRANT_POLICY:-ops-mason-build}"
GRANT_POLICY="${GRANT_POLICY:-ops-mason-survey}"
GRANT_TTL="${GRANT_TTL:-45m}"
GRANT_MAX_TTL="${GRANT_MAX_TTL:-1h}"
OIDC_PATH="${OIDC_PATH:-netkingdom}"

View file

@ -5,7 +5,7 @@
./scripts/custody-inventory.py operators one mount or prefix
./scripts/custody-inventory.py --undescribed only paths missing metadata
Reads metadata only — never a value — so it runs under ops-mason-build and can
Reads metadata only — never a value — so it runs under ops-mason-survey and can
be handed to anyone orienting themselves without granting them a single secret.
A path with no description is a finding, not a formatting problem: it is a

View file

@ -12,7 +12,7 @@ auth-role listings, KV metadata existence for the target path, matching
ops-warden routing catalog entries, and a draft answer to "does an existing lane
already satisfy this demand?".
Metadata only. It runs under the ops-mason-build grant (~/.claude-bao-token),
Metadata only. It runs under the ops-mason-survey grant (~/.claude-bao-token),
refuses any other token, and every bao invocation passes `allowed_bao_call`, an
allowlist that rejects `kv get` and every `*/data/*` path before a process starts.
Policy bodies are read with `bao policy read` (policy text, never a secret value)
@ -33,11 +33,11 @@ from pathlib import Path
from typing import Callable
GRANT_FILE = "~/.claude-bao-token"
GRANT_POLICY = "ops-mason-build"
GRANT_POLICY = "ops-mason-survey"
DEFAULT_ADDR = "http://127.0.0.1:18200"
DEFAULT_CATALOG = "~/ops-warden/registry/routing/catalog.yaml"
MAX_POLICY_READS = 15
NOT_PERMITTED = "not permitted by ops-mason-build"
NOT_PERMITTED = "not permitted by ops-mason-survey"
# Path segments too generic to identify a consumer.
GENERIC = {"platform", "workloads", "operators", "secret", "data", "metadata",
"kv", "read", "workload", "role", "token", "auth", "policy"}
@ -133,7 +133,7 @@ def grant_env(environ: dict | None = None) -> dict:
with open(grant) as f:
env["BAO_TOKEN"] = f.read().strip()
if not env.get("BAO_TOKEN"):
raise SurveyError("no ops-mason-build grant (~/.claude-bao-token absent and BAO_TOKEN unset); "
raise SurveyError("no ops-mason-survey grant (~/.claude-bao-token absent and BAO_TOKEN unset); "
"ask the founder to run ./scripts/bao-session.sh grant <task>")
return env