# JWT 认证系统 + ETCD 加密 - 完整部署总结

## 项目概览

这个项目为微服务提供了一个完整的 JWT 认证系统，包括：

1. **JWT 令牌管理** - 令牌生成、验证、刷新和撤销
2. **Redis Cluster 存储** - 令牌交换缓存（30天TTL）和用户会话管理
3. **RBAC 权限控制** - 限制只有 user-rpc 和 envoy-gateway 服务可以访问 JWT 秘钥
4. **ETCD 加密** - 在 Kubernetes 集群中对所有 Secrets 进行加密
5. **网关保护** - Envoy 网关处理 CSRF 防护和请求路由

## 创建的文件清单

### 部署配置文件

#### `/deploy/k8s/secrets/`

| 文件 | 说明 | 关键内容 |
|-----|------|--------|
| `jwt-secret.yaml` | Secret + RBAC 配置 | 包含JWT秘钥、ServiceAccounts、Role、RoleBindings |
| `README.md` | 快速参考指南 | Secret 创建和 Deployment 更新说明 |
| `DEPLOYMENT.md` | 详细部署步骤 | 12个部署步骤，包括ETCD加密配置 |
| `ENCRYPTION.md` | ETCD加密完整指南 | 密钥生成、配置修改、验证流程 |
| `VERIFICATION.md` | 验证清单 | 12个部分的完整验证脚本和检查项 |

### 应用代码更新

| 文件路径 | 修改内容 |
|---------|--------|
| `/app/users/rpc/internal/utils/jwt.go` | JwtManager 实现（已存在） |
| `/app/users/rpc/internal/config/config.go` | JwtConfig 结构体（已存在） |
| `/app/users/rpc/internal/svc/serviceContext.go` | Redis Cluster + JwtManager 依赖注入（已存在） |
| `/app/users/rpc/etc/pb.yaml` | JWT 和 Redis Cluster 配置（已存在） |
| `/deploy/k8s/service/user/user-rpc.yaml` | ✅ **已更新** - 添加 serviceAccountName + JWT_SECRET_KEY 环境变量 |
| `/deploy/k8s/envoy/envoy.yaml` | ✅ **已更新** - 添加 serviceAccountName: envoy-gateway |
| `/app/users/api/INTEGRATION.md` | 🆕 **新建** - JWT 集成指南（interceptors, handlers, middleware） |

## 部署状态示意图

```
┌─────────────────────────────────────────────────────────────────────┐
│                        Kubernetes Cluster                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                    juwan Namespace                          │   │
│  ├─────────────────────────────────────────────────────────────┤   │
│  │                                                              │   │
│  │  ┌────────────────────────────────────────────────────┐    │   │
│  │  │ Secret: jwt-secret                                │    │   │
│  │  │ ├─ secret-key: <encrypted in ETCD>               │    │   │
│  │  │ └─ Protected by RBAC Role + RoleBindings         │    │   │
│  │  └────────────────────────────────────────────────────┘    │   │
│  │                       △                                     │   │
│  │                       │ (mounted via serviceAccountName)   │   │
│  │                       │                                     │   │
│  │  ┌─────────────────┐   ┌──────────────────────┐           │   │
│  │  │   user-rpc      │   │  envoy-gateway       │           │   │
│  │  │  Deployment     │   │   Deployment         │           │   │
│  │  ├─────────────────┤   ├──────────────────────┤           │   │
│  │  │ SA: user-rpc    │   │ SA: envoy-gateway    │           │   │
│  │  │ Replicas: 3     │   │ Replicas: 1          │           │   │
│  │  │ Port: 9001(RPC) │   │ Port: 8080(HTTP)     │           │   │
│  │  │       4001(Met)  │   │                      │           │   │
│  │  └─────────────────┘   └──────────────────────┘           │   │
│  │         │ JWT Manager              │ CSRF Filter            │   │
│  │         │ (HS256 signing)          │ (X-CSRF-Token)         │   │
│  │         │                          │                        │   │
│  │  ┌──────▼──────────────────────────▼─────┐                │   │
│  │  │      user-redis (RedisCluster)        │                │   │
│  │  │      3-node cluster                   │                │   │
│  │  │      - Token exchange cache (30d TTL) │                │   │
│  │  │      - User session management        │                │   │
│  │  └────────────────────────────────────────┘                │   │
│  │                                                              │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                      │
│  ┌─────────────────────────────────────────────────────────────┐   │
│  │                  Control Plane (kube-apiserver)             │   │
│  │  • ETCD 加密: AES-CBC 32-byte key                          │   │
│  │  • Secrets 自动加密存储                                     │   │
│  └─────────────────────────────────────────────────────────────┘   │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
```

## 核心配置参数

### JWT 配置

```yaml
JWT:
  SecretKey: "your-secret-jwt-key-change-this-in-production"
  Issuer: "your-app-name"
  # Token 有效期: 7 天
  # Redis TTL: 30 天（支持令牌刷新）
```

### Redis Cluster

```yaml
RedisCluster:
  ClusterSize: 3 🔴 主服务器 + 2 🔵 从服务器
  Address: "user-redis.juwan:6379"
  HighAvailability: 自动故障转移
```

### RBAC 权限

```yaml
Role: jwt-secret-reader
Resources: [secrets]
ResourceNames: [jwt-secret]
Verbs: [get]           # 只读，无列表/创建/删除
Subjects:
  - user-rpc (ServiceAccount)
  - envoy-gateway (ServiceAccount)
```

## 部署流程

### 快速部署（5分钟）

```bash
# 第1步：创建 Secret 和 RBAC
kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml

# 第2步：更新 Deployments
kubectl apply -f deploy/k8s/service/user/user-rpc.yaml
kubectl apply -f deploy/k8s/envoy/envoy.yaml

# 第3步：验证
./verify-jwt-setup.sh
```

### ETCD 加密部署（需要集群管理员权限）

```bash
# 在 Control Plane 节点执行
1. 生成 32 字节密钥
2. 创建 /etc/kubernetes/encryption-config.yaml
3. 修改 /etc/kubernetes/manifests/kube-apiserver.yaml
4. 重启 kube-apiserver
5. 验证加密已启用
```

详见：`deploy/k8s/secrets/ENCRYPTION.md`

## 关键特性

### 1. JWT 令牌生命周期

```
登录 → 生成 JWT
      ├─ 有效期: 7 天（exp claim）
      └─ 存储到 Redis: 30 天（TTL）

Token 过期（7天+）
      ├─ JWT 签名验证失败
      └─ 检查 Redis 是否仍有数据
         ├─ 有 → 生成新 Token（刷新）✅
         └─ 无 → 令牌已过期，需要重新登录 ❌
```

### 2. Redis 双键结构

```
jwt:user:{userId} → {token}
  用途: 快速查询用户当前令牌
  TTL: 30 天

jwt:token:{token} → {payload}
  用途: 令牌验证和刷新
  TTL: 30 天
```

### 3. CSRF 防护（Envoy 网关）

```
安全方法 (GET/HEAD/OPTIONS)
  → 自动生成 csrf_token
  → 返回 Set-Cookie: csrf_token=...

不安全方法 (POST/PUT/DELETE/PATCH)
  → 检查 Cookie csrf_token
  → 检查 X-CSRF-Token 头
  → 两者必须相等，否则 403
```

### 4. 权限隔离

```
Only user-rpc + envoy-gateway 可以:
  ✅ 读 jwt-secret

Other services 无法:
  ❌ 列出 secrets
  ❌ 获取 jwt-secret（RBAC 拒绝）
  ❌ 删除 secrets
```

### 5. ETCD 加密

```
未加密:
  etcdctl get /registry/seca/...
  → secret-key: "plaintext-value"

已加密 (AES-CBC):
  etcdctl get /registry/secrets/...
  → 二进制数据，无法读取
```

## 集成点

### 1. RPC Handler（需要实现）

```go
// 在 gRPC server 中注册拦截器
s := grpc.NewServer(
  grpc.UnaryInterceptor(interceptor.JwtUnaryInterceptor(ctx)),
)

// 拦截器会:
// 1. 提取 Authorization 头中的 Token
// 2. 调用 JwtManager.Valid()
// 3. 如果过期，尝试 JwtManager.Renew()
// 4. 将声明注入 context
```

参考：`app/users/api/INTEGRATION.md` 第1-2章

### 2. REST Endpoint（需要实现）

```go
// 创建 JWT Middleware
protected := middleware.JwtMiddleware(svcCtx)

// 应用到受保护的路由
router.HandleFunc("GET /api/v1/users/me", 
  protected(user.GetUserInfoHandler(svcCtx)))

// Middleware 会验证 Authorization: Bearer {token}
```

参考：`app/users/api/INTEGRATION.md` 第3-4章

### 3. 登录/登出流程（需要实现）

```
登录:
  1. 验证用户凭证（DB 查询）
  2. JwtManager.New() → 生成令牌
  3. 返回令牌给客户端

登出:
  1. 从上下文提取 userId
  2. JwtManager.Revoke() → 删除 Redis 中的令牌
  3. 用户需要重新登录获取新令牌
```

参考：`app/users/api/INTEGRATION.md` 第5-6章

## 文档导航

| 场景 | 推荐阅读 |
|-----|--------|
| 第一次部署 | `README.md` → `DEPLOYMENT.md` |
| 部署遇到问题 | `VERIFICATION.md` + `DEPLOYMENT.md` 故障排查部分 |
| 代码集成 | `app/users/api/INTEGRATION.md` |
| ETCD 加密配置 | `ENCRYPTION.md` |
| ETCD 加密验证 | `VERIFICATION.md` 第9部分 |
| 安全最佳实践 | `DEPLOYMENT.md` 安全最佳实践部分 |
| 灾难恢复 | `DEPLOYMENT.md` 灾难恢复部分 |

## 生产就绪检查清单

- [ ] 所有 Pods 都在 Running 状态
- [ ] JWT Secret 已创建并正确挂载
- [ ] RBAC 权限验证通过
- [ ] Redis Cluster 健康（3/3 节点）
- [ ] ETCD 加密已启用（如需要）
- [ ] 监控和日志聚合正常工作
- [ ] 密钥轮换计划已制定
- [ ] 备份和恢复流程已文档化
- [ ] 安全审计日志已启用
- [ ] 端到端测试已通过

## 下一步行动

### 短期（本周）

1. **部署 Secret 和 RBAC**
   ```bash
   kubectl apply -f deploy/k8s/secrets/jwt-secret.yaml
   ```

2. **更新 Deployments**
   ```bash
   kubectl apply -f deploy/k8s/service/user/user-rpc.yaml
   kubectl apply -f deploy/k8s/envoy/envoy.yaml
   ```

3. **验证部署**
   ```bash
   ./verify-jwt-setup.sh
   ```

### 中期（本月）

1. **实现 JWT 集成**
   - 创建 gRPC 拦截器
   - 实现登录/登出端点
   - 添加 JWT 中间件到 REST API

2. **端到端测试**
   - 测试令牌生成和验证
   - 测试令牌刷新
   - 测试 CSRF 防护

### 长期（本季度）

1. **启用 ETCD 加密**
   - 按照 `ENCRYPTION.md` 配置
   - 验证所有 Secrets 都已加密

2. **生产部署**
   - 启用审计日志
   - 配置监控和告警
   - 制定密钥轮换政策

## 支持

如遇到问题：

1. **检查日志**
   ```bash
   kubectl logs -n juwan -l app=user-rpc -f
   kubectl logs -n juwan -l app=envoy-gateway -f
   ```

2. **运行验证脚本**
   ```bash
   chmod +x deploy/k8s/secrets/verify-jwt-setup.sh
   ./deploy/k8s/secrets/verify-jwt-setup.sh
   ```

3. **查看详细文档**
   - 部署问题 → `DEPLOYMENT.md`
   - 代码集成 → `INTEGRATION.md`
   - ETCD 加密 → `ENCRYPTION.md`
   - 诊断 → `VERIFICATION.md`

## 总结

这个系统为微服务提供了：

✅ **安全的身份验证** - JWT 令牌 + HS256 签名
✅ **灵活的令牌管理** - 7天有效期，30天可刷新
✅ **高可用性** - Redis Cluster 自动故障转移
✅ **权限隔离** - RBAC 限制密钥访问
✅ **数据加密** - ETCD 加密保护敏感信息
✅ **请求保护** - Envoy CSRF 双令牌验证

现在可以部署并集成到应用中了！
