zentinelproxy/zentinel-agent-auth
GitHub: zentinelproxy/zentinel-agent-auth
Zentinel 反向代理的身份验证与授权代理,支持 JWT、OIDC、SAML SSO、mTLS 等多种认证协议与 Cedar 策略引擎。
Stars: 2 | Forks: 0
# zentinel-agent-auth
[Zentinel](https://github.com/zentinelproxy/zentinel) 反向代理的身份验证与授权 agent。支持 JWT/Bearer token、OIDC/OAuth 2.0、API 密钥、Basic 认证、SAML SSO、mTLS 客户端证书以及 SCIM 2.0 用户配置。
## 功能
### 身份验证
- **JWT/Bearer token** - HS256、RS256、ES256 及其他算法
- **OIDC/OAuth 2.0** - 带有自动 JWKS 密钥轮换的 OpenID Connect
- **API 密钥** - 简单的基于 header 的身份验证
- **Basic 认证** - 用户名/密码身份验证
- **SAML SSO** - 具有会话持久性的企业级单点登录
- **mTLS 客户端证书** - 基于 X.509 证书的身份验证
### 授权
- **Cedar 策略引擎** - 基础的策略即代码 授权(principal、action、resource 评估)
### Token 服务
- **Token 交换 (RFC 8693)** - 在不同 token 类型之间转换(SAML 到 JWT,外部到内部 JWT)
### 配置
- **SCIM 2.0 (RFC 7644)** - 从 IdP(Keycloak、Kanidm、Okta、Azure AD)进行动态用户配置
### 常规
- 可配置的用户 ID 和身份验证方法 header
- 用于优雅降级的 fail-open 模式
- 全面的审计日志
## 文档
- [配置参考](docs/configuration.md) - 完整的配置选项
- [SAML 认证](docs/saml.md) - SAML SSO 设置与 IdP 集成
- [会话管理](docs/session-management.md) - 会话持久性与生命周期
- [OIDC 认证](docs/oidc.md) - 带有 JWKS 的 OIDC/OAuth 2.0
- [mTLS 认证](docs/mtls.md) - 客户端证书身份验证
- [授权](docs/authorization.md) - Cedar 策略引擎指南
- [Token 交换](docs/token-exchange.md) - RFC 8693 token 交换
- [SCIM 配置](docs/scim.md) - SCIM 2.0 用户配置
## 安装
### 从 crates.io
```
cargo install zentinel-agent-auth
```
### 从源码
```
git clone https://github.com/zentinelproxy/zentinel-agent-auth
cd zentinel-agent-auth
cargo build --release
```
## 用法
```
zentinel-auth-agent --socket /var/run/zentinel/auth.sock \
--jwt-secret "your-secret-key" \
--api-keys "key1:app1,key2:app2"
```
### 命令行选项
| 选项 | 环境变量 | 描述 | 默认值 |
|--------|---------------------|-------------|---------|
| `--socket` | `AGENT_SOCKET` | Unix socket 路径 | `/tmp/zentinel-auth.sock` |
| `--jwt-secret` | `JWT_SECRET` | JWT 密钥(用于 HS256) | - |
| `--jwt-public-key` | `JWT_PUBLIC_KEY` | JWT 公钥文件(用于 RS/ES) | - |
| `--jwt-algorithm` | `JWT_ALGORITHM` | JWT 算法 | `HS256` |
| `--jwt-issuer` | `JWT_ISSUER` | 必需的 JWT 签发者 | - |
| `--jwt-audience` | `JWT_AUDIENCE` | 必需的 JWT 受众 | - |
| `--api-keys` | `API_KEYS` | API 密钥 (key:name,key:name) | - |
| `--api-key-header` | `API_KEY_HEADER` | API 密钥 header 名称 | `X-API-Key` |
| `--basic-auth-users` | `BASIC_AUTH_USERS` | Basic 认证用户 (user:pass) | - |
| `--user-id-header` | `USER_ID_HEADER` | 用户 ID 的 header | `X-User-Id` |
| `--auth-method-header` | `AUTH_METHOD_HEADER` | 身份验证方法的 header | `X-Auth-Method` |
| `--fail-open` | `FAIL_OPEN` | 在身份验证失败时允许通过 | `false` |
| `--verbose` | `AUTH_VERBOSE` | 启用调试日志 | `false` |
有关 OIDC、mTLS、Cedar 授权、token 交换和 SCIM 配置选项,请参见[配置参考](docs/configuration.md)。
## 身份验证方法
### JWT/Bearer Token
```
# 使用 HS256 secret 配置
zentinel-auth-agent --jwt-secret "your-32-char-minimum-secret-key"
# 使用 RS256 public key 配置
zentinel-auth-agent --jwt-algorithm RS256 --jwt-public-key /path/to/public.pem
# 带有 issuer 和 audience 验证
zentinel-auth-agent \
--jwt-secret "secret" \
--jwt-issuer "https://auth.example.com" \
--jwt-audience "my-api"
```
客户端请求:
```
curl -H "Authorization: Bearer eyJ..." http://localhost:8080/api
```
### API 密钥
```
# 配置 API keys
zentinel-auth-agent --api-keys "sk_live_abc123:production,sk_test_xyz:development"
```
客户端请求:
```
curl -H "X-API-Key: sk_live_abc123" http://localhost:8080/api
```
### Basic 认证
```
# 配置 users
zentinel-auth-agent --basic-auth-users "admin:secretpass,user:userpass"
```
客户端请求:
```
curl -u "admin:secretpass" http://localhost:8080/api
```
### OIDC/OAuth 2.0
配置带有自动 JWKS 密钥获取和刷新的 OIDC:
```
config {
oidc {
enabled #true
issuer "https://auth.example.com"
jwks-url "https://auth.example.com/.well-known/jwks.json"
audience "my-api"
required-scopes "read,write"
}
}
```
客户端请求:
```
curl -H "Authorization: Bearer " http://localhost:8080/api
```
### mTLS 客户端证书
使用 X.509 证书对客户端进行身份验证(需要 Zentinel 代理转发客户端证书):
```
config {
mtls {
enabled #true
client-cert-header "X-Client-Cert"
allowed-dns "CN=service.example.com,O=Example"
extract-cn-as-user #true
}
}
```
Zentinel 代理在 TLS 终止后通过 header 转发客户端证书。
## 授权
身份验证通过后,可以使用 Cedar 策略对请求进行授权:
```
config {
authz {
enabled #true
policy-file "/etc/zentinel/policies/auth.cedar"
default-decision "deny"
}
}
```
Cedar 策略示例:
```
permit(
principal,
action == Action::"GET",
resource
) when {
resource.path like "/api/public/*"
};
permit(
principal,
action,
resource
) when {
principal.roles.contains("admin")
};
```
有关更多详细信息,请参见[授权指南](docs/authorization.md)。
## 添加的 Header
身份验证成功后,agent 会将以下 header 添加到请求中:
| Header | 描述 | 示例 |
|--------|-------------|---------|
| `X-User-Id` | 已验证的用户 ID | `user123` |
| `X-Auth-Method` | 使用的身份验证方法 | `jwt`, `oidc`, `mtls`, `api_key`, `basic`, `saml` |
| `X-Auth-Claim-*` | JWT/OIDC 声明(用于 token 认证) | `X-Auth-Claim-role: admin` |
| `X-Client-Cert-*` | 证书信息(用于 mTLS) | `X-Client-Cert-CN: service.example.com` |
## 配置
### Zentinel 代理配置
```
agents {
agent "auth" {
type "custom"
transport "unix_socket" {
path "/var/run/zentinel/auth.sock"
}
events "request_headers"
timeout-ms 50
failure-mode "open"
}
}
routes {
route "api" {
matches {
path-prefix "/api"
}
upstream "backend"
agents "auth"
}
}
```
### Docker/Kubernetes
```
# Environment variables
JWT_SECRET: "your-secret-key"
JWT_ISSUER: "https://auth.example.com"
API_KEYS: "key1:app1,key2:app2"
FAIL_OPEN: "false"
```
## 响应码
| 代码 | 描述 |
|------|-------------|
| 401 | 未提供有效的凭证 |
| (透传) | 凭证有效,请求已转发 |
agent 会在 401 响应中添加 `WWW-Authenticate: Bearer realm="zentinel"` header。
## 开发
```
# 以 debug logging 运行
RUST_LOG=debug cargo run -- \
--socket /tmp/test.sock \
--jwt-secret "test-secret-at-least-32-characters" \
--api-keys "test-key:test-app"
# 运行 tests
cargo test
```
## 安全注意事项
- **对于 JWT,优先使用 RS256/ES256 而非 HS256** — HS256 使用共享密钥(签名者和验证者都必须知道它)。在生产环境中使用非对称算法(RS256、ES256)以避免跨服务共享密钥。
- 始终使用强随机的 JWT 密钥(对于 HS256 至少 32 个字符)
- 将密钥存储在环境变量中,而不是命令行参数中
- 生产环境中尽可能使用带有公钥的 RS256/ES256
- 谨慎启用 `fail_open` - 仅用于非关键路径
- 考虑在身份验证的同时进行速率限制
## 许可证
Apache-2.0
标签:JWT, OIDC, Rust, 反向代理, 可视化界面, 授权, 网络流量审计, 通知系统, 零信任网络