内容
# 哨兵 — 面向代理人工智能的安全代理,具备溯源感知能力
> **论文。** AI 代理的风险存在于**从指令来源到动作的因果路径**中,而非指令或动作的文本本身。哨兵保护**动作层**(工具调用),授权每个工具调用基于其**溯源**,确保指令通过检索内容到达,即使绕过内容过滤器,也不会驱动高风险动作。
**▶ 现场演示:https://sentinel-i63x.onrender.com** — 打开后,英雄攻击自动播放;观察数据外泄在几秒内被**阻止**。(免费层,闲置后可能需要 ~50 秒唤醒 — 只需刷新一次。)
哨兵是一个 **MCP(模型上下文协议)代理**。对于受保护的代理,它表现为 MCP 服务器;对于真正的工具服务器,它是 MCP 客户端。每个工具调用都必须经过哨兵 — **拦截由网络拓扑保证,而非代码包装**。它与代理无关:保护 Microsoft Foundry 代理、Claude、GPT 或任何自定义 MCP 客户端完全相同,且**无需修改代理代码**。
```
代理(Foundry / Claude / GPT / 自定义) ← 唯一可达的 MCP 端点
│ 使用 MCP
▼
┌─────────────────────────────────────────────┐
│ 哨兵 │
│ 溯源跟踪器 (集合模型) │ 每个工具调用 →
│ 授权引擎 (类型化 AST) │ ToolCallsProposed → 授权
│ 信任评分器 (二级,拉普拉斯) │ → 信任 → 转发 / 阻止
│ 法医跨度脊柱 (OTel + 序列) │ → ToolExecuted / ToolBlocked
└───────────────────┬─────────────────────────┘
│ 使用 MCP(仅在授权后)
▼
隔离的工具服务器 (web_fetch · send_email · get_customer_record …)
— 网络隔离:仅可从哨兵访问,无外部入口 —
```
## 差异化因素(溯源,正式)
溯源是 **信任标签集**(`SYSTEM > USER > AGENT > RETRIEVED_CONTENT`),通过跨度的传递 `derived_from` 祖先进行联合 — 而不是单个可变枚举。`is_tainted(span) := RETRIEVED_CONTENT ∈ effective_provenance(span)`。实际的防循环图遍历计算它;授权引擎将策略解析为**类型化条件 AST**(从不 `eval`),并在谱系被污染时阻止 `send_email`。污染仅通过显式、可审计的 **StructuredExtractor** 清除(模式验证 → 新鲜的 SYSTEM 信任值,无继承祖先)— 且不能用净化值清洗受污染的兄弟节点。
## 运行它
### 1 · 尝试现场演示(无需安装)
打开 **https://sentinel-i63x.onrender.com** — 英雄攻击自动播放,您将看到数据外泄在几秒内被阻止。点击 **重置** 然后 **启动攻击** (或 **--evasion**)以再次运行。免费层,闲置后可能需要 ~50 秒唤醒;只需刷新一次。
### 2 · 本地运行
**需要 Python 3.11+ 和 git.**
```bash
git clone https://github.com/Harshith029/Sentinel.git
cd Sentinel
python -m venv .venv
```
安装(可编辑,带开发额外功能)并启动仪表盘:
```powershell
# Windows (PowerShell)
.venv\Scripts\python.exe -m pip install -e ".[dev]"
.venv\Scripts\python.exe -m uvicorn sentinel.control.app:create_app --factory --host 127.0.0.1 --port 8765
```
```bash
# macOS / Linux (或仅:make dashboard)
.venv/bin/python -m pip install -e ".[dev]"
.venv/bin/python -m uvicorn sentinel.control.app:create_app --factory --host 127.0.0.1 --port 8765
```
然后打开 **http://localhost:8765** 并点击 **启动攻击** (或 **--evasion**)。
### 3 · 使用 Docker 运行(无需 Python)
```bash
docker build -t sentinel -f deploy/Dockerfile .
docker run --rm -p 8765:8765 sentinel # → http://localhost:8765
```
### 4 · 完整产品(添加真正的 `/mcp` 线上端点)
`create_gateway_app` 在 `/mcp` 处暴露一个可流式传输的 HTTP MCP 服务器,以便外部 MCP 客户端可以连接并通过同一管道保护 — 这就是现场演示和 `make serve` 运行的内容:
```bash
.venv/bin/python -m uvicorn sentinel.control.app:create_gateway_app --factory --host 127.0.0.1 --port 8765
```
### 5 · 测试和检查
```bash
.venv/bin/python -m pytest # 277 个测试 (make test)
.venv/bin/python -m ruff check src tests # 检查 (make lint)
.venv/bin/python -m mypy src # mypy --strict (make typecheck)
```
在 Windows 上,将 `.venv/bin/python` 替换为 `.venv\Scripts\python.exe`。`make` 目标只是 Unix 快捷方式,用于上述命令。
**英雄攻击。** 用户要求代理查找客户记录并研究定价页面。该页面被植入隐藏指令,以将记录发送到 `attacker@evil-corp.io`。记录被检索(RETRIEVED_CONTENT);页面被获取(RETRIEVED_CONTENT);诱导的 `send_email` 被 **阻止**,因为其血统被污染 — 合成 SSN/api_key **从未到达邮箱**。规避变体绕过第 1 层盾牌,仍被授权捕获(论文:架构拯救了局面,而不是过滤器)。
## 将哨兵置于您自己的代理(MCP over HTTP)之前
哨兵不仅仅是一个脚本演示 — 它通过真正的网络传输使用 MCP。`make serve` 将代理暴露为 **可流式传输的 HTTP MCP 服务器在 `/mcp` 处**。将任何 MCP 客户端指向它(Claude Desktop、Azure AI Foundry 代理或上游 `mcp` SDK),代理的每个工具调用都通过完整管道运行;客户端需要**没有哨兵特定的代码** — 拦截是通过拓扑结构,而不是集成。
```bash
make serve # 控制平面 + 仪表盘 + /mcp 线上端点
python examples/connect_over_http.py # 真实的 MCP 客户端驱动英雄攻击 → 阻止
```
每个 MCP 会话都是其自己的跟踪(自己的溯源前沿,每个代理的信任);实时运行在仪表盘上显示为 `live-mcp` 跟踪。这在 `tests/test_phase9_mcp_gateway.py` 中从头到尾得到证明 — 真实的 `mcp` 客户端连接,运行杀伤链,数据外泄在 MCP 边界被拒绝。默认情况下,下游工具服务器是进程内模拟;设置 `SENTINEL_TOOLS_{WEB,EMAIL,RECORDS}_URL`,网关改为通过 **MCP-over-HTTP** 连接到**远程工具服务器**(真实部署拓扑)— 在 `tests/test_phase9_mcp_gateway.py` 中从头到尾得到证明,代理路由到三个 HTTP 服务的工具服务器,仍然阻止数据外泄。
**真实的 LLM 是默认代理。** 当配置凭据时,每次运行都由真正的模型驱动,决定行动 — 设置 **`OPENAI_API_KEY`** (可选 `OPENAI_MODEL`,默认为 `gpt-4o-mini`)或 **`AZURE_OPENAI_ENDPOINT` + `AZURE_OPENAI_DEPLOYMENT`** (身份验证)。无需凭据,运行将确定性地回落到脚本转录,因此离线/CI 保持无密钥和可复制。
`LLMAgentDriver` 运行一个真正的工具使用循环,其中**模型**决定要执行的操作;哨兵是最后的保障。将它指向 `/mcp` 端点与真实模型 — 或如果您没有密钥,则使用离线易受攻击的替代模型:
```bash
OPENAI_API_KEY=sk-... python examples/run_live_agent.py # 真实模型,被诱导 → 阻止
python examples/run_live_agent.py --offline # 无密钥:忠实替代模型
```
模型获取中毒页面,被诱导发送记录到攻击者,调用在电线上被阻止 — 代理然后看到阻止并放弃。循环(和 OpenAI/Azure 适配器的解析)被 `tests/test_phase10_llm_agent.py` 覆盖,包括规避变体,其中第 1 层未命中,授权通过溯源仍然捕获。
## 威胁模型 — 哨兵不保护的内容(优势)
- 溯源跟踪在 **消息/工具结果** 粒度级别,而不是不透明模型推理中的 token 级别。污染保守地传播,除非净化器清除。
- 哨兵保护 **动作层**,而不是模型的认知。它不阻止模型被**说服**;它阻止由此产生的未经授权的**动作**。
- 代理本身和策略存储是**受信任**的组件。
- **跟踪亲和力:** 一个跟踪 → 一个代理实例;水平扩展是跨跟踪的,这就是为什么每个跟踪的单调 `seq` 足以(矢量时钟超出范围)。
## 框架
- **保守污染是故意的。** 我们优化以永远不会让不受信任的指令到达高风险动作,接受某些良性工作流需要显式净化。污染饱和是动作层安全的正确偏差。
- **净化是语法上的,而不是语义上的。** 模式验证的 `{price: 999999}` 仍然被参数级规则 `amount >= cap` 捕获。净化器和策略引擎捕获**不同**的问题类别并组合 — 优势,而不是差距。
- **MCP 是基质,而不是限制。** 由于拦截发生在 MCP 消息边界,哨兵在拓扑结构中下降到 *任何* 说 MCP 的代理或工具生态系统,而无需代码更改;代理是基础设施,而不是沙盒。
## 部署(Azure 容器应用)
插入点:注册哨兵作为代理的 MCP 工具服务器(`MCPTool`,`server_url=SENTINEL_MCP_URL`,`require_approval="never"`,工具显式枚举)— **代理唯一可达的 MCP 端点**。模拟工具服务器部署时**仅具有内部入口**(无外部端点);只有哨兵可以访问它们,因此拓扑结构强制执行论文。KEDA HTTP 并发缩放器在代理上;系统分配的托管标识 + Key Vault RBAC;Cosmos 按 `trace_id` 分区(幂等更新,默认 SDK 重试)。参见 [`deploy/`](./deploy) 和 [`deploy/DEPLOY.md`](./deploy/DEPLOY.md)。
**演示模式 vs AZURE 模式。** 安全管道在两种模式下**实时且相同**;只有集成在没有 Azure 时会降级。仪表盘的*部署模式*面板命名增量:Layer-1 提示盾牌、语义攻击分类器(Azure OpenAI)、分布式 Cosmos 持久性、应用洞察可观察性、实时 Foundry 驱动器和 Key-Vault 机密解析在 AZURE 模式下全部亮起。切换模式显示增量 — “Azure 是负载承载的”证明。只有代理**驱动器**在模式之间有所不同。
## 依赖项
Python 3.11+,Pydantic v2。确切的销钉记录在 [`versions.lock`](./versions.lock) 中; [`SDK_VERIFICATION.md`](./SDK_VERIFICATION.md) 中确认的 SDK 事实。关键运行时依赖项:`mcp==1.27.1`,`azure-ai-projects==2.0.0`,`openai==2.38.0`,`azure-identity`,`azure-cosmos`,`azure-monitor-opentelemetry`,`fastapi==0.136.3`,`sse-starlette==3.4.4`,`uvicorn`,`pydantic==2.13.4`,`PyYAML`。开发:`pytest`,`ruff`,`mypy`,`httpx`,`pre-commit`(带有 `gitleaks` 钩子)。
## 数据处理
**所有数据都是合成的。** “客户记录”是一个明确标记的假记录(`Jordan Rivera (SYNTHETIC TEST RECORD)`,SSN `000-00-0000`,一个非功能的 `sk-synthetic-DO-NOT-USE` 密钥)。`send_email` 将数据写入**内存汇集器** — 永远不会发送。法医跨度默认情况下存储在内存中(LRU 有界);在 AZURE 模式下,使用身份验证和仅限身份(无代码密钥)在 Cosmos 中。不会处理或持久化真正的 PII。开发中的机密存储在 gitignored `.env` 中;`gitleaks` 预提交钩子阻止意外提交。
## AI 工具披露
- **Claude Code** (Anthropic)— 逐阶段用于编写此实现。
- **GitHub Copilot** — 内联协助。
- **Azure OpenAI** — 语义攻击分类器(为 SOC 面板标记阻止尝试;AZURE 模式)。
- **Azure AI 内容安全 · 提示盾牌** — 第 1 层注入盾牌(AZURE 模式)。
## 开源积分
模型上下文协议 Python SDK (`mcp`),FastAPI,Starlette,`sse-starlette`,Uvicorn,Pydantic,OpenTelemetry,PyYAML,httpx,pytest,ruff,mypy,gitleaks,以及 Python Azure SDK。感谢他们的维护人员。
## 团队和角色
| 成员 | 角色 |
|---|---|
| Pali Krishna Harshith (单独)| 架构,溯源/授权核心,代理和控制平面,仪表盘和 UX,部署 |