Jesseman-418/zero-trust-api-gateway
GitHub: Jesseman-418/zero-trust-api-gateway
一个实现零信任架构的 API 网关,整合认证、授权、速率限制与防篡改审计以保障 API 安全。
Stars: 0 | Forks: 0
# 零信任 API 网关
一个生产级别的反向代理,实现了**零信任安全架构**,包含 JWT/JWKS 认证、双策略引擎(RBAC + ABAC)、按身份速率限制和防篡改审计日志。
旨在展示对身份感知访问控制、API 安全模式以及支撑现代身份平台(如 Okta)的原则的深入理解。
## 架构
```
ZERO-TRUST API GATEWAY
Client Request Policy Decision Point
─────────────┐ ┌──────────────────────┐
│ │ │
▼ │ ┌──────────────┐ │
┌─────────────────────┐ │ │ RBAC Engine │ │
│ Security Headers │ │ │ (roles.json) │ │
│ Body Size Limit │ │ └──────┬───────┘ │
│ Request ID │ │ │ │
└──────────┬──────────┘ │ ┌──────▼───────┐ │
│ │ │ ABAC Engine │ │
┌──────────▼──────────┐ │ │ (abac.json) │ │
│ Metrics Collector │ │ └──────┬─────���─┘ │
│ Audit Logger │ │ │ │
└──────────┬──────────┘ │ ┌──────▼───────┐ │
│ │ │ Combined │ │
┌──────────▼─���────────┐ │ │ Decision │ │
│ Route Resolution │────────▶│ │ (deny wins) │ │
│ IP Allow/Deny │ │ └──────────────┘ │
└─────────��┬──────────┘ └──────────────────────┘
│ │
┌───���──────▼──────────┐ │
│ mTLS Validation │ │
│ (if configured) │ │
└──────────┬──────────┘ │
│ │
┌──────────▼──────────┐ ┌──────────▼──────────┐
│ JWT Authentication│ │ Authorization │
│ ┌───────────────┐ │ │ (Policy Engine) │
│ │ JWKS Fetch + │ │ └──────────┬────���─────┘
│ │ Key Cache │ │ │
│ └───────────────┘ │ ┌──────────▼─��────────┐
│ ┌───────────────┐ │ │ Per-Identity Rate │
│ │ Token │ │ │ Limiter (sliding │
│ │ Introspection │ │ │ window by `sub`) │
│ │ (RFC 7662) │ │ └──────────┬─────────��┘
│ └───────────────┘ │ │
│ ┌────��──────────┐ │ ┌──────────▼──��───────┐
│ │ HMAC Verify │ │ │ Reverse Proxy │
│ │ (optional) │ │ │ ┌───────────────┐ │
│ └───────────────┘ │ │ │ Circuit │ │
└──────────┬──────────┘ ��� │ Breaker │ │
│ │ └───────────────┘ │
└─────────────────────│ ┌───────────────┐ │
│ │ Health Check │ │
│ └───────────────┘ │
└─���────────┬──────────┘
│
▼
┌─────────────────────┐
│ Upstream Service │
│ (port 4001) │
└──��──────────────────┘
```
### 请求管线
每个请求都经过完整管线——**没有捷径,没有旁路**。这是零信任的核心原则:**永不信任,始终验证**。
```
Request → Security Headers → Metrics → Audit → Route Resolution → IP Filter
→ mTLS → JWT Auth → JWKS Verify → Introspection → HMAC Verify
→ RBAC Check → ABAC Check → Rate Limit → Proxy → Upstream
```
## 这展示了什么
### 零信任原则
- **显式验证**——每个请求都通过 JWT/JWKS 进行身份验证,无论网络来源
- **最小权限**——RBAC 确保身份仅能访问其角色所允许的内容
- **假设已受侵害**——ABAC 策略强制执行环境约束(时间、IP、MFA)作为纵深防御
- **持续验证**——令牌自省(RFC 7662)可实时检测吊销的令牌
### 身份与访问管理概念
- **JWKS 密钥轮换**——自动获取公钥并支持缓存与轮换
- **基于声明的身份**——角色从 JWT 声明(`roles`、`groups`、Okta/Auth0 格式)中提取
- **策略即代码**——声明式 JSON 策略,无需重启即可热重载
- **关注点分离**——身份认证(你是谁?)与授权(你能做什么?)
### 安全工程
- **防篡改审计链**——SHA-256 链式哈希(区块链风格)保障日志完整性
- **按身份速率限制**——基于 `sub` 声明而非 IP(防止跨身份节流)
- **断路器模式**——上游健康监测与自动故障转移
- **纵深防御**——mTLS + JWT + RBAC + ABAC + IP 过滤 + HMAC + 安全头
## 快速开始
### 先决条件
- Node.js 18+
- npm
### 设置
```
# 克隆并安装
cd zero-trust-gateway
npm install
# 复制环境配置
cp .env.example .env
# 默认 .env 在本地测试中使用 DEMO_MODE=true
```
### 运行演示
终端 1 —— 启动模拟上游 API:
```
npm run demo:upstream
# → 模拟上游 API 运行在 http://localhost:4001
```
终端 2 —— 启动网关:
```
npm start
# → 零信任 API 网关运行在 http://localhost:3002
```
终端 3 —— 运行测试客户端:
```
npm run demo:client
```
### 演示展示内容
测试客户端发送带有不同身份令牌的请求:
| 场景 | 令牌 | 预期结果 |
|------|------|----------|
| 公开路由无认证 | 无 | 200 OK |
| 缺少令牌 | 无 | 401 未授权 |
| 已过期令牌 | 过期 JWT | 401 令牌已过期 |
| Viewer 读取用户 | `roles: [viewer]` | 200 OK |
| Viewer 尝试写入 | `roles: [viewer]` | 403 禁止 |
| 用户写入 | `roles: [user]` | 200 OK |
| 用户尝试删除 | `roles: [user]` | 403 禁止 |
| 管理员删除 | `roles: [admin]` | 200 OK |
| 非管理员访问 /admin | `roles: [user]` | 403 禁止 |
### 仪表板
打开 `http://localhost:3002/gateway/dashboard` 查看实时监控仪表板,展示:
- 请求量与吞吐量
- 延迟百分位数(p50、p95、p99)
- 按类别划分的错误分布
- 上游健康状态与断路器状态
- 审计链完整性验证
- 按身份速率限制状态
## 策略引擎
### RBAC(基于角色的访问控制)
定义在 `policies/rbac.json`。将角色映射到权限,并将路由映射到所需权限。
```
{
"roles": {
"admin": { "permissions": ["read", "write", "delete", "admin"] },
"user": { "permissions": ["read", "write"] },
"viewer": { "permissions": ["read"] }
},
"routes": {
"/api/users": {
"GET": ["read"],
"POST": ["write"],
"DELETE": ["admin"]
},
"/api/admin/*": { "*": ["admin"] }
}
}
```
**工作原理**:网关从 JWT 的 `roles` 或 `groups` 声明提取角色,解析这些角色的权限,然后检查身份是否拥有该路由与 HTTP 方法所需权限中的任意一项。
### ABAC(基于属性的访问控制)
定义在 `policies/abac.json`。在请求时评估环境条件。
```
{
"policies": [
{
"name": "business-hours-only",
"effect": "deny",
"condition": { "time.hour": { "notBetween": [9, 17] } },
"resources": ["/api/admin/*"]
}
]
}
```
**支持的属性:**
| 属性 | 描述 |
|------|------|
| `time.hour` | 当前 UTC 小时(0-23) |
| `time.dayOfWeek` | 星期几(0=星期日) |
| `request.ip` | 客户端 IP 地址 |
| `request.method` | HTTP 方法 |
| `token.amr` | 认证方法(来自 JWT) |
| `token.sub` | 主体标识符 |
| `token.scope` | OAuth 作用域 |
**支持的操作符:**
`equals`、`notEquals`、`in`、`notIn`、`between`、`notBetween`、`contains`、`notContains`、`inCIDR`、`notInCIDR`、`matches`(正则)、`greaterThan`、`lessThan`
### 组合评估
策略引擎使用**拒绝优先组合**:RBAC 与 ABAC 必须同时允许访问。即使是管理员,若 ABAC 条件不满足(例如在非工作时间访问管理路由)也会被拒绝。
### 热重载
无需重启网关即可重载策略:
```
curl -X POST http://localhost:3002/gateway/policies/reload
```
## API 端点
### 网关管理(无需认证)
| 端点 | 描述 |
|------|------|
| `GET /gateway/health` | 包含上游状态的健康检查 |
| `GET /gateway/metrics` | 请求计数、延迟百分位数、错误率 |
| `GET /gateway/audit` | 审计日志条目及链完整性检查 |
| `GET /gateway/ratelimit` | 按身份速率限制状态 |
| `POST /gateway/policies/reload` | 热重载所有策略 |
| `GET /gateway/dashboard` | 实时监控仪表板 |
### 代理路由(默认需认证)
所有其他路由在通过完整安全管线后,会被代理到配置的 upstream。
## 安全模型
### 认证层
1. **JWT 验证**——基于 JWKS 的签名验证,带密钥缓存与自动轮换
2. **令牌自省**——RFC 7662 实时令牌验证,用于检查吊销
3. **HMAC 请求签名**——通过 `X-Request-Signature` 头进行可选的请求完整性验证
### 授权层
4. **RBAC**——带通配符路由支持的角色-权限映射
5. **ABAC**——环境策略评估(时间、IP、声明、方法)
### 传输层
6. **mTLS**——服务间双向 TLS(可按路由配置)
7. **安全头**——HSTS、CSP、X-Content-Type-Options、X-Frame-Options、Referrer-Policy、Permissions-Policy
### 运营层
8. **按身份速率限制**——基于 JWT `sub` 声明的滑动窗口
9. **IP 允许/拒绝列表**——按路由的网络限制
10. **请求体大小限制**——防止过大负载
11. **断路器**——上游健康监测与自动故障转移
### 审计层
12. **防篡改日志**——SHA-256 链式哈希(每个条目包含前一个条目的哈希)
13. **链验证**——可随时验证日志完整性的 API 端点
## 插件架构
通过自定义中间件扩展网关。插件从 `src/plugins/` 自动发现。
```
// src/plugins/my-plugin.js
module.exports = {
name: 'my-plugin',
version: '1.0.0',
phase: 'pre-proxy', // pre-auth | post-auth | pre-proxy | post-proxy
init(app, config) {
// One-time setup
},
middleware() {
return (req, res, next) => {
// Custom logic
next();
};
},
};
```
## 测试
```
npm test
```
运行集成测试,涵盖:
- 认证管线(有效/无效/过期令牌)
- RBAC 强制执行(角色-权限检查)
- 安全头
- 速率限制
- 审计链完整性
- 带身份头的代理转发
- 策略热重载
## 生产部署
生产使用时,请更新 `.env`:
```
DEMO_MODE=false
JWKS_URI=https://your-okta-domain.okta.com/oauth2/default/v1/keys
JWT_ISSUER=https://your-okta-domain.okta.com/oauth2/default
JWT_AUDIENCE=api://default
INTROSPECTION_ENDPOINT=https://your-okta-domain.okta.com/oauth2/default/v1/introspect
MTLS_ENABLED=true
```
该网关设计用于部署在任何微服务之前,在网络边缘强制执行身份验证与访问策略——这正是 Okta 身份平台在企业架构中实现的方式。
## 技术栈
| 组件 | 技术 |
|------||
| 运行时 | Node.js 18+ |
| 框架 | Express |
| 代理 | http-proxy |
| JWT | jsonwebtoken + jwks-rsa |
| 哈希 | Node.js crypto (SHA-256) |
| 速率限制 | 内存滑动窗口(Map) |
| 指标 | 内存计数器 + 百分位计算 |
| 审计 | JSONL 文件 + 链式哈希 |
## 许可证
MIT
标签:ABAC, API安全, API安全模式, API网关, JSONLines, JSON输出, JWKS, JWT, MITM代理, Okta, RBAC, 不可篡改日志, 云端原生安全, 企业安全, 反向代理, 基于属性的访问控制, 基于角色的访问控制, 安全头, 安全架构, 审计日志, 指标收集, 授权策略, 每身份限流, 生产级网关, 细粒度权限, 网络资产管理, 自定义脚本, 访问控制策略, 请求ID, 请求体大小限制, 身份平台, 身份感知访问控制, 零信任