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:
parent
47171385ce
commit
6b177270d3
10 changed files with 261 additions and 40 deletions
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue