ops-mason/intakes/intakes.md
tegwick e7a368af0f MASON-IN-0005: restore ops-mason as the OpenBao builder (ops-mason-construct)
Founder decision 2026-10-18, "build, but never log in": a plan-scoped grant
that writes workload-kv-read-* policies, external-secrets-* and AppRole role
definitions, and create-only placeholder KV under platform/{workloads,suppliers},
and denies role-id, secret-id, token creation and all value reads, so the
MASON-IN-0004 chain stays broken. Adds bao-session.sh build, policy tests,
INTENT/AGENTS alignment and MASON-WP-0015. Not installed.

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 11:48:27 +02:00

12 KiB

Intake records

MASON-IN-0001 — Grandfather the legacy MASON-0001 identifier scheme

id: MASON-IN-0001
kind: intake
title: Grandfather the legacy MASON-0001 identifier scheme
lane: green
status: closed
outcome: absorbed
origin: residual
origin_ref: MASON-WP-0002
priority: low
owner: ops-mason
description: The finished bootstrap workplan uses legacy MASON-0001 and noncanonical
  MASON-0001-Txx identifiers, including a duplicate T01. Fleet canon says existing
  identifiers are never renamed and legacy schemes must be grandfathered. Coordinate
  with the Custodian canon steward and Repo Manager to add the exact legacy scheme
  mapping, then verify statehub consistency without rewriting registered UUIDs or
  historical source identity.
notes: Custodian decision 3c487545-ee40-4049-89fa-34b41747a7eb grandfathered
  the exact MASON-0001 workplan and MASON-0001-TNN task schemes. Registered UUIDs
  remain unchanged, and the duplicate MASON-0001-T01 source blocks are indexed as
  one logical task while retaining both source locations as diagnostic provenance.
  Absorbed by that decision and the CUST-WP-0063 canon/validator update.
created: '2026-08-22T09:33:08.629717Z'
updated: '2026-08-22T21:19:02Z'
state_hub_intake_id: "01a028d1-c4af-7a06-adb5-c90399721872"

MASON-IN-0002 — Declaration requested: state this repository's layer in INTENT.md (security layer model §11)

id: MASON-IN-0002
kind: intake
title: 'Declaration requested: state this repository''s layer in INTENT.md (security
  layer model §11)'
status: closed
outcome: absorbed
origin: cross-repo
origin_ref: net-kingdom security-layer-model_v0.4 §11
priority: low
owner: ops-mason
requested_by: gate-house
proposed_layer: Staff
description: 'A conformance sweep on 2026-08-28 found this repository has no layer
  declaration of its own. It carries a layering review note gate-house wrote into
  the top of its INTENT.md on 2026-08-24, and that note names a layer — but the words
  are gate-house''s, sitting above a line admitting the body is unadapted. Section
  11 has since been amended to say so explicitly: a layer stated about a repository
  by another repository is not a declaration; only the repository''s own file, in
  its own voice, conforms. Seven of fifteen estate-authored repositories have declared;
  this is one of the eight that have not. REQUESTED: state the layer in INTENT.md
  in your own voice, or contest it. PROPOSED LAYER: Staff. Builds and tears down access
  routes, credentials, and perimeters. Two things to state in your words: the Staff
  binding rule (you act through Engine APIs, never directly against Tooling — a grep
  of your own source is the check, as ops-warden did and found one), and the demarcation
  you are half of: ops-mason and ops-warden own access lanes, access-engine owns access
  rules. Contesting is a real option and costs nothing — the three repositories that
  reviewed this model each returned a correction, two of which changed the standard.
  If the proposed layer is wrong for what this repository actually does, that is more
  useful to us than a label added to close a checkbox. Standard: net-kingdom/canon/standards/security-layer-model_v0.4.md.'
created: '2026-08-28T21:03:29.920563Z'
updated: '2026-09-28T09:54:34.065401Z'
notes: >-
  Closed against the repository-authored Staff / pep-shaped declaration in
  INTENT.md, dated 2026-09-21. That declaration names access-engine as the
  authorization decision point and explicitly records direct Tooling contacts
  and the founder-accepted plan-approval exception. The declaration request is
  fulfilled; the accepted conformance gaps and their 2026-12-21 review remain
  declared and are not marked conformant by this intake closure.
state_hub_intake_id: "01a06e68-575c-714f-b572-79bcd739c3a0"

MASON-IN-0003 — Construct the fluid-telegram adapter read lane

id: MASON-IN-0003
kind: intake
title: Construct the fluid-telegram adapter read lane
status: open
origin: cross-repo
origin_ref: FT-WP-0002-T06
priority: high
owner: ops-mason
requested_by: ops-warden
description: Design and construct a runtime identity for the fluid-telegram adapter
  after its deployment identity is declared. The lane may read only the campaign's
  bot-token and redaction-salt entries. It must be denied operator-app and
  operator-session, must not reuse the attended provisioner OIDC role, and must pass
  positive plus sibling-workload/campaign and operator-credential negative checks
  before ops-warden activation. Demand message 287cf897-7f47-4bcc-87d6-085f43d5f03e;
  parent construction workplan MASON-WP-0005.
created: '2026-09-04T21:55:00+02:00'
updated: '2026-09-04T21:55:00+02:00'
state_hub_intake_id: "01a06e68-8c29-7230-b0dc-88f1e374afa4"

2026-10-09: the parent operator plan is approved (MASON-WP-0005-T03), so this lane can be designed once the adapter's deployment identity is known. Nothing in fluid-telegram declares one yet (no manifests; FT-WP-0002-T06 delivered only internal/adaptercfg, whose LoadToken reads bot-token alone). Asked fluid-telegram (message 6d06bd9d): where the adapter runs (Kubernetes SA with ESO, or a host AppRole), whether it needs redaction-salt as well as bot-token, and per-campaign or shared.

MASON-IN-0004 — Close the policy-plus-AppRole escalation path in ops-mason-build

id: MASON-IN-0004
kind: intake
title: Close the policy-plus-AppRole escalation path in ops-mason-build
status: closed
outcome: resolved
origin: review
origin_ref: inbound-library ILIB-WP-0003 (finding raised 2026-10-05 while preparing the first grant)
priority: high
owner: ops-mason
requested_by: founder
description: >-
  policies/ops-mason-build.hcl says OpenBao, not convention, enforces "ops-mason
  never reads a secret value". The explicit denies on platform/, operators/ and
  secret/ data hold only for tokens that carry ops-mason-build. The same grant can
  also do the following:
  (1) create or update any ACL policy except its own (sys/policies/acl/*);
  (2) create or update any AppRole role and read or write anything beneath it
  (auth/approle/role/*), which includes reading role-id and minting secret-id;
  (3) do the same for Kubernetes auth roles.
  A grant holder could therefore write a policy granting read on platform/data/*,
  bind it to a new AppRole, read that role's role-id, mint a secret-id and log in.
  The resulting token does not carry ops-mason-build, so none of its denies
  apply. Kubernetes roles allow the same path for anyone holding a
  service-account JWT. This was confirmed by reading the policy text. It was
  not exercised.
  The builder legitimately needs to write policies and mint secret-ids to deliver
  AppRole lanes, as it did for inbound-library-imap-approle on 2026-10-05. A
  path-level deny on secret-id would therefore break every build. Parameter
  constraints such as allowed_parameters with token_policies=workload-kv-read-*
  narrow the role binding but not policy content, because a policy with a
  conforming name can still grant platform/data/*.
options: >-
  (a) Separation of duties: ops-mason drafts policy HCL in the plan, and the
  founder applies the policy write in an attended operator session. The grant
  loses sys/policies/acl/* create/update and keeps role binding and delivery,
  restricted by allowed_parameters to the policy names the plan approved.
  (b) Detective control: after every build, re-read the written policy and role
  and compare them to the approved build_spec (policy text derived from kv_path
  and capabilities). Alert from the OpenBao audit log on any sys/policies/acl
  write or role secret-id mint by a claude-* display_name that has no matching
  build-log record.
  (c) Two grants: a read-only survey grant (survey, metadata, capabilities), and
  a build grant minted only after plan approval and scoped by allowed_parameters
  to that plan's exact policy and role names. Bao policies cannot template on
  plan content, so this means minting a per-plan policy at grant time, itself an
  operator act.
  These can be combined, for example (b) now and (a) or (c) as the structural fix.
  This is a decision for the founder. Do not widen or loosen ops-mason-build
  while it is open.
notes: >-
  A survey needs only (c)'s read-only grant. Today MASON-WP-0008 plan-survey runs
  under the full build grant, so separating them also reduces what a survey
  session can do.
resolution: >-
  Founder decision (Bernd Worsch, 2026-10-07, given in the key-cape session):
  (c)+(a), a read-only grant only. ops-mason gets the read-only
  ops-mason-survey policy (policies/ops-mason-survey.hcl: read/list on mounts,
  auth methods, policies, auth role definitions and KV metadata; capability
  queries; lookup-self and revoke-self; explicit denies on */data/*, its own
  policy, and AppRole role-id / secret-id / secret-id-accessor /
  custom-secret-id). No policy writes, no auth-role writes, no secret-id
  minting, no token creation. Those acts go through the founder-attended
  railiance-platform delegated applier (scripts/credential-change.py
  applier-apply under warden access openbao-platform-admin-login --exec), as
  for CCR-2026-0033/0034 on 2026-10-07. ops-mason-build moved to
  policies/retired/ with a do-not-install header; it was not present in
  OpenBao at the time. bao-session.sh, plan-survey.py, custody-inventory.py,
  tests, AGENTS.md, INTENT.md and docs/construction-plan-format.md switched to
  ops-mason-survey. Installing the policy is a founder act (AGENTS.md,
  "Installing the survey policy"). Commit: 6b17727.
updated: '2026-10-07T00:00:00Z'
installed: >-
  2026-10-07 by the founder through warden access openbao-platform-admin-login.
  The stored policy's sha256 c2dc066d76b1b9f0... matches policies/ops-mason-survey.hcl
  byte for byte. Correction: the note that ops-mason-build is not installed was
  wrong. The grant script's "does not exist" message came from an expired operator
  session. MASON-WP-0009-T04 found ops-mason-build still installed and bound to no
  role. The founder deleted it on 2026-10-07 through the warden platform-admin login.
  A follow-up read shows ops-mason-build absent and ops-mason-survey present.
state_hub_intake_id: "01a11118-1f35-7ad5-ad51-65dd785c932f"

MASON-IN-0005 — Restore ops-mason as the OpenBao builder without reopening MASON-IN-0004

id: MASON-IN-0005
kind: intake
title: Restore ops-mason as the OpenBao builder without reopening MASON-IN-0004
status: open
origin: review
origin_ref: MASON-IN-0004; INTENT.md review of ops-mason and ops-warden, 2026-10-18
priority: high
owner: ops-mason
requested_by: founder
description: >-
  Founder, 2026-10-18: ops-mason exists to set up and organize secrets
  structure in OpenBao systematically; ops-warden finds and provides it. The
  read-only resolution of MASON-IN-0004 returned every build to the founder,
  which contradicts ops-mason INTENT.md (phase 4, success criterion 1: no
  founder hand-running bao) and leaves ops-warden's INTENT (route and assist,
  ops-mason the peer lane owner that builds) with nothing built to route to.
  Both INTENT bodies already agree; the grant and the INTENT frontmatter
  blocked_on text do not.
resolution: >-
  Founder decision (Bernd Worsch, 2026-10-18, this session): "Build, but
  never log in". New policy policies/ops-mason-construct.hcl: create, update and
  delete workload-kv-read-* policies; external-secrets-* Kubernetes auth roles
  and AppRole role definitions limited to workload-kv-read-* token policies;
  create-only placeholder KV data and full metadata under
  platform/{workloads,suppliers}/; explicit denies on role-id, secret-id,
  token creation, every */data/* read, and the default, root and ops-mason-* policies.
  ops-mason can build a lane but never log in as one, which breaks the
  MASON-IN-0004 chain at step three. AppRole secret-id delivery stays a
  founder act; Kubernetes auth (the current default) needs none. A post-build
  check comparing policy text with the plan file is the detective control for
  over-broad content. ops-mason-survey stays for survey-only sessions.
  Implementation and install: MASON-WP-0015.
updated: '2026-10-18T00:00:00Z'