the switchboard · messaging gateways · designed and ratified, implementation scheduled

Put an agent in the chat, keep the governance

A support agent that lives in your company chat is the most useful agent you can deploy, and the most dangerous, because one instance answers many people. The switchboard is how the hall will let a centrally hosted agent runtime — Hermes, the harness behind our own Discord assistant, or any harness on a VM you control — serve a whole Teams, Slack or Discord workspace: every person proves who they are once, every message arrives signed by the platform, and every answer is capped by the room it will be printed in. Nothing anyone types can widen that.

status, honestly: messaging gateways are designed and ratified (RH-GATEWAY-DESIGN, 2026-08-24); the core acceptance contract and the first adapters are scheduled after 1.0. nothing on this page is clickable yet.

Blueprint illustration of a switchboard room at the hall’s entrance: an operator at a patch panel with three incoming lines labelled Teams, Slack and Discord, a badge register on the desk, a room-clearance board on the wall, a glass booth holding the agent terminal, and a narrow job-card slot into the hall.
01 the problem

One agent, many people

Today a chat agent is usually a single service identity with wide access. Every answer runs under its authority, not the asker’s, and the model is the only thing deciding who gets to see what. That is not a control.

The confused deputy

One agent instance answers many people. If it runs under its own wide authority, the only thing between “what is on Alice’s host?” asked by Bob and the answer is the model’s judgement — and every chat message is attacker-writable input.

Context contamination

Even with per-call permission checks, a model remembers what it read while answering Bob. Alice’s next question can pull it back out. Authorization on tool calls cannot scrub a context window; only a separate context can.

the room defines what may be said · the person defines what may be done · the server verifies who spoke and computes both · the model decides neither

03 the rooms · venues

The room decides what may be said

In a shared channel the answer prints into a room, and everyone who can read the thread will read it. So the question is never “may Alice see this?” — it is “may this be printed here?”. Each room — a venue, in the product’s words — is bound on the owner plane, the human-only administration surface, to a group and an access profile, the published permission set that becomes the room’s disclosure ceiling. Identity is checked first: an unlinked person gets only the linking instruction. A linked person in a room nobody has bound gets one fixed “this room is not configured” reply that names no object.

Ceilings intersect, never add

A person holding root asking in a low-cleared channel gets low-cleared answers. An elevated badge in the room never widens the room; what the person may command is their own authority, capped by the room and the gateway.

One context per room

Every room gets its own agent session with its own context, so nothing the model read at a higher clearance can leak into a lower room. A direct message is the room of one — and “one” is proven from the platform’s signed conversation data, never assumed. A group DM is a room.

One refusal, always the same

When the answer may not be printed here — the object does not exist, is outside this room, or the asker is not allowed — the reply is one fixed text, byte for byte, with one standing hint: for anything outside this room, DM me or use the board. Nobody in the room learns which of the three it was.

#ops-billing · slack · acmeroom: ops-billing group · profile: billing-readers
m.kowalska linked · ops-lead
@relay-bot disk state on bill-prod-01?
relay-bot
bill-prod-01 · /var 91 % · journald retention misconfigured since role v2.3 · related: INC-4785 (RCA on the board). Want a task for the fix? I will prepare it for you to confirm.
j.nowak linked · billing
@relay-bot and hr-db-02?
relay-bot the one fixed refusal
I can’t answer that in this room. For anything outside this room, DM me or use the board.
the hall audit
host disclosure computed by the broker: room selector ∩ person selector ∩ gateway selector ∩ its closed read-only envelope · refusal cause recorded server-side only · context for this room untouched by the refusal

if m.kowalska starts a direct message and asks the same question, it runs in a fresh context under a separate credential capped by her own badge — a private answer is never computed inside a shared room

04 the operator · gateway and on-behalf-of credential

Verified, then minted, then capped live

A gateway is a Service of a third kind, beside services and connectors: it carries people’s messages in under verified attestation. A connector works; a gateway speaks for people. That difference in trust earns it its own noun, its own registration and its own ceiling.

Verify or nothing. The gateway hands the hall the raw platform-signed event — a Slack request signature, a Discord Ed25519 interaction, a Teams token — and asserts nothing else. Core verifies it with a signature module the deployment installed, derives who spoke and in which room from the signed bytes, and refuses anything that disagrees. A platform whose events cannot be verified gets no on-behalf-of features at all: its gateway may read under its own identity, write nothing, and attribute nothing.

Then the exchange. The gateway presents its own credential plus the verified event, and the authorization server mints a short-lived on-behalf-of credential — standard token exchange, not a bespoke door. That credential stores references, never computed authority, and on every request the server computes two separate live ceilings. In a shared room, what may be disclosed is capped by the gateway and the exact credential it presented, that credential’s own scopes, the room’s current access profile and the fixed task-and-report envelope; what the person may command is that disclosure ceiling further capped by their own current authority. In a proven one-person direct message both ceilings are capped by the person as well. If any required arm is missing, the request fails closed.

Revocation revokes the memory. Narrow the room, unlink the person, disable the gateway or the Account, and the credential dies mid-thread — and the room’s agent session must start a fresh, empty context before it may say another word. A fully compromised gateway can never exceed its own configured ceiling.

on-behalf-of credential · minted 10:02:41expires 10:17 · epoch 7
gateway

slack-acme · Service kind: gateway · own ceiling: work plane

proven by

Slack request signature over event Ev07… · installation acme/A0… bound to this gateway · dedup ok

subject

m.kowalska (Account) · identity link slack:acme:U04… · active

room

#ops-billing · group ops-billing · profile billing-readers@v12 (followed live)

audience

board · scopes ⊆ tasks:read, tasks:write, reports:read, reports:write

authority

computed on every request · disclosure: gateway and source credential ∩ credential scopes ∩ room profile ∩ envelope · command: disclosure ∩ person · any required arm missing fails closed

05 the ceiling · work plane

Chat can ask, never operate

Reads and job-card writes at most: a chat-derived credential can never carry more than tasks and reports, whatever the room or the person would otherwise allow.
Infrastructure changes, credential operations and approvals are structurally unreachable from chat — no configuration can opt in. “Reboot host X” becomes a prepared task plus a deep link to the board; the link carries no authority and nothing is approved by replying.
A write is recorded as yours only when you confirmed it: the agent shows a structured summary, you confirm in a message the platform signed, and only a write matching that summary is created as you. Anything else is attributed to the gateway, with you as the source.
#ops-billing · confirmdigest-bound confirmation
Create task “Fix journald retention on bill-prod-01” in project BillCore operations — confirm?

phase: 3 · fix · references: INC-4785 RCA · addressed to: the authoring line · created as: m.kowalska (on your confirmation)

ConfirmCancel

your confirming message is itself a platform-signed event; the task is created as you only if it matches this summary exactly · “deploy it” from chat becomes a prepared act and a board link, never an action

06 the counter · disclosure-only brokers

Browse servers, answer questions, change nothing

The sysadmin case — “what is the state of that host?” — never gives the agent standing keys. A broker Service in your estate presents the on-behalf-of credential to the hall’s minimized introspection surface. When every live arm and the designated caller check out, the hall returns only an active state, a subject reference, the groups relevant to that broker, and three opaque selectors derived from the room, the person and the presenting gateway. The broker intersects those and may issue a short-lived, read-only host certificate from its closed list of operations: no shell, no write, no reboot expressible. The hall stays infrastructure-agnostic; hosts are never board objects.

Three arms, intersected

The room’s clearance, the person’s own entitlement, and the gateway’s own host-domain entitlement — a wide room never discloses past the person, a powerful person never widens a low room, and no gateway reaches hosts outside its own registration.

The general plugin contract

The same shape serves ServiceNow, secret vaults, ticketing or n8n: the hall supplies minimized identity, the groups relevant to that plugin and the three opaque selectors for room, person and gateway; the plugin applies its own domain rules. Direct-from-chat calls are disclosure only.

Mutations go through the board

Anything that changes something flows chat → task → a normally authorized agent that checks the requester’s identity and groups before acting. That is the production line from the tour, entered from a chat window.

The warehouse uses the same disclosure-only pattern for your knowledge sources

07 the seam

What the hall provides, and what you plug in

in the product · designed

The acceptance contract

the identity-link registry
room bindings and their owner-plane changes
the on-behalf-of exchange on the OAuth 2.1 authorization server
verification of platform-signed events, with the signature modules the deployment installs
the work-plane ceiling, applied last and untunable
a minimized introspection surface for brokers
yours to build and register

The adapters and the runtime

one adapter per platform — Slack, Discord, Teams — each its own repository and app registration
the agent runtime it fronts: Hermes, or any harness on a VM you control
brokers and plugins that decide access in their own domain
the platform signing keys and workspace ids, kept in deployment configuration and never in the repository
the membership watchdog that mutes a room whose readership drifted from its group

status, honestly: the design is ratified (RH-GATEWAY-DESIGN); it adds exactly one mechanism to the authority model — the on-behalf-of exchange — and no execution ever flows through a gateway: a task created from chat enters the same pull model as any other, and your lines pick it up under their own credentials. implementation lands after 1.0; the roadmap keeps the tally.

Give your chat a governed voice

The design is ratified; the core contract and the adapters are scheduled after 1.0. Stand up the hall today, and the switchboard will plug into that hall when it ships.