lenoshz/zero-trust-identity-lab
GitHub: lenoshz/zero-trust-identity-lab
一套基于 Docker Compose 一键部署的企业级零信任 IAM 实验平台,集成了 Keycloak SSO、OpenBao 密钥管理、ELK SIEM 和 JML 生命周期工作流,用于学习和演示零信任身份安全架构。
Stars: 0 | Forks: 0
# 🔐 零信任身份与 IAM 工作流实验
[](LICENSE)
[](https://docs.docker.com/compose/)
[](https://www.keycloak.org/)
[](https://openbao.org/)
## 📺 视频演示
**[在 YouTube 上观看完整演示](https://youtu.be/CBMsW2FbgQk)**
*展示完整的 JML 生命周期、OpenBao 密钥注入以及 Elastic SIEM 事件路由的实际运行情况。*
## 概述
一个类似生产环境的**零信任身份与访问管理 (IAM)** 平台,使用 **Keycloak SSO** (OpenID Connect)、**OpenBao** 密钥管理、带有 TLS 的 **Nginx** 反向代理以及 **ELK Stack** SIEM 集成来演示企业 IAM 工作流。具有完整的**入职/调岗/离职 (JML) 生命周期引擎**、**访问权限审查认证工作流**、**MFA 强制执行**、**SIEM 证据面板**和**影响指标仪表盘**。
每一项设计决策都遵循零信任原则:**永不信任,始终验证**。
本项目是一个完全容器化的单命令部署方案,它镜像了企业环境中使用的身份安全堆栈——作为展示实际 IAM 工程技能的作品集而构建。
## 架构

## IAM 用例场景
本实验室模拟了企业身份与访问管理在实践中的运作方式。以下是其与现实世界的对应关系:
| 实验室功能 | 企业级等效方案 | 现实世界服务 |
|---|---|---|
| **Joiner(入职)工作流** | 新员工入职 | Azure AD / Okta 用户配置 |
| **Mover(调岗)工作流** | 内部调动 / 角色重新计算 | SailPoint IdentityNow 生命周期事件 |
| **Leaver(离职)工作流** | 离职流程 / 访问权限撤销 | ServiceNow ITSM + SCIM 取消配置 |
| **访问权限审查** | 定期访问权限认证活动 | SailPoint Access Certifications,Azure AD Access Reviews |
| **MFA 强制执行** | 针对特权操作的逐步认证 | Okta Adaptive MFA,Azure Conditional Access |
| **SIEM 集成** | 身份威胁检测与审计追踪 | Splunk,Microsoft Sentinel,Elastic SIEM |
| **KPI 指标** | IAM 项目健康状况与运营指标 | 身份治理仪表盘 |
| **基于 Keycloak 的 RBAC** | 集中化角色管理 | Azure AD Roles,Okta Groups,CyberArk |
| **来自 OpenBao 的密钥** | 运行时密钥管理 | HashiCorp Vault,AWS Secrets Manager |
### JML 生命周期流程
```
Joiner Mover Leaver
┌─────────┐ ┌───────────┐ ┌──────────┐
│ Create │ │ Transfer │ │ Disable │
│ user │ │ department│ │ user │
│ profile │ │ │ │ account │
└────┬────┘ └─────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌───────────┐ ┌──────────┐
│ Auto- │ │ Recompute │ │ Revoke │
│ assign │ │ role from │ │ all │
│ baseline│ │ dept map │ │ roles │
│ role │ │ │ │ │
└────┬────┘ └─────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌───────────┐ ┌──────────┐
│ Log JML │ │ Log JML │ │ Log JML │
│ event + │ │ event + │ │ event + │
│ SIEM │ │ SIEM │ │ SIEM │
└─────────┘ └───────────┘ └──────────┘
```
## RBAC + MFA 策略矩阵
| 路由 | 所需角色 | 需要 MFA | 回退方案 |
|---|---|---|---|
| `/app/` | 无(公开) | 否 | — |
| `/app/dashboard` | 已认证 | 否 | 重定向至登录页 |
| `/app/secrets` | `zero-trust-admin` 或 `zero-trust-user` | 否 | RBAC 拒绝访问 |
| `/app/admin` | `zero-trust-admin` | 是 | 要求 MFA 页面 |
| `/app/admin/iam/joiner` | `zero-trust-admin` | 是 | 要求 MFA 页面 |
| `/app/admin/iam/mover` | `zero-trust-admin` | 是 | 要求 MFA 页面 |
| `/app/admin/iam/leaver` | `zero-trust-admin` | 是 | 要求 MFA 页面 |
| `/app/admin/reviews` | `zero-trust-admin` | 是 | 要求 MFA 页面 |
| `/app/admin/reviews/decide` | `zero-trust-admin` | 是 | 要求 MFA 页面 |
| `/app/admin/reviews/export` | `zero-trust-admin` | 是 | 要求 MFA 页面 |
**MFA 强制执行模式:**
| 模式 | 环境变量 | 行为 |
|---|---|---|
| **演示(默认)** | `FLASK_ADMIN_MFA_STRICT=false` | 允许管理员操作但显示可见警告横幅;绕过行为记录至 SIEM |
| **严格** | `FLASK_ADMIN_MFA_STRICT=true` | 无 MFA 则阻止管理员操作;重定向至 MFA 设置页面 |
## 实现的零信任原则
| 原则 | 实现方式 |
|-----------|---------------|
| 🔍 **永不信任,始终验证** | 每个请求均通过 Keycloak OIDC token 进行身份验证 |
| 🔒 **最小权限** | RBAC 角色及限定范围的 OpenBao 策略 (`flask-app-policy`) |
| ⏱️ **短期 Token** | Access token:5 分钟 · 会话:最长 1 小时 |
| 🔑 **密钥永不硬编码** | 所有密钥均在运行时从 OpenBao KV 引擎获取 |
| 📊 **所有访问均被记录** | Keycloak 事件 + Nginx 日志 + SIEM 事件均发送至 ELK |
| 🛡️ **全局 TLS** | Nginx 强制使用带有 HSTS、CSP 和安全头的 HTTPS |
| 🔐 **强制执行 MFA** | 对管理员操作强制执行 TOTP/OTP,具有可配置的严格性 |
| 🌐 **网络隔离** | Docker 网络分离身份和监控流量 |
| 👤 **身份生命周期** | JML 工作流管理用户入职、调动和离职 |
| ✅ **访问认证** | 具有批准/撤销及审计追踪的定期访问审查 |
## 技术栈
| 组件 | 技术 | 版本 | 用途 |
|-----------|-----------|---------|---------|
| 身份提供者 | Keycloak | 24.0.4 | SSO,OIDC,RBAC,MFA |
| 密钥引擎 | OpenBao | 2.0.0 | KV 密钥管理 |
| 反向代理 | Nginx | 1.25-alpine | TLS 终结,安全头 |
| 演示应用 | Flask (Python) | 3.0.3 | 受 OIDC 保护的 Web 应用及 IAM 工作流 |
| IAM 数据存储 | SQLite | 3.x | JML 记录、访问审查、SIEM 事件 |
| 数据库 | PostgreSQL | 16-alpine | Keycloak 持久化存储 |
| 搜索引擎 | Elasticsearch | 8.13.4 | 日志存储与分析 |
| 仪表盘 | Kibana | 8.13.4 | SIEM 可视化 |
| 日志传送器 | Filebeat | 8.13.4 | 日志收集与转发 |
| 编排工具 | Docker Compose | v2 | 容器编排 |
## 快速开始
### 前置条件
- [Docker](https://docs.docker.com/get-docker/) (20.10+)
- [Docker Compose](https://docs.docker.com/compose/install/) v2
- OpenSSL(用于证书生成)
- 推荐至少 8GB 内存(Elasticsearch 约需 512MB)
### 部署
```
# Clone repository
git clone https://github.com/lenoshz/zero-trust-identity-lab.git
cd zero-trust-identity-lab
# Make scripts executable
chmod +x scripts/bootstrap.sh
# 使用单条命令 Deploy 所有内容
./scripts/bootstrap.sh
```
### 手动设置(如果不使用 bootstrap.sh)
```
# 1. Generate TLS 证书
chmod +x nginx/ssl/generate-certs.sh
./nginx/ssl/generate-certs.sh
# 2. 启动所有 services
docker compose up -d
# 3. 等待 services healthy(约 90 秒)
docker compose ps
# 4. Seed OpenBao secrets
chmod +x openbao/init/setup.sh
./openbao/init/setup.sh
# 5. Check health
chmod +x scripts/healthcheck.sh
./scripts/healthcheck.sh
```
## 服务 URL
| 服务 | URL | 凭据 |
|---------|-----|-------------|
| 🌐 演示应用 | `https://localhost/app` | 见下方演示用户 |
| 🔐 Keycloak 登录 | `https://localhost/auth` | 见下方演示用户 |
| ⚙️ Keycloak 管理控制台 | `https://localhost/auth/admin` | `admin` / `Admin@ZeroTrust1` |
| 📊 Kibana SIEM | `https://localhost/kibana` | `elastic` / `Elastic@ZeroTrust1` |
| 🔑 OpenBao UI | `http://localhost:8200` | Token:`root-dev-token-zerotrust` |
### 演示用户
| 用户名 | 密码 | 角色 | 访问级别 |
|----------|----------|------|-------------|
| `ztadmin` | `Admin@123` | `zero-trust-admin` | 完整的管理员访问权限 + IAM 工作流 |
| `ztuser` | `User@123` | `zero-trust-user` | 标准读/写访问权限 |
| `ztviewer` | `View@123` | `zero-trust-readonly` | 只读访问权限 |
## 演示演示流程
### 1. 通过 Keycloak OIDC 认证
导航至 `https://localhost/app` 并点击 **"Authenticate with Keycloak"**。您将被重定向至 Keycloak 登录页面。
### 2. 以管理员身份登录
使用 `ztadmin` 用户名和 `Admin@123` 密码登录。Keycloak 会发放一个短期 JWT access token(5 分钟 TTL)并将您重定向回 Flask 应用。
### 3. 查看身份仪表盘
仪表盘显示:
- **KPI 指标**:入职时间、离职完成度、特权账户、MFA 覆盖率、带有趋势箭头的审查完成度
- 您已认证的用户名、电子邮件和角色分配
- 带有实时状态芯片的 Token 过期倒计时
- OpenBao 连接状态
- **审计日志**:会话范围内的事件
- **实时健康状况**:每个服务的响应码和延迟
- **安全事件 (SIEM)**:带有过滤器芯片和 Kibana 深度链接的持久安全事件时间线
### 4. 管理用户生命周期 (JML)
- **Joiner(入职)** (`/app/admin/iam/joiner`):创建新用户 → 根据部门自动分配基准角色
- **Mover(调岗)** (`/app/admin/iam/mover`):将用户转移到新部门 → 自动重新计算角色
- **Leaver(离职)** (`/app/admin/iam/leaver`):禁用用户 → 撤销所有角色,使会话失效
### 5. 进行访问审查
导航至 `/app/admin/reviews`:
- 审查每个用户的角色分配并附上风险级别标签(低 / 中 / 高 / 严重)
- 一键批准角色分配
- 撤销高级访问权限时需提供强制性理由评论
- 将所有审查决定导出为 CSV 以作合规证据
### 6. 查看来自 OpenBao 的密钥
导航至 `/app/secrets` 查看从 OpenBao 的 KV v2 引擎实时获取的应用程序密钥。所有值均已屏蔽——源代码中绝不暴露。
### 7. 生成 SIEM 事件
- **登录失败**:尝试使用错误密码登录 — Keycloak 记录 `LOGIN_ERROR`
- **管理员操作**:访问管理面板 — 记录为 `admin_action`
- **JML 事件**:创建/调岗/禁用用户 — 记录完整审计细节
- **访问审查**:批准或撤销 — 记录为 `review_decision`
- **MFA 绕过**:在演示模式下访问管理功能 — 记录为 `mfa_bypass`
所有事件均可在仪表盘的“安全事件”面板中查看,并通过 Filebeat 流向 ELK。
### 8. 查看 Kibana 仪表盘
导航至 `https://localhost/kibana` 并探索 `zerotrust-logs-*` 索引模式以查看实时身份事件。使用仪表盘上的“Open in Kibana”按钮可获取预过滤的查询。
## JML + 访问审查测试场景
### Joiner(入职)测试
```
1. Log in as ztadmin
2. Navigate to /app/admin/iam/joiner
3. Create user: username=testuser1, email=test@co.com, name=Test User, dept=Engineering
4. Verify: success message shown, role auto-assigned = zero-trust-user
5. Verify: user appears in Recent Joiners table
6. Verify: security event logged in SIEM panel
```
### Mover(调岗)测试
```
1. Navigate to /app/admin/iam/mover
2. Select testuser1 → see current: Engineering / zero-trust-user
3. Change to department: Security
4. Verify: transfer preview shows Engineering→Security, role→zero-trust-admin
5. Submit → verify success, role recomputed
6. Verify: movement history updated
```
### Leaver(离职)测试
```
1. Navigate to /app/admin/iam/leaver
2. Select testuser1
3. Review revocation checklist → confirm disable
4. Verify: user disabled, roles revoked
5. Verify: user appears in Disabled Users table
6. Verify: user no longer in Mover/Joiner active user lists
```
### 访问审查测试
```
1. Navigate to /app/admin/reviews
2. Review ztadmin → Risk Level = CRITICAL → Approve
3. Review ztuser → Risk Level = MEDIUM → Revoke with reason: "Access no longer needed"
4. Verify: review history updated with decision + reviewer + timestamp
5. Click Export CSV → verify downloaded file contains decisions
6. Verify: review completion percentage updates
```
### MFA 强制执行测试
```
# Demo 模式(默认):
1. Log in as ztadmin → access /app/admin
2. Verify: yellow "MFA Not Verified" warning banner shown
3. Verify: admin actions still functional
4. Verify: mfa_bypass event logged in security events
# Strict 模式:
1. Set FLASK_ADMIN_MFA_STRICT=true in .env
2. docker compose up -d flask-app
3. Access /app/admin → verify: redirected to MFA Required page
4. Verify: mfa_denied event in security events
```
## KPI 指标说明
| 指标 | 衡量内容 | 重要性 |
|---|---|---|
| **平均入职时间** | 从创建入职人员到分配角色的模拟时间 | 入职缓慢 = 安全盲区(无访问权限)或风险(仓促授权) |
| **离职完成率 %** | 已完全撤销所有角色的被禁用用户百分比 | 离职不完全 = 孤立账户 = 安全风险 |
| **特权账户** | 拥有 `zero-trust-admin` 角色的用户数量 | 过多的特权 = 扩大的攻击面 |
| **MFA 覆盖率 %** | 配置了 MFA 的活跃用户百分比(模拟) | MFA 比例低 = 凭据被盗风险 |
| **审查完成率 %** | 已完成访问审查的用户百分比 | 完成率低 = 过时的权限 = 合规盲区 |
### 趋势箭头
每个 KPI 都显示一个箭头 (↑/↓/→),将当前值与先前的快照进行比较:
- **绿色 ↑/↓**:改善(完成率更高,入职时间更短,特权账户更少)
- **红色 ↑/↓**:恶化
- **灰色 →**:无显著变化
## 系统图库
### 1. 零信任架构落地页

### 2. Keycloak OIDC 认证

### 3. 身份仪表盘与 KPI 指标

### 4. 通过 OpenBao 获取动态密钥

### 5. IAM 管理中心

### 6. Joiner 工作流(入职与自动配置)


### 7. Mover 工作流(角色重新计算)

### 8. Leaver 工作流(全部会话与访问权限撤销)

### 9. 访问审查治理


## 本项目如何映射到企业 IAM 服务
| 本实验室 | Azure AD / Entra ID | Okta | SailPoint |
|---|---|---|---|
| Keycloak OIDC SSO | Azure AD App Registration | Okta OIDC Integration | — |
| JML Joiner | 通过 SCIM 进行的 Azure AD 用户配置 | Okta 生命周期钩子 | IdentityNow Joiner Rule |
| JML Mover | Azure AD 动态组 | Okta 配置文件属性映射 | IdentityNow Mover Rule |
| JML Leaver | Azure AD 用户禁用 + 许可证撤销 | Okta 停用用户 | IdentityNow Leaver Rule |
| 访问审查 | Azure AD Access Reviews | Okta Access Certifications | Access Campaigns |
| MFA 强制执行 | Conditional Access + MFA 质询 | Adaptive MFA 策略 | — |
| 安全事件 | Azure AD Sign-in Logs + Sentinel | Okta System Log | Activity Monitoring |
| KPI 仪表盘 | Identity Governance Analytics | Okta Reports | IdentityNow Dashboards |
| OpenBao 密钥 | Azure Key Vault | Okta Credential Management | — |
| RBAC | Azure AD Roles + Privileged Identity Mgmt | Okta Groups + App Assignments | Entitlements |
## 项目结构
```
zero-trust-identity-lab/
├── docker-compose.yml # Full stack orchestration
├── .env # Environment secrets (gitignored)
├── .env.example # Template with placeholder values
├── README.md # This file
├── ARCHITECTURE.md # Detailed architecture documentation
├── nginx/
│ ├── nginx.conf # TLS reverse proxy configuration
│ └── ssl/
│ └── generate-certs.sh # Self-signed certificate generator
├── keycloak/
│ ├── realm-export.json # Pre-configured realm with users/roles
│ └── themes/ # Custom theme placeholder
├── openbao/
│ ├── config/openbao.hcl # Server configuration
│ └── init/setup.sh # Secret seeding script
├── flask-app/
│ ├── Dockerfile # Python 3.12 container image
│ ├── requirements.txt # Pinned Python dependencies
│ ├── app.py # OIDC + OpenBao + IAM workflows
│ ├── iam_store.py # SQLite IAM data layer
│ └── templates/
│ ├── index.html # Public landing page
│ ├── dashboard.html # Dashboard + SIEM + KPIs
│ ├── login_required.html # Auth/session failure page
│ ├── mfa_required.html # MFA enforcement page
│ ├── iam_joiner.html # JML Joiner workflow
│ ├── iam_mover.html # JML Mover workflow
│ ├── iam_leaver.html # JML Leaver workflow
│ └── access_reviews.html # Access review certifications
├── elk/
│ ├── elasticsearch/ # ES single-node config
│ ├── kibana/ # Kibana config with base path
│ └── filebeat/ # Log shipping configuration
├── scripts/
│ ├── bootstrap.sh # One-command deployment
│ ├── keycloak-configure.sh # Realm verification
│ └── healthcheck.sh # Service status checker
└── docs/
├── screenshots/ # UI screenshots (post-deployment)
├── zero-trust-flow.md # Authentication flow diagram
└── setup-guide.md # Detailed setup & Kibana guide
```
## 故障排除
有关详细的故障排除,请参阅 [docs/setup-guide.md](docs/setup-guide.md),包括:
- Docker 网络问题
- Keycloak 启动失败
- 证书问题
- Elasticsearch 堆内存问题
- OpenBao 连接错误
### Keycloak 客户端设置
如果遇到 OIDC 登录循环、回调失败或显示无效的重定向错误,请验证 Keycloak 中的 `flask-demo-app` 客户端:
- 客户端类型 / 访问类型:**Confidential**
- 客户端身份验证:**Enabled**
- 有效的重定向 URI:
- `https://localhost/app/callback`
- `https://localhost/app/*`
- `http://localhost:5000/callback`(可选的直接回退)
- Web origins:
- `https://localhost`
- `http://localhost:5000`(可选)
这些值必须与 `docker-compose.yml` 中 Flask 应用的 OIDC 环境变量相匹配。
### OIDC 诊断命令
```
docker compose logs --tail=200 flask-app
docker compose logs --tail=200 nginx
curl -kI https://localhost/auth/realms/zero-trust-realm/.well-known/openid-configuration
curl -kI https://localhost/app/
```
预期快速检查结果:
- Discovery endpoint 返回 `HTTP/1.1 200 OK`
- App endpoint 返回 `HTTP/1.1 200 OK`
- Flask 日志显示解析的 OIDC 设置和登录重定向 URI
- Nginx 日志显示 `/auth/` 和 `/app/` 请求且无上游解析崩溃
### Token 时序、RBAC 及审计验证
```
# 1) 验证在 login callback 后 session token 时间字段已填充
docker compose logs --tail=200 flask-app
# 2) 验证 app health endpoint 包含 live check 元数据
curl -k https://localhost/app/health
# 3) 验证 RBAC guards
# - /app/secrets 允许 zero-trust-admin 和 zero-trust-user
# - /app/admin 仅允许 zero-trust-admin
curl -kI https://localhost/app/secrets
curl -kI https://localhost/app/admin
# 4) 验证 IAM routes 存在(未认证时 302 redirects 到 login)
curl -kI https://localhost/app/admin/iam/joiner
curl -kI https://localhost/app/admin/iam/mover
curl -kI https://localhost/app/admin/iam/leaver
curl -kI https://localhost/app/admin/reviews
# 5) 验证使用来自 Flask container 的 app-scoped token 访问 OpenBao
docker compose exec -T flask-app python -c "import requests; tok=open('/run/secrets/openbao/flask-app-token','r',encoding='utf-8').read().strip(); base='http://openbao:8200/v1'; hdr={'X-Vault-Token':tok}; print('db',requests.get(f'{base}/secret/data/flask-app/db',headers=hdr,timeout=5).status_code); print('api',requests.get(f'{base}/secret/data/flask-app/api',headers=hdr,timeout=5).status_code); print('config',requests.get(f'{base}/secret/data/flask-app/config',headers=hdr,timeout=5).status_code)"
# 6) 验证 SQLite database 存在
docker compose exec flask-app ls -la /app/data/iam.db
```
### 快速修复
```
# 查看所有 container 日志
docker compose logs -f
# 重启特定 service
docker compose restart keycloak
# Full reset(警告:销毁所有数据)
docker compose down -v && docker compose up -d
# Check container health
docker compose ps
```
## 许可证
MIT 许可证 — 详见 [LICENSE](LICENSE)。
标签:Docker Compose, Elasticsearch, ELK Stack, IAM, IT安全, JML工作流, JSONLines, Keycloak, Logstash, MFA, Nginx, NIDS, OIDC, OpenBao, OpenID Connect, RBAC, SSO, Streamlit, StruQ, 企业级安全, 加入者/调动者/离职者, 动态机密, 单点登录, 反向代理, 后端开发, 基于角色的访问控制, 多因素认证, 大语言模型安全, 安全实验室, 安全工程, 定期访问审查, 实时身份威胁检测, 容器化, 机密管理, 测试用例, 版权保护, 访问控制, 越狱测试, 身份与访问管理, 身份安全, 身份生命周期管理, 逆向工具, 零信任