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: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![Docker Compose](https://img.shields.io/badge/Docker%20Compose-v2-blue)](https://docs.docker.com/compose/) [![Keycloak](https://img.shields.io/badge/Keycloak-24.0.4-orange)](https://www.keycloak.org/) [![OpenBao](https://img.shields.io/badge/OpenBao-2.0.0-yellow)](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 工程技能的作品集而构建。 ## 架构 ![架构图](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/33e946c31d223249.svg) ## 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. 零信任架构落地页 ![落地页](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/ddd35e797c223251.png) ### 2. Keycloak OIDC 认证 ![Keycloak 登录](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/4eef3236d2223253.png) ### 3. 身份仪表盘与 KPI 指标 ![仪表盘](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/890a953276223254.png) ### 4. 通过 OpenBao 获取动态密钥 ![密钥页面](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/b24c6b9eb3223256.png) ### 5. IAM 管理中心 ![管理面板](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/eeac53e7c5223257.png) ### 6. Joiner 工作流(入职与自动配置) ![Joiner 表单](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/3e3ca42ab1223258.png) ![Joiner 成功](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/3fd0fe4538223300.png) ### 7. Mover 工作流(角色重新计算) ![Mover 预览](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/d1b4a5f5c3223301.png) ### 8. Leaver 工作流(全部会话与访问权限撤销) ![Leaver 撤销](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/7fc916a096223302.png) ### 9. 访问审查治理 ![审查表格](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/8871382638223304.png) ![审查撤销模态框](https://static.pigsec.cn/wp-content/uploads/repos/2026/04/5f0d1f73e9223305.png) ## 本项目如何映射到企业 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, 企业级安全, 加入者/调动者/离职者, 动态机密, 单点登录, 反向代理, 后端开发, 基于角色的访问控制, 多因素认证, 大语言模型安全, 安全实验室, 安全工程, 定期访问审查, 实时身份威胁检测, 容器化, 机密管理, 测试用例, 版权保护, 访问控制, 越狱测试, 身份与访问管理, 身份安全, 身份生命周期管理, 逆向工具, 零信任