gaurav-gs7/Judikt
GitHub: gaurav-gs7/Judikt
Judikt 是一个 MCP 安全网关和 AI agent 控制平面,通过确定性的策略执行、prompt injection 防御和防篡改审计来治理 AI agent 对外部工具的调用。
Stars: 0 | Forks: 0
# Judikt
Judikt 是一个用于 Model Context Protocol (MCP) 工具执行的确定性安全与可靠性控制平面。它在外部工具运行前管理请求,在不受信任的结果到达 agent 之前对其进行检查,并为这两项决策生成防篡改的操作证据。
核心演示仅需在 8 GB 内存的笔记本上运行,完全使用 Python,无需本地模型,也无需 API key。可选配置文件可添加官方 MCP SDK、Redis、OpenTelemetry/OpenInference、Docker 可观测性、AWS 部署以及 Groq 事件摘要。没有任何 LLM 参与允许或拒绝的决策。
## 150秒产品与实时终端演示

此录制中每个绿色的终端提示符都是存储库中可执行的命令。录制程序启动了真实的 Streamable HTTP MCP server,通过官方 MCP client 驱动它,并且仅渲染从这些执行过程中捕获的参数、响应、指标、审计状态、故障演练和基准测试摘要。
## 为什么开发此项目
MCP server 可以向 AI agent 公开功能强大的操作工具。有趣的非生产环境问题不在于 agent 能否调用工具,而在于平台能否在压力下约束、观察、禁用并解释这些调用。
Judikt 演示了:
- 通过 JSON-RPC stdio 进行 MCP 网关代理
- 面向生产客户端的官方 MCP SDK Streamable HTTP server
- 操作员配置的、指向独立构建的 stdio MCP server 的代理
- 针对官方 Filesystem、Memory 和 GitHub MCP server 的版本化互操作性测试工具
- 最小化的子进程环境,仅公开显式代理的上游凭证
- 在信任之前进行递归的工具描述和 JSON Schema 检查
- SHA-256 工具定义锁定与失败即关闭的 rug-pull 检测
- 跨工具参数、元数据和结果的确定性直接与间接 prompt injection 检查
- 抗规避扫描,涵盖 base64、hex、URL 编码、不可见 Unicode、易混淆字符、leetspeak、间隔字母 payload 以及跨 JSON 字段拆分的注入
- 针对西班牙语、法语、德语、葡萄牙语、中文和俄语中常见指令覆盖和角色重置短语的窄范围多语言规则
- 不会向 agent 返回恶意文本的隔离信封
- 策略即代码的允许列表和被阻止的参数模式
- 带有 issuer、audience、group 和 scope 验证的 JWT/OIDC resource-server 身份验证
- 经过身份验证的主体绑定,可拒绝调用者 actor 欺骗
- OAuth protected-resource 元数据和 caller-token 透传拒绝
- 范围限定的 OAuth 质询和精确的 HTTP Origin 验证
- 用于重启和回滚操作的 HMAC 签名批准 token
- 带有签名回调、批准者允许列表、去重和重放保护的 Slack 按钮批准
- 在执行影响生产的操作前强制执行回滚计划
- 用于安全 agent 评估的纯 dry-run 和 shadow-mode 结果
- 针对生产操作的确定性风险评分
- 针对审计日志和 agent 可见响应的密钥脱敏
- 针对每个工具的速率限制和即时 kill switch
- 用于多副本部署的可选 Redis 支持的分布式速率限制
- 带有保护隐私的哈希 actor/tool key 和实时多实例 CI 的原子 Redis 计数器
- 针对重复上游工具故障的断路器
- 哈希链式且可选 HMAC 签名的本地审计证据
- 针对生产模式的失败即关闭审计签名和全链路启动验证
- JSONL、S3、通用 HTTPS SIEM 或 Splunk HEC 审计传输,以及单独签名的 DynamoDB serverless 事件
- 跨运行时凭证的可重用 AWS Secrets Manager 和 Vault KV 密钥代理
- 关联 ID、Prometheus 指标、OpenInference/OpenTelemetry 追踪和 AWS X-Ray
- 包含 Prometheus、Grafana、Tempo、Jaeger 和 Redis 的 Docker Compose 可观测性栈
- 用于 Kubernetes 部署的 Helm chart
- 带有离线回退的可选 Groq 事件分析
- 通过 OpenTelemetry 导出的可选 OpenInference 兼容追踪
- MCP-38 覆盖矩阵和对抗性策略回归套件
- 兼容 MCP-AttackBench 的数据集适配器,提供分类别指标和隐私安全报告
- 可重现的全流水线延迟、开销、吞吐量和审计完整性基准测试
- 持久化的受阻发现导出,可在 Argus 的 RCA pipeline 中创建去重的 incidents
- AWS Secrets Manager、X-Ray tracing、IAM 审查、SLO、runbook 和故障模式测试
## 架构
```
flowchart LR
Agent["AI agent or MCP client"] --> Auth["OAuth/JWT authentication"]
Auth --> Request["Identity + allowlist + risk + rate + approval"]
Request -->|"deny"| Evidence["Signed audit + metrics + trace"]
Request -->|"allow"| Integrity["Pinned tool metadata check"]
Integrity --> Upstream["Built-in or external MCP server"]
Upstream --> Inspect["Result injection scan"]
Inspect -->|"quarantine"| Evidence
Inspect -->|"safe"| Redact["Recursive redaction"]
Redact --> Agent
Redact --> Evidence
Evidence --> Sink["SQLite/JSONL/S3/SIEM or DynamoDB/CloudWatch"]
Evidence --> Finding["Durable finding outbox or EventBridge"]
Finding --> Incident["Argus incident and RCA or SQS/DLQ"]
```
上游工具 server 是独立的子进程:
- `platform-ops`:生产服务健康状态、净化的配置、日志、允许列表诊断、滚动重启和部署回滚。
- `kubernetes`:pod 状态、受保护的 pod 重启和 rollout 状态。默认使用安全的模拟器,在受控实验室内可通过 `JUDIKT_KUBERNETES_MODE=kubectl` 指向 `kubectl`。
- `incident`:创建 incident、附加相关证据并读取时间线。
### 内容安全流水线
Judikt 将 MCP 参数、工具定义和工具结果视为不受信任的内容。每个被检查的字符串都会被直接检查,并通过规范化变体进行检查,这些变体会移除不可见控制字符、映射常见的易混淆字符和 leetspeak 字符,并折叠间隔字母混淆。候选的 base64、hex 和 URL 编码 payload 会被解码并重新扫描,而来自同一对象的字符串也会被连接起来进行有限的检查,以捕获跨 JSON 字段拆分的指令。
检查是确定性的、大小受限的且保护隐私的:检查结果包含规则名称、JSON path 和证据哈希,而不是匹配到的恶意文本。在 `fail_closed` 模式下,可疑结果会被替换为隔离信封,并且永远不会返回给 agent。超过扫描预算也会导致失败即关闭。`report_only` 和 `disabled` 模式可用于受控评估。
这是深度防御,而不是对完整语义检测的声明。多语言规则仅涵盖精心挑选的少量高价值短语,新颖的改写可能会逃避确定性模式。因此,Judikt 将内容检查与策略执行、范围限定的凭证、元数据锁定、批准、隔离、审计证据和 kill switch 结合在一起。
## 快速开始
要求:macOS 或 Linux 以及 Python 3.11+。
当项目虚拟环境存在时,启动脚本会自动使用 `.venv/bin/python`。否则,它们会使用系统 `python3`。
若要为某次运行使用独立的审计数据库:
```
./scripts/run_demo.sh --audit-db /tmp/judikt-demo.db
```
```
./scripts/run_demo.sh
```
常用开发者命令:
```
make test
make demo
make demo-recording
make eval
make attackbench-smoke
make performance-smoke
make failure-test
make interop-community
make trace
make observability-up
make helm-template
```
`make test` 是所有 Tier 1、Tier 2 和 Tier 3 工作的规范发布门控。它会配置独立的 Redis 和 Vault 容器,运行一次完整的单元/集成/端到端套件,强制执行聚合和安全关键的分支覆盖,执行对抗性和故障演练,测量受保护调用的性能,并验证锁定的官方 Filesystem 和 Memory MCP server。现有的 Redis 和 Vault endpoint 可通过 `JUDIKT_TEST_REDIS_URL`、`JUDIKT_TEST_VAULT_ADDR` 和 `JUDIKT_TEST_VAULT_TOKEN` 提供。
启动仪表板:
```
./scripts/run_dashboard.sh
```
然后打开 [http://127.0.0.1:8080](http://127.0.0.1:8080)。该页面包含用于允许的调用、被阻止的调用、批准的回滚演练、密钥脱敏和 kill switch 测试的按钮。
环回是唯一无需身份验证的模式。除非设置了 `JUDIKT_API_TOKEN`,否则绑定到任何其他接口都将失败。
浏览器会询问一次 token,并将其保留在会话存储中。
要将 Judikt 本身作为 stdio MCP server 公开:
```
./scripts/run_mcp_gateway.sh
```
对于 MCP client 配置,请使用:
```
{
"mcpServers": {
"judikt": {
"command": "/absolute/path/to/Judikt/scripts/run_mcp_gateway.sh"
}
}
}
```
### 外部 MCP Server
将 `JUDIKT_UPSTREAM_CONFIG` 设置为使用 [`config/upstreams.example.json`](config/upstreams.example.json) 中结构的 JSON 文件。命令直接执行,不通过 shell。敏感的上游凭证应使用 `from_env` 或 `from_aws_secret`;调用者提供的 OAuth token 会根据策略被递归拒绝。
测试套件会将 [`tests/fixtures/external_mcp_server.py`](tests/fixtures/external_mcp_server.py) 作为独立进程启动,并证明正常和纯文本响应、分页发现、server 发起的请求、环境隔离、注入结果隔离以及元数据更改阻止。版本化的[社区互操作性测试工具](docs/COMMUNITY_INTEROP.md)专门针对官方 MCP Filesystem 和 Memory server 以及 GitHub 的官方只读 server。
## 可选的 Groq 集成
默认情况下,演示会生成确定性的本地 incident 摘要。要添加托管的 LLM 摘要:
```
export GROQ_API_KEY="your-key"
export GROQ_MODEL="openai/gpt-oss-20b"
./scripts/run_demo.sh
```
如果 Groq 不可用,网关仍会继续工作。策略评估从不依赖于模型。
## 仪表板 API
| Endpoint | 用途 |
| --- | --- |
| `GET /healthz` | 就绪检查 |
| `GET /api/tools` | 列出上游 MCP 工具 |
| `GET /api/events` | 读取最近相关的审计事件 |
| `GET /api/kill-switches` | 读取被禁用的工具和 server |
| `GET /api/telemetry` | 读取 OpenInference 追踪模式和 OTLP endpoint |
| `GET /api/audit-integrity` | 验证本地审计哈希链和签名 |
| `GET /metrics` | Prometheus 风格的计数器 |
| `POST /api/call` | 调用受保护的工具 |
| `POST /api/approval` | 发放短期批准 token |
| `POST /api/kill-switch` | 启用或禁用工具或 server |
| `POST /api/analyze` | 汇总最近的审计证据 |
示例:
```
curl -s http://127.0.0.1:8080/api/call \
-H 'Content-Type: application/json' \
-d '{"server":"platform-ops","tool":"platform.health","arguments":{"service":"payments-api"}}'
```
为回滚发放签名的批准 token:
```
TOKEN=$(./scripts/python.sh -m judikt.cli issue-approval \
--actor gaurav \
--reason "rollback after elevated 5xx rate" \
--server platform-ops \
--tool platform.rollback_deployment \
--arguments '{"service":"payments-api","version":"payments-api@2026.05.2","actor":"gaurav","rollback_plan":"verify service health and restore previous release if errors increase"}')
curl -s http://127.0.0.1:8080/api/call \
-H 'Content-Type: application/json' \
-d "{\"server\":\"platform-ops\",\"tool\":\"platform.rollback_deployment\",\"arguments\":{\"service\":\"payments-api\",\"version\":\"payments-api@2026.05.2\",\"actor\":\"gaurav\",\"rollback_plan\":\"verify service health and restore previous release if errors increase\",\"approval_token\":\"$TOKEN\"}}"
```
## 测试
```
PYTHONPATH=src ./scripts/python.sh -m unittest discover -s tests -v
```
该套件测试了实际的子进程 MCP 边界,以及允许、拒绝、脱敏、批准、kill switch、断路器、审计和回退分析行为。
运行对抗性评估工具:
```
./scripts/run_evals.sh
```
评估涵盖不安全的诊断、直接 prompt injection、token 透传、未经批准的破坏性操作、未知工具、安全诊断、健康检查和审计脱敏。报告还验证了 [`config/mcp38_coverage.json`](config/mcp38_coverage.json) 中的所有 38 个条目:目前 12 个已覆盖,21 个部分覆盖,5 个根据该文件中存储的定义明确未覆盖。
单独的[兼容 MCP-AttackBench 的评估器](docs/ATTACKBENCH.md)可读取 JSONL、JSON、CSV 或可选的 Parquet 数据集,并报告准确率、精确率、召回率、F1、假阳性/假阴性率、各类别覆盖率、延迟百分位数、吞吐量以及输入/策略摘要。其内置的八样本 CI fixture 用于验证适配器;它并不代表在独立的 70,448 样本语料库上的结果。
运行故障模式测试工具:
```
./scripts/run_failure_tests.sh
```
它验证了批准门控、kill switch、断路器、脱敏和速率限制。
## Docker
构建并运行面向生产的真实 MCP 容器:
```
make docker-build
docker run --rm -p 8080:8080 \
-e JUDIKT_HTTP_BEARER_TOKEN="local-dev-token" \
judikt:local
```
容器绑定到 `0.0.0.0`,因此除非配置了 bearer/JWT 身份验证,或者为独立实验室明确设置了 `JUDIKT_ALLOW_UNAUTHENTICATED_REMOTE=true`,否则启动将失败即关闭。
容器默认使用官方 MCP Streamable HTTP server:
```
GET /healthz
GET /metrics
POST /mcp
GET /mcp
```
对于远程演示,请使用 bearer token:
```
docker run --rm -p 8080:8080 \
-e JUDIKT_HTTP_BEARER_TOKEN="$(openssl rand -hex 24)" \
judikt:local
```
要改为运行仪表板容器:
```
docker run --rm -p 8080:8080 \
-e JUDIKT_MODE=dashboard \
-e JUDIKT_API_TOKEN="$(openssl rand -hex 24)" \
judikt:local
```
仪表板 API client 必须发送 `Authorization: Bearer $JUDIKT_API_TOKEN`。
健康 endpoint 和仪表板页面保持未验证状态;仪表板 API
和 `/metrics` 受到保护。
## 真实 MCP Server
Judikt 现在包含一个使用 Streamable HTTP 的官方 MCP SDK server。它通过项目其余部分所使用的相同策略、风险、批准、脱敏、审计、指标、kill switch、速率限制和断路器控制来公开生产操作工具。
在本地运行:
```
export JUDIKT_HTTP_BEARER_TOKEN="local-dev-token"
./scripts/run_real_mcp_http.sh --host 127.0.0.1 --port 8080
```
MCP endpoint:
```
http://127.0.0.1:8080/mcp
```
通过存储库的官方 Streamable HTTP client 驱动该 endpoint:
```
export JUDIKT_MCP_URL="http://127.0.0.1:8080/mcp"
./scripts/mcp_client.sh list
./scripts/mcp_client.sh call platform.health \
--arguments '{"service":"payments-api"}'
```
client 从 `JUDIKT_HTTP_BEARER_TOKEN` 读取 bearer 身份验证,打印确切的请求和结构化响应,递归隐藏敏感的响应 key,并支持批准 token 的 `0600` 权限模式文件,以防它们进入 shell 历史记录或终端输出。
MCP server 公开的适用于生产环境的工具:
- `platform.health`
- `platform.read_config`
- `platform.read_logs`
- `platform.run_diagnostic`
- `platform.restart_deployment`
-platform.rollback_deployment`
- `kubernetes.get_pod`
- `kubernetes.restart_pod`
- `kubernetes.rollout_status`
- `incident.create`
- `incident.attach_evidence`
- `incident.timeline`
- `judikt.issue_approval`
- `judikt.request_approval`
- `judikt.approval_status`
- `judikt.call_upstream`
- `judikt.set_tool_enabled`
- `judikt.set_server_enabled`
- `judikt.runtime_state`
## AWS Free-Tier 部署
主要的完整 AWS 路径是由 Terraform 管理的 EC2,运行官方 Streamable HTTP MCP 容器,并配备 ECR、IAM、Secrets Manager、SSM Session Manager 和加密的 EBS。Lambda/API Gateway/DynamoDB/EventBridge/SQS 栈是一个独立的 serverless 控制平面实验室,配有 CloudWatch 和 X-Ray;它锻炼了更强的 AWS serverless 技能,但公开的是 HTTP 工具 API,并未声称是官方 MCP 传输。Free-tier EC2 路径是一个受限 CIDR 的实验室 endpoint,而不是 TLS 终止的公共生产 endpoint。
从 [docs/AWS_FREE_TIER_DEPLOY.md](docs/AWS_FREE_TIER_DEPLOY.md) 开始,然后使用 [docs/AWS_AIOPS_SKILLS.md](docs/AWS_AIOPS_SKILLS.md) 将此项工作转化为 AIOps/LLMOps 学习路线图。
有关 JWT 身份验证、基于 Redis 的速率限制、Grafana/Tempo/Jaeger 和 Helm 的使用,请参阅 [docs/PRODUCTION_ENHANCEMENTS.md](docs/PRODUCTION_ENHANCEMENTS.md)。
推荐的 serverless 命令形式:
```
export AWS_REGION=us-east-1
export JUDIKT_API_TOKEN="$(openssl rand -hex 24)"
export JUDIKT_APPROVAL_SECRET="$(openssl rand -hex 32)"
export JUDIKT_AUDIT_HMAC_SECRET="$(openssl rand -hex 32)"
./scripts/aws/deploy_serverless.sh
```
演示后销毁 serverless 部署:
```
./scripts/aws/destroy_serverless.sh
```
EC2 Terraform 命令形式:
```
export AWS_REGION=us-east-1
export JUDIKT_ALLOWED_CIDR="$(curl -s https://checkip.amazonaws.com)/32"
export JUDIKT_HTTP_BEARER_TOKEN="$(openssl rand -hex 24)"
export JUDIKT_APPROVAL_SECRET="$(openssl rand -hex 32)"
export JUDIKT_AUDIT_HMAC_SECRET="$(openssl rand -hex 32)"
./scripts/aws/deploy_terraform.sh
```
演示后销毁 Terraform 部署:
```
./scripts/aws/destroy_terraform.sh
```
CloudFormation 回退方案:
```
export AWS_REGION=us-east-1
IMAGE_URI=$(./scripts/aws/build_push_ecr.sh)
./scripts/aws/deploy_ec2.sh "$IMAGE_URI"
```
演示后删除 CloudFormation 栈:
```
./scripts/aws/delete_stack.sh
```
## 可选的 OpenInference Tracing
默认演示没有第三方运行时依赖。要启用 AI 感知的分布式追踪,请安装可观测性配置文件:
```
python3 -m pip install -e '.[observability]'
```
将兼容 OpenInference 的 span 打印到终端:
```
JUDIKT_TELEMETRY=console ./scripts/run_demo.sh
```
通过 OTLP HTTP 将 span 导出到本地 Phoenix 实例或其他兼容 OTLP 的后端:
```
export JUDIKT_TELEMETRY=otlp
export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://127.0.0.1:6006/v1/traces
./scripts/run_dashboard.sh
```
追踪层级是有意设计为安全感知的:
```
judikt.call_tool CHAIN
judikt.policy.evaluate GUARDRAIL
mcp.platform.health TOOL # only created for forwarded calls
groq.incident_summary LLM # only created when Groq is called
```
在将参数和输出附加到 span 之前,会对其进行脱敏。远程 server 使用官方 MCP Python SDK,而 Judikt 会发出显式的策略、工具和 LLM span,使得安全决策具有独立于自动注入的稳定属性。外部 stdio 上游仍然是独立的进程,并且尚未在该进程边界上传播追踪上下文。
## 威胁模型
已实施并测试的控制直接解决了以下问题:
- Agent 尝试访问敏感的本地路径,例如 `.ssh`、`.aws` 和 `.env`。
- Agent 尝试在诊断参数中运行不安全的网络命令。
- 嵌入在工具参数中的直接 prompt injection。
- 嵌入在外部 MCP 工具结果中的间接 prompt injection。
- 确定性检查规则所涵盖的编码、Unicode 混淆、间隔字母、易混淆字符、多语言短语和拆分字段变体。
- 恶意的工具描述、嵌套的 schema 字段、确切的名称影子覆盖和 rug pull。
- 调用者 token 透传和经过身份验证的 actor 欺骗。
- 未经授权的重启或回滚操作。
- 上游工具响应或记录的参数导致的密钥泄漏。
- 对昂贵或破坏性工具的重复大容量调用。
- 对受损工具或 MCP server 的快速遏制。
- 审计记录突变以及通过可选的中央传输导致的仅本地证据丢失。
仍然存在明显的差距:Judikt 是一个 OAuth resource server,而不是授权 server;PKCE 和每个 client 的同意应属于所选的 IdP/client 流程。它的内容防护是启发式的,而不是完整的语义或基于模型的检测器,其多语言规则也特意不具有详尽性。它尚未提供多租户隔离、用于隐私推理的语义 DLP、除 Origin 验证之外的完整 Host-header 和部署边缘 DNS-rebinding 防御、加密签名的策略包、OS 级别上游沙箱,或完整的 MCP resource/prompt 代理。覆盖矩阵将这些视为部分覆盖或未覆盖,而不是将项目展示为普遍达到生产完备状态。
## 设计说明
简短的设计说明位于 [docs/DESIGN_NOTES.md](docs/DESIGN_NOTES.md),产品路线图位于 [docs/ROADMAP.md](docs/ROADMAP.md),AWS 学习计划位于 [docs/AWS_AIOPS_SKILLS.md](docs/AWS_AIOPS_SKILLS.md),生产运维文档位于 [docs/SLO.md](docs/SLO.md)、[docs/RUNBOOKS.md](docs/RUNBOOKS.md)、[docs/IAM_REVIEW.md](docs/IAM_REVIEW.md)、[docs/TRACING.md](docs/TRACING.md)、[docs/PERFORMANCE.md](docs/PERFORMANCE.md)、[docs/FAILURE_TESTING.md](docs/FAILURE_TESTING.md)、[docs/CICD.md](docs/CICD.md)、[docs/COMMUNITY_INTEROP.md](docs/COMMUNITY_INTEROP.md) 和 [docs/PRODUCTION_ENHANCEMENTS.md](docs/PRODUCTION_ENHANCEMENTS.md)。
## 许可证
本项目基于 Apache License 2.0 授权获得许可。简而言之,您可以修改、分发和再授权代码。
请参阅 [LICENSE](LICENSE) 了解完整条款,并参阅 [SECURITY.md](SECURITY.md) 获取
支持的部署边界和漏洞报告指南。
标签:子域名突变, 搜索引擎查询, 用户代理, 自定义请求头, 请求拦截, 逆向工具