MCP Security Gateway
# MCP Security Gateway(Open-Core)
让企业敢把 AI Agent 接进生产系统的「安全治理网关」——开源核心版。
```
MCP Client/Agent ──Bearer/JWT──> 网关(策略+审计+代理) ──MCP──> 上游 Server(CRM/工单/知识库)
```
## 功能(开源核心 v0.1:M1-M4)
- **MCP 代理**:代理上游 `tools/list` 与 `tools/call`;stdio 与 **Streamable HTTP** 双形态服务。
- **工具级 RBAC + 受限授权**:按角色 allow/deny,`policy.default: deny` 安全默认;allow 规则可携带**参数约束**(lte/gte/maxLength/pattern/in…),越界 = 约束不满足 = 拒绝;listTools 不泄露无权工具。
- **身份(M4)**:stdio 走 env/静态;HTTP 走 `Authorization: Bearer <token>`——
- `static`:配置文件或 `${ENV}` 注入的令牌映射(联调/服务账号);
- `oidc`:JWT + JWKS(issuer/audience 校验),自定义 `rolesClaim`(支持 Keycloak `realm_access.roles` 风格点路径)、`subjectClaim`、`agentClaim`,可直接对接企业 IdP(企微/飞书/Okta)。
- **审计哈希链(WORM-lite)**:append-only JSONL + SHA-256 前向链;`谁-角色-Agent-工具-入参摘要-决策-原因` 可完整校验、可检测篡改;进程重启自动续链。
- **YAML 配置(GitOps 友好)** + `${ENV_VAR}` 替换(令牌不入库)+ CLI。
## 快速开始
```bash
npm install
npm test # 64 用例:策略/审计链/配置/OIDC 验证/HTTP 与 stdio 端到端
npm run demo # stdio:Client → 网关 → CRM
npm run demo:http # HTTP:Bearer viewer/operator 双身份演示(监听 127.0.0.1:8090)
```
```bash
# stdio 模式(作为本地 MCP Server 被 Agent 拉起)
tsx src/index.ts --config examples/gateway.yaml
# HTTP 模式
npm run dev:http
curl -i http://127.0.0.1:8090/mcp # GET 元数据(可作探针)
# 业务调用请使用任意 MCP Client 并携带 Authorization: Bearer demo-viewer-token / demo-operator-token
```
`examples/gateway.yaml`(stdio)与 `examples/gateway-http.yaml`(HTTP + static 令牌 + OIDC 模板注释)内置演示 CRM 上游:viewer 只读、operator 受限发邮件、delete 全局拒绝。
## 容器与 K8s(M3)
```bash
# 本地/单机(已提供 docker-compose,审计卷持久化)
docker compose up -d --build
# 镜像含:dist 编译产物 + 示例上游;以非 root、只读根文件系统运行
# 审计日志:/app/data/audit.log(哈希链,篡改可检出)
# Kubernetes(deploy/k8s/,按文件名顺序 apply)
kubectl apply -f deploy/k8s/00-namespace.yaml
kubectl apply -f deploy/k8s/10-configmap.yaml
kubectl create secret generic gateway-tokens -n mcp-gateway \
--from-literal=GATEWAY_TOKEN_VIEWER=$(openssl rand -hex 24) \
--from-literal=GATEWAY_TOKEN_OPERATOR=$(openssl rand -hex 24)
kubectl apply -f deploy/k8s/30-pvc.yaml -f deploy/k8s/40-deployment.yaml -f deploy/k8s/50-service.yaml
```
> 说明:`deploy/k8s/20-secret-sample.yaml` 仅供开发演示。配置经 ConfigMap 挂载,令牌经 Secret + `${ENV}` 注入。镜像构建需在本机或 CI 具备 Docker 的环境执行。
## 目录结构
```
src/
├── config/ schema + YAML loader(role 快捷规则、${ENV} 替换、HTTP 认证配置)
├── policy/ engine:纯函数策略评估(deny > 受限 allow > default)
├── audit/ logger:哈希链 JSONL(自动建目录、断链可校验)
├── identity/ Env/静态上下文 + auth.ts:Bearer → IdentityContext(static/OIDC+JWKS)
├── upstream/ MCP Client:stdio / http 适配(协议隔离点)
├── gateway/ Guard:决策 → 审计 → 透传(支持显式会话主体)
├── server/ handlers(共享绑定)+ stdio + http(Streamable HTTP、Bearer 会话)
examples/ 示例配置 + CRM Demo Server
deploy/ Dockerfile / docker-compose / k8s manifests
test/ node:test 用例 + stdio/http 演示客户端
```
## 开源 / 商业边界
| 本仓库(开源核心,Apache-2.0) | 商业增强版(独立私有仓,专有许可) |
|---|---|
| MCP 代理(stdio / Streamable HTTP) | 行 / 字段级 PII 脱敏 |
| 工具级 RBAC + 参数约束 | HITL 审批工作台 |
| 审计哈希链(WORM-lite) | 注册中心 + 供应链扫描 |
| 静态 / OIDC 身份接入 | 合规报告自动导出 |
| YAML 配置 + Docker / K8s 部署件 | 治理控制台 + 计量与授权 |
两者仅通过**公开契约**集成:`src/exports.ts` 的管道 Hook 契约与审计链只读 API。
开源核不内联任何商业逻辑,也不依赖商业包内部路径。
## 里程碑状态
- [x] M1:骨架 + 核心模块(策略 / 审计 / 配置)
- [x] M2:stdio 代理打通(真实上游 CRM 端到端)
- [x] M3:Dockerfile 多阶段 + compose + K8s manifests(镜像与 dist 冒烟通过)
- [x] M4:Streamable HTTP + Bearer 会话 + OIDC / 静态身份验证(12 项新用例)
变更记录见 `CHANGELOG.md`。
## 许可与参与
- **许可**:Apache-2.0,见 `LICENSE`;第三方组件许可见 `NOTICE`。
- **贡献**:见 `CONTRIBUTING.md`。
- **安全问题**:请遵循 `SECURITY.md`,勿开公开 Issue。
TDQS
Scored across 2 tools
The two tools are clearly distinct: one lists customers in a paginated manner, the other fetches a single customer's details. There is no overlap or ambiguity in their purposes.
Both tool names follow the exact same verb_noun pattern: list_customers and read_customer. The naming is perfectly consistent and predictable.
With only two tools, the server feels thin, especially given the name 'Security Gateway' which implies a broader scope. However, the two tools cover a minimal read-only customer lookup workflow, so it is borderline but not extreme.
The server provides only read operations (list and get) with no create, update, or delete capabilities. For a customer-focused toolset, this is a notable gap unless the server is intentionally read-only. The mismatch between the server name and the tool domain further obscures expected completeness.