Bus/Presence/MCP Auth Scope (T584)
Finding
apiTokenIsValid (src/store/apiTokens.ts) is wired into exactly one place: the REST
authorized() check in src/web/security.ts, which is itself skipped entirely when the
web server is bound to loopback (isLoopbackBind(), see enforceWebSecurity). The
team-bus/presence/MCP surface — src/store/busTools.ts (sendBusMessage, pollBusInbox,
queryRuns, listTeam, sendToTeam), src/store/presence.ts (announcePresence,
heartbeatPresence, tombstonePresence, roster, resolveRecords/resolveAddr), and
src/mcp.ts's registered tools (send_message, poll_inbox, query_runs, list_team) —
has zero reference to apiTokens. Any local process can publish a bus envelope or a
presence record and have it rendered/acted on by any other local participant (the TUI's
/team view, pollTeamInboxNow, another chat session, another MCP client) with no
identity check whatsoever.
Update 2026-09-22: the
src/mcp.tstools now have an opt-inCYBERINE_MCP_AUTH_TOKENgate (T602), fail-open when the env var is unset, seesrc/mcp.ts:63-86. The underlyingbusTools.ts/presence.tsstore functions still take no caller identity, so the residual gap is those functions, not "every MCP tool".
Decision: defer (no auth wiring)
This repo is explicitly in Sandbox stage (.claude/rules/user-vibe-stage.md): not deployed
anywhere, local/dev only, no production exists, single operator. Given that:
- The trust boundary is already the operator's own shell, not a network boundary.
The bus, presence directory, and MCP stdio transport all live under
$CYBERINE_HOMEon the local filesystem (src/store/messageBus.ts,src/store/presence.ts'sbusRoot()/presenceDir()), and the MCP server (src/mcp.ts) is a stdio process spawned directly by the host (Claude Code, Cursor, Claude Desktop) — never exposed over a socket. Anything able to write to that bus/presence directory or spawn the MCP process already has the same OS-level access as the operator's own terminal. A token check here would gate a boundary that does not exist yet. enforceWebSecurityalready establishes the precedent that this repo does NOT authenticate loopback-local traffic —isLoopbackBind()short-circuits the one placeapiTokenIsValidIS wired in. The bus/presence/MCP surface is at least as local as a loopback HTTP bind (it never leaves the filesystem/stdio), so treating it as unauthenticated is consistent with, not an exception to, the existing security posture.- The real multi-host teaming feature (T490) hasn't landed. Today every participant on
the bus is a process the same operator started, on the same machine. Auth only starts to
matter once the bus (or an MCP endpoint) can be reached by a process the operator did NOT
start — e.g. a remote teammate, a shared multi-host
$CYBERINE_HOME, or an MCP transport exposed over a network socket instead of stdio. Building token checks now, before that shape exists, is friction (every local dev/test invocation would need a token minted and threaded throughsendBusMessage/announcePresence/every MCP tool call) with no corresponding gain: the only additional thing an "attacker" could do today is act as a process the operator already trusts to run on their own machine. - Existing hardening already covers the realistic local-abuse case. T568
(
security(bus): sanitize presence+envelope in /team paths, seescripts/t568-smoke.ts) already sanitizes rendered presence/envelope fields against a malformed-or-hostile LOCAL writer (a buggy or unusual process on the same bus), which is the actual risk this stage faces — a garbage/oversized field crashing or corrupting the TUI render — not impersonation across a trust boundary that doesn't exist yet.
Re-open trigger
Re-open this decision (and default to "build": require apiTokenIsValid, or an equivalent
allowlist, on sendBusMessage/announcePresence/the MCP tool handlers) as soon as ANY of:
- T490 (multi-host teaming) ships and
$CYBERINE_HOME/the bus becomes reachable from a process the operator did not start. - The MCP server gains a network transport (SSE/HTTP) instead of stdio-only.
- The project's stage ladder moves off
early-dev(seeuser-vibe-stage.md) — i.e. any live deploy with real or shared users.
Non-decision
This note does not touch REST API auth (src/web/security.ts) — that path already has
apiTokenIsValid wired in and is out of scope for T584.
Hook Matcher: Anchoring vs Exact Match (T563)
Claude Code v2.1.195 changed hook matchers to require an EXACT match for hyphenated identifiers (e.g. code-reviewer, mcpbrave-search). Previously CC's matcher ran an unanchored substring test, so...
ContextQ Integration — Cyberine long-term memory on the Agent Memory Layer
Status: design spec (drives implementation). Grounded against ContextQ as it ships today (shared-context-server, agent layer migration 0043) and Cyberine memory waves 1-4.