Skip to main content
Glama
nasserma

communications-access-broker

by nasserma
README.md
# communications-access-broker

Communications MCP access broker: tiered, human-gated chat access to
Matrix and Microsoft Teams, built on access-broker-core. Fourth broker
in the suite.

## Why access brokers

The Model Context Protocol connects AI agents to real infrastructure:
file stores, chat platforms, mail servers, a home. Its permission model
is static. An MCP server declares a list of tools; the client shows the
list to the user once, at install time; the user approves; from then on,
every tool call runs with the server's full credential.

The model cannot express what matters once the infrastructure is real.

- A grant is all-or-nothing at install time. There is no scoped, expiring
  grant for one folder, one room, or one lock. Approving the server
  approves everything it can reach.
- There is no per-operation review. After install, a destructive write
  runs as freely as a harmless read.
- There is no audit of agent decisions. What the agent requested, what
  was refused, and who approved what is recorded nowhere the owner
  controls.
- There is no human gate for sensitive actions. The only approval
  happened between the agent and the client, before any concrete
  operation existed.
- The credential at the server carries everything the server can do.
  Tool descriptions that promise restraint are advisory; the token is
  not.

An access broker is an MCP server that closes these gaps for one domain.
It holds the real credential, exposes a deliberately small tool surface,
and turns access into an explicit object: a scoped, expiring, audited,
human-approved grant, evaluated per operation.

## The access broker model

The suite implements one model with seven properties. Every broker
carries all of them; the mechanics live in access-broker-core.

1. A tier model per domain. Every operation is classified before it can
   be requested. T0/T1 are free-lane reads and reversible actions that
   run without a grant. T2 operations are sensitive and require
   per-operation human approval through an approval gateway on a chat
   platform; the agent cannot self-approve, and batches do not exist.
   T3 operations are always gated and, where the action is irreversible,
   are never offered as tools at all.

2. Declared operations. Each tool names the operation it performs. The
   wall, the broker's scope checker, validates the resource and the
   operation against active grants before anything executes. The free
   lane is defined by the domain tier table, not by what happens to be
   exposed.

3. Write-before-operate, hash-chained audit. Every request, execution,
   refusal, and human decision is an audit-class event written to a
   hash-chained log before the operation runs. `verify_chain` detects
   tampering, including truncation. The chain, not memory, is the record
   of what the agent did and why.

4. Fail-closed everywhere. Any configuration or validation failure
   refuses the boot. Unknown or malformed input denies. A restart never
   widens capability and never promotes pending or suspended state.

5. Approval separation. The approval gateway account is never a brokered
   account. A broker that could approve its own requests is a design
   failure, and the configuration is refused at boot.

6. Custody declarations. The broker declares, machine-readably, what its
   backend credentials can reach. An undeclared trust boundary refuses
   to start, and the custody class rides every audit record.

7. The D5 two-surface model in the data domain. The agent surface
   handles metadata and reasoning; bulk bytes move through a separate
   transfer surface addressed only by a CLI holding its own token, with
   SHA-256 verify-then-write. File content never enters LLM context.

## The suite

[access-broker-core](https://github.com/nasserma/access-broker-core)
carries the mechanics: the grant store (conditional-SQL CAS state
machine), policy wall evaluation, the hash-chained audit log, the
approval-gateway substrate, the custody registry, the baseline engine,
and transport authentication. Each broker is a thin domain layer: a
scope-checker wall, backend adapters, a tier table, and tool surfaces.
One repo per broker; no monorepo.

| Broker | Domain | Repository |
|---|---|---|
| data-access-broker | WebDAV and OneDrive file stores | https://github.com/nasserma/data-access-broker |
| communications-access-broker | Matrix and Microsoft Teams chat | to be published |
| groupware-access-broker | Mail, calendar, contacts, tasks over IMAP/SMTP, CalDAV/CardDAV, MS Graph | to be published |
| automation-access-broker | Physical automation: Home Assistant entities and services, extendable to any actuated device | to be published |

## What it is

One MCP server brokering an AI agent's access to chat platforms. The
broker holds a dedicated Matrix account's token and a Teams delegated
Graph token; the agent never sees either. It contributes the
communications wall (room scoping), the Matrix (matrix-nio) and Teams
(Graph delta-polling) backends, and the enforcement that gives
approval separation teeth for the first time in the suite: the
brokered Matrix account must never be its own approval gateway, and a
configuration where the two coincide refuses the boot
(`check_approval_separation`).

## The tier model for conversation

- **No free reads.** Conversation content is surveillance-grade; reads
  are grant-scoped per room, full stop. A read without an active grant
  naming the room is refused. This is the one broker in the suite with
  no T0/T1 lane at all: the seventh suite property is data-domain, and
  this domain's analogue goes the other way, everything is grant-scoped
  because everything a room contains is private by default.
- **T2 gated, per operation (no batches):** send, reply, react,
  edit-own. Messages have no version history and no trash; per-
  operation approval is the compensating-control argument.
- **T3 gated, never offered:** redaction, deletion, bulk operations,
  membership changes, moderation. No v1 tool form reaches them; a
  moderation function that cannot be revoked after the fact does not
  become a tool.
- **No wildcards.** Grants name rooms exactly; room aliases resolve at
  the backend boundary, never in the wall.
- **E2EE fails closed.** Encrypted rooms are detected and refused at
  the backend boundary; key custody is a fast-follow with its own
  review.
- **One discovery exception: `list_spaces`.** The account-scoped
  `@spaces` read (room ids, names, joined/invited state) is the
  surface's single free read — audited like every executed op, never
  content. Registered only when the deployment enables discovery
  (`discovery: true`, the default; `false` removes the tool at
  registration time). Everything else in the tier table is unchanged:
  a grant-less content read is refused, never approvable by call.

Tool surface: `get_history`, `get_room_state`, `get_members` (reads,
grant-scoped per room; each preflighted — an invisible room refuses
with the real reason, never a silent empty payload), `send_message`,
`reply`, `react`, `edit_own` (each individually human-approved), plus
`request_access`, `check_access`, `revoke_access`, `list_accounts`,
and `list_spaces` (discovery; see the exception above).

## Production-alpha notes

Live-verified 2026-09-21/22 through the owner's native MCP client
(discovery → request → approval → grant → read/send → read-back).

- **Approval-plane shield.** `execute()` and `request_access` refuse
  ANY operation on the gateway's own approval room, before the wall:
  the brokered identity cannot request access to the room that
  approves it. The shield beats active grants and rides
  `protected_surfaces` from the gateway config.
- **Membership preflight.** Every content read (`get_history`,
  `get_room_state`, `get_members`) verifies the caller's own
  membership first: homeservers answer reads on invisible rooms with
  an HTTP-200 empty payload, and the preflight turns that into a
  refusal with the real reason.
- **T2 grant semantics (open, owner decision pending).** An approved
  T2 grant currently carries a time window, while the historical
  wording promises per-operation approval every time. No
  consume-on-use path exists in v1. Resolution options on record:
  execute-time self-revocation after a gated op fires (true one-shot)
  or a docstring correction to match the window semantics. Until the
  owner decides, treat an approved T2 grant as a time window and audit
  it accordingly (grant-level revocation is available agent- and
  owner-side).
- **Known cosmetic gaps (queued).** Pending-request dedupe (repeated
  requests stack new numbers), the `ops` comma-string parameter shape,
  and pre-approval validation of gated-op targets.

## What is NOT here (v1)

Email (never here; drafts and store-and-forward are the groupware
broker's domain), Telegram and Signal (v2), encrypted rooms, voice
(deferred hard: no draft artifact, no revision point), raw user-API
Telegram reads (ToS-sensitive). File storage is the data broker's
domain; PIM is groupware's; entities are the automation broker's.

## Status

Production alpha (owner-verified live 2026-09-22 through the native
MCP client; see the notes above). 327 tests across nine files, 100%
statement and branch on every module; the real-protocol battery runs
against a scratch Dendrite. See CHANGELOG.md and DEPLOYMENT.md
(including the user-space systemd supervision section). Repository
publication: Sourcehut canonical, owner-gated.

## Security

SECURITY.md carries the domain threat model: the primary adversary is
the conversation content itself (a planted prompt injection in any
granted room is inside the agent's trust boundary), the secondary is
the irreversibility of sent messages, the tertiary is the approval
plane. Custody classes are declared per backend (matrix: account-wide;
teams: scoped under the employer app registration). The suite
invariants are stated once in the core README and inherited here.

## Provenance

Author and maintainer: Nasser Mohieddin Abukhdeir. The primary
implementation model was GLM (glm-5.3), with glm-5.3-flash as the
delegated sub-agent model. See AUTHORS.md for the full provenance
record.

## License

GPL-3.0-or-later.