# Fluid-telegram attended operator KV lane Status: proposed, not provisioned. Owner: railiance-platform, RPF-WP-0033. Demand: State Hub message `170b9127-f18f-4045-8f64-5c211a3aa187`. Construction reference: `../ops-mason/plans/fluid-telegram-operator-credential-lane.md`. Consumer source: `../fluid-telegram/internal/secrets/secrets.go`, `session.go` and `internal/apply/apply.go`. ## Proposed coordinates Use KV-v2 mount `platform`, proposed campaign prefix `workloads/coulomb/fluid-telegram/hall-of-helix`. The organisation/tenant precedent is CCR-2026-0001, not the consumer's State Hub domain `infotech`. This is the platform design recommendation; tenant ownership is still an explicit activation gate. Set `FLUID_BAO_PREFIX` to the mount-relative prefix, without `platform/` or `data/`. The current client defaults to `infotech` and its comment claims owner confirmation that the construction plan does not contain; the client/docs must be corrected once the tenant decision is accepted. Propose policy `workload-kv-fluid-telegram-hall-of-helix-operator` and OIDC role `fluid-telegram-hall-of-helix-workload-kv` under `auth/netkingdom`. Bind the actual owner-confirmed `groups` claim. `fluid-telegram-operators` is only a candidate name; it must not become a live binding without KeyCape/NetKingdom evidence and membership approval. Require an attended human identity and the owner's MFA requirement; group membership alone is not proof of MFA. Token TTL `15m`, maximum and explicit maximum `30m`, no default policy, no periodic token. Do not choose a finite use count without measuring the session writer; propose `token_num_uses=0` within that short lifetime to avoid interrupting MTProto session persistence. Self-revoke at completion with an explicit `auth/token/revoke-self` update grant. OIDC scopes are `openid,profile,email,groups`, user claim `sub`, groups claim `groups`. Approve exact private/operator callback URIs with the provider; reuse verified localhost/127.0.0.1 CLI callbacks. Do not add a public Bao UI callback merely because old CCRs contain it while RPF-WP-0025 retracts that listener. ## Exact data scope Let `P = platform/data/workloads/coulomb/fluid-telegram/hall-of-helix`. Each row is a literal path; there is no wildcard or parent listing. | Path | Fields used by current client | Capabilities | | --- | --- | --- | | `P/operator-app` | `api_id`, `api_hash` | read | | `P/operator-session` | `session_b64` | create, read, update | | `P/bot-token` | `token` | create, read, update | | `P/redaction-salt` | `salt` | create, read | No metadata access, patch, delete, undelete, destroy, list or sudo is granted. The KV ACL governs an entry, not individual fields: the builder must not mix unrelated material into these entries. Operator-app is seeded through an independent approved attended write path. The provisioner owns session/token writes. The future adapter receives its own read-only bot-token/salt lane and never the session or operator-app credential. Add exact coding-agent boundary denies on all four data and metadata paths before activation, and test the effective union of identity policies. The provisioner currently accepts ambient tokens and `~/.vault-token`; its attended wrapper must explicitly select the bounded role and avoid silently using an old broader operator token. Cleanup must not delete an unrelated token sink. ## Required tooling change Propose a new CCR request type `workload-kv-operator-matrix`, not a reinterpretation of `workload-kv-read`. Its schema must require confirmed tenant, campaign, group claim, per-entry exact path/fields/capabilities, issuer/MFA evidence, reviewers, callback list, token bounds, boundary deny targets and lifecycle. Its validator must enforce this approved matrix, reject wildcard/parent paths, unknown capabilities, duplicate/escaping paths and unconfirmed bindings. The renderer/applier must reject this type until implemented; existing read-only CCR validation must continue unchanged. ops-mason also needs an OIDC role writer and per-path policy renderer with a reviewable mutation plan and exact scope. No direct policy/role write bypass is authorized by this design. `CreateIfAbsent` currently does GET then ordinary POST. Require the salt write to use KV-v2 `options.cas=0`; concurrent losers reread the winning salt and must not overwrite it. Test this against the installed engine with a disposable probe entry under separately approved probe scope, never by granting wildcard access to production. OpenBao documents distinct create/update ACLs and CAS zero semantics in its [KV-v2 guide](https://openbao.org/docs/secrets/kv/kv-v2/). Do not try to enforce field names or CAS using KV-v2 ACL parameter restrictions; the guide says those parameter filters are unsupported. ## Approval, verification and lifecycle Platform and consumer accept tenant/path; IAM owner confirms group and MFA; ops-mason/platform review matching CCR and executor changes; an attended operator approves exact objects and value-entry window after a live survey. Activation requires positive matrix checks, wrong-group and agent denial, sibling campaign/workload denial, salt first-write success/second-write denial, concurrent CAS behavior, and safe error/cleanup tests. Replace preflight output that currently prints an `api_id` prefix with a boolean presence result. Session compromise requires Telegram-side session revocation, not just Bao token revocation. Bot-token rotation requires provider replacement and consumer verification. Salt rotation changes longitudinal pseudonyms and requires an explicit data-owner decision; never rotate it as routine teardown. Disabling the role stops new sessions but existing tokens need revocation or TTL expiry. Keep KV versions in custody pending retention decisions; rollback disables the role/policy without deleting values. Publish the routing pointer only after all verification and owner receipts are complete.