From 854e8078990881e4c3711da0a1ad3b2fbceeb324 Mon Sep 17 00:00:00 2001 From: tegwick Date: Fri, 4 Sep 2026 23:11:24 +0200 Subject: [PATCH] Request a credential lane for the Telegram operator Addressed to ops-warden as the front door, and explicit that the lane itself is railiance-platform's to create -- ops-warden routes this row rather than executing it. States the two things that are easy to get wrong. The lane needs write and not only read: apply's critical write happens immediately after BotFather issues the bot token, and a denial there leaves a registered bot whose only credential is a chat message, with a re-run creating a second bot. And the redaction salt must never be rotated, so write-once on that path would be welcome if the lane tooling can express it. Leaves the segment open rather than assuming infotech: the only concrete lane we can read uses "coulomb", which looks like a tenant rather than a sector, and the segment belongs to its owner. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0172sgCZEEDJcnQmr4SGDvKa Assistant: claude-code Assistant-Model: opus Assistant-Process: 1361245@bnt-lap001 Assistant-Session: b3b428ef-f3e6-4688-b091-01f71461d66a --- .../ops-warden-telegram-operator-lane.md | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 docs/requests/ops-warden-telegram-operator-lane.md diff --git a/docs/requests/ops-warden-telegram-operator-lane.md b/docs/requests/ops-warden-telegram-operator-lane.md new file mode 100644 index 0000000..f4bd9a1 --- /dev/null +++ b/docs/requests/ops-warden-telegram-operator-lane.md @@ -0,0 +1,140 @@ +--- +to: ops-warden +from: fluid-telegram +date: "2026-09-04" +subject: "Credential lane for the Telegram operator (workplan FT-WP-0002)" +routes_to: railiance-platform (OpenBao) +--- + +# Request — credential lane for the Telegram operator + +`fluid-telegram` provisions HelixForge's Telegram presence from a declared +specification (`FT-WP-0002`, `docs/provisioning.md`). The tooling is built, +tested and ready; the only thing blocking the first run is that it has nowhere +sanctioned to keep four secrets and no role that can reach them. + +Per `wiki/AccessRouting.md` this is the "API key / DB credential" row, so +ops-warden **routes** rather than executes it. We are asking ops-warden for the +routing artifacts, and asking it to point us at railiance-platform for the lane +itself. + +## What the workload is + +A provisioning tool, run by an operator on demand. It is **not** on any request +path, and it is not the adapter — the adapter that publishes to Telegram holds +only a bot token and never sees the rest. + +It runs `plan` and `apply` against a declared spec: registering the bot through +BotFather over MTProto, creating channels, and granting the bot `post_messages` +and nothing wider. + +## The four secrets + +All under one bundle prefix, one KV entry each: + +| Bundle | Contents | Written by | Read by | +|---|---|---|---| +| `operator-app` | `api_id`, `api_hash` from my.telegram.org | operator, by hand | provisioner | +| `operator-session` | MTProto session string | provisioner (`session bootstrap`) | provisioner | +| `bot-token` | Telegram bot token | provisioner (`apply`) | provisioner, adapter | +| `redaction-salt` | 32 random bytes | provisioner, **once, never rotated** | adapter | + +Two of these deserve a note. + +**`operator-session` is a full-account credential.** It can do anything the +operator's Telegram account can do. It is held only because the Bot API cannot +create a bot or a channel — both are client capabilities reachable only through +MTProto (Canon INT-03). The account is a dedicated operator account, never a +person's own, and the session is used for provisioning only: all ordinary +publishing goes through the bot token on the supported Bot API surface. We would +grade this lane **high risk**. + +**`redaction-salt` must never be rotated.** Rotating it silently invalidates +every longitudinal comparison the interface has made, with no visible failure — +the numbers keep arriving and quietly stop meaning what they used to. The tool +has no code path that overwrites it (create-if-absent only). If your lane +tooling can enforce write-once on that one path, we would welcome it. + +## What we need + +### 1. From railiance-platform — a workload KV lane + +Following `railiance-platform/docs/workload-kv-access-lanes.md`: + +- A role, by your naming convention presumably `fluid-telegram-workload-kv` +- Policy over `platform/workloads//fluid-telegram//*` +- OIDC through `auth/netkingdom`, as the existing lanes use + +**This lane needs write, not only read.** Every documented lane we found is +`-workload-kv-read`, and read-only would fail badly here rather than merely +being inconvenient: `apply` writes three of the four paths, and the write that +matters happens *immediately after BotFather issues the bot token*. A denial at +that moment leaves a registered bot whose only surviving credential is a chat +message, and re-running creates a second bot. If a split is preferred, the +minimum is write on `operator-session`, `bot-token` and `redaction-salt`, and +read on all four. + +### 2. From ops-warden — a catalog entry + +So that `warden access 'telegram operator credentials'` resolves to something +concrete rather than the generic `openbao-api-key` template. Proposed, in the +shape of `whynot-design-npm-publish`: + +```yaml +id: fluid-telegram-operator +title: "fluid-telegram Telegram operator credentials (MTProto session, bot token, salt)" +risk: high +workload_ref: + applicability: applicable +need_keywords: [telegram, mtproto, botfather, bot, token, session, fluid-telegram, + helix-forge, hall-of-helix, provisioning] +owner_repo: railiance-platform +subsystem: OpenBao +warden_executes: false +auth_method: bao login -method=oidc -path=netkingdom role=fluid-telegram-workload-kv +path_template: platform/workloads//fluid-telegram/ +policy_ref: flex-auth check secret.read:fluid-telegram +wiki_ref: fluid-telegram/docs/seeding-runbook.md +``` + +Corrections welcome — we have modelled this on your existing entries rather than +inventing a shape. + +## One open question — the `` segment + +We had assumed `infotech`, this repository's State Hub domain. But the only +concrete lane we can read uses `platform/workloads/**coulomb**/whynot-design/…`, +where the segment looks like a tenant rather than a sector. + +We do not want to guess: the segment is yours to define, and a workload that +picks its own path in someone else's store is how a policy ends up written +around a mistake. Tell us which is correct and we will take it. + +The provisioner reads `BAO_MOUNT` and `FLUID_BAO_PREFIX`, so whatever you +confirm is configuration on our side, not a code change. + +## What is already done + +- Paths, mount and prefix are configurable; nothing is hardcoded. +- The tool reads `~/.vault-token` and `BAO_TOKEN`/`VAULT_TOKEN`; it never writes + a credential to disk or logs one, and error messages name paths, never values. +- `provision preflight` checks the whole chain without contacting Telegram, and + currently reports everything green except OpenBao access. + +## Note on a diagnosis that cost us time + +`warden access` renders `bao login -method=oidc role=` for this need. +The working form is `-path=netkingdom`, which we found in railiance-platform's +runbook. Because OpenBao answers `403 permission denied` for paths that do not +exist as well as for those you may not reach, the wrong mount is +indistinguishable from an expired token from the outside — we spent a while +renewing a token that was not the problem. + +If `auth_method` in the generic `openbao-api-key` entry carried `-path=netkingdom`, +the next person would not repeat this. Offered as an observation, not a defect +report: the entry is explicitly a template with owner-confirmed placeholders. + +## Contact + +Repository `fluid-telegram`, workplan `FT-WP-0002`, State Hub topic +`helix-forge`, domain `infotech`.