SubjectBroker

SubjectBroker

Enables AI agents to access registered resources based on a fixed subject identity, enforcing default-deny policies and auditing for controlled context sharing.

Category
访问服务器

README

SubjectBroker

English · 简体中文 · 繁體中文

CI License

SubjectBroker helps different AI agents see different data—even when they work in the same project.

SubjectBroker is an experimental subject-bound context broker with default-deny policy and fail-closed auditing. The current prototype speaks the Model Context Protocol (MCP); the authority model is protocol-independent.

[!WARNING] SubjectBroker is an experimental macOS research prototype, not a production security boundary or an agent sandbox. An agent with direct filesystem, shell, network, browser, credential, or process access can bypass the broker. Use OS-level isolation to close those paths.

SubjectBroker is useful when multiple AI agents work against the same project and some registered data should be reachable by only some of them. It is not a replacement for a sandbox.

Want to see it work first? Jump to the quick start.

SubjectBroker in plain English

Imagine several AI assistants working in the same environment. They should not automatically receive the same data.

SubjectBroker places a controlled checkpoint in front of selected resources. Instead of asking for a filesystem path, an agent asks for a registered name such as design-doc. Each SubjectBroker process starts with a fixed subject, such as orchestrator or worker, and that subject cannot be changed by the request.

For every brokered read, SubjectBroker checks a default-deny policy, verifies the registered file, and writes a metadata-only audit event. Content is returned only if every required step succeeds. A denied request—or an audit failure—returns no protected content.

SubjectBroker is not limited conceptually to secrets: the context being controlled could represent a design document, customer record, knowledge source, or credential. The current prototype implements this model for registered UTF-8 text files.

Three terms describe the model:

  • Subject — the AI identity making the request, such as orchestrator or worker.
  • Resource — registered data with a stable name, such as design-doc.
  • Policy — the rules deciding which subject may read which resource.

For example, an orchestrator might be allowed to read design-doc but denied access to customer-records. A worker can have a different view of the same project because it is evaluated as a different subject.

Why this exists

Agent frameworks often hand a subtask to a child agent while giving that child the parent's full authority. If a parent can see both an orchestrator and worker MCP connection, a default child may inherit both and gain their combined authority.

Unsafe: one context holds both subjects       Safer: one visible subject per context

parent: orchestrator + worker                 orchestrator process: orchestrator only
└── child inherits both                       worker process: worker only
                                              └── descendants inherit worker only

SubjectBroker makes the MCP side of that boundary explicit:

  • subject identity is fixed when the process starts;
  • callers request registered resource IDs, never arbitrary paths;
  • policy is default-deny;
  • allowed content is released only after audit succeeds; and
  • denial, error, and audit output exclude protected content.

How the data path changes

SubjectBroker does not classify content or make decisions by topic. It changes how registered resources are requested: the agent asks for a stable resource ID, and the process-bound subject is evaluated before protected content can be returned.

flowchart TB
    subgraph BEFORE["Before — agent reads data directly"]
        A1["Agent"] -->|"Direct file access"| F1[("Protected data")]
        F1 --> O1["Data reaches agent<br/>No SubjectBroker policy decision"]
    end

    subgraph AFTER["With SubjectBroker — access is brokered"]
        A2["Agent"] -->|"Request a resource ID"| B["SubjectBroker"]
        B --> P{"Policy allows<br/>this subject?"}

        P -->|"Yes"| R["Verify file identity<br/>Read data + write audit"]
        R --> O2["Data reaches agent"]

        P -->|"No"| D["Record denial<br/>No protected content"]
        D --> O3["Agent receives<br/>ACCESS_DENIED"]
    end

An allow decision is not sufficient by itself: file verification, a bounded UTF-8 read, and the metadata-only audit write must all succeed before content is released. A denied read records the outcome and returns no protected bytes.

Quick start

All current security, integration, and demo validation was performed on macOS. On other platforms, the enforced read path and demo fail closed with PLATFORM_UNSUPPORTED rather than claiming an unverified security boundary.

To run the current demo, install:

  • Node.js 20 or newer; and
  • npm.
git clone https://github.com/gexchai/subject-broker.git
cd subject-broker
npm ci
npm run demo

Expected result:

SubjectBroker subject-bound read demo

orchestrator → {"decision":"allow","reasonCode":"ALLOWED","resourceId":"secret","content":"SUBJECT_BROKER_DEMO_SECRET\n"}
worker       → {"decision":"deny","reasonCode":"ACCESS_DENIED","resourceId":"secret"}

Both outcomes were written to separate metadata-only audit logs.

The demo creates a temporary protected resource and one policy, then starts two broker instances bound to different subjects. It cleans up its temporary files on exit. The integration test suite separately exercises the complete MCP stdio transport.

Run the full unit, integration, and security test suite:

npm test

Implemented safeguards

The implemented macOS path includes:

  • process-level subject binding;
  • strict policy parsing and default-deny evaluation;
  • registered resource IDs instead of caller-supplied paths;
  • symlink, replacement, and file-identity checks;
  • bounded strict UTF-8 reads;
  • fail-closed audit semantics;
  • non-sensitive denial and startup diagnostics; and
  • a capability report that names covered and uncovered paths.

Field-tested agent behavior

These are version-pinned integration results, not universal claims about future releases.

Harness Observed delegation behavior Supported distinct-subject topology
Claude Code 2.1.220 Default subagents inherited parent MCP authority Persistent named custom subagent with an explicit MCP tools allowlist
Codex CLI 0.144.4 Native children inherited parent MCP connections Separate process and CODEX_HOME, with one subject connection per profile; tested through depth 2
Hermes Agent 0.19.0 Native delegation inherited the profile's connections Separate top-level process/profile per subject
Pi 0.82.1 No native subagent mechanism in the tested release Separate single-subject process; direct-read enforcement still requires a sandbox

See the Claude Code, Codex, Hermes, and Pi integration notes for the exact boundaries.

Run as an MCP server

Build the server:

npm run build

Create a policy using absolute paths:

version: 1
storageRoot: /absolute/path/to/protected-storage
subjects:
  - orchestrator
  - worker
resources:
  contract:
    path: /absolute/path/to/protected-storage/contract.txt
rules:
  - subject: orchestrator
    resource: contract
    action: read
    decision: allow
  - subject: worker
    resource: contract
    action: read
    decision: deny

Start one process for one subject:

node dist/server.js \
  --policy /absolute/path/to/subject-broker.yaml \
  --subject worker \
  --audit /absolute/path/to/subject-broker-worker-audit.jsonl \
  --max-bytes 1048576

The stdio server exposes exactly:

  • list_resources
  • read_resource
  • explain_decision
  • capability_report

--max-bytes defaults to 1 MiB. Policy and registered file identity are pinned at startup. Restart after an authorized resource replacement; a changed file identity returns RESOURCE_CHANGED.

The audit destination must be a regular owner-only (0600) file and must not be a symlink. If validation or writing fails, content is not released.

Detect cross-subject retries

The offline checker flags one observed escalation pattern: a deny for one subject followed by an allow for a different subject on the same resource within a configured window.

npm run audit:check -- \
  --window-seconds 10 \
  /absolute/path/to/audit-worker.jsonl \
  /absolute/path/to/audit-orchestrator.jsonl

Exit code 0 means no match, 2 means one or more suspicious matches, and 1 means invalid arguments or audit input.

This is a heuristic detective control. It may flag legitimate concurrency and cannot detect a privileged-first call. A clear result does not prove safe delegation.

What SubjectBroker does not do

SubjectBroker does not currently provide:

  • OS sandboxing or mandatory routing through the broker;
  • protection from direct filesystem, shell, network, browser, clipboard, credential, or process access;
  • encryption, redaction, classification, search, or write operations;
  • a daemon or cloud control plane; or
  • a guarantee that third-party agent frameworks isolate their own delegated contexts.

The central deployment invariant is:

Every agent context must see only the SubjectBroker connection for its assigned subject.

If one context can see multiple subject-bound connections, its effective authority is their union. The broker cannot repair that configuration from inside a third-party harness.

Evidence

Published field evidence is minimized to relevant actor relationships, tool events, prompts, normalized configuration, and broker audits. Raw account, machine, plugin, session, request, thinking-signature, and unrelated provider metadata are not published. Source-artifact SHA-256 hashes are retained for provenance.

Project status

Status: experimental, working, attack-tested spike.

SubjectBroker was developed under the former working name ContextGuard. Dated architecture decisions and retained field evidence preserve that name where changing it would rewrite the historical record.

The policy schema and behavior may change. Only entries marked decided in DECISIONS.md describe deliberate choices for this spike. Before production use, the direct-read path requires an independently verified OS sandbox and a fresh security review.

See CONTRIBUTING.md before proposing a change. Potential vulnerabilities should follow the private-reporting guidance in SECURITY.md.

Licensed under the Apache License 2.0.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选