Files
opsx-vpn/docs/specs/SDD-007-built-in-feishu-issuer.md
T

43 lines
4.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SDD-007:内置飞书 OIDC 发行者
| 字段 | 内容 |
|---|---|
| 级别 | S3(公网身份入口、签名密钥、生产网关变更) |
| 状态 | 实施中,尚未验证真实飞书登录 |
| 日期 | 2026-10-22 |
## 1. 现状与目标
当前 OpenVPN OIDC 模式调用 `openvpn-auth-oauth2`,要求外部标准 issuer;`/api/tunnels/openvpn/oidc-readiness` 仅检测已安装插件与 HTTPS 管理入口。Nginx 只允许管理页面/API,其他路径返回 444;现有 LDAP 与密码专线均应保留。
增加单租户、单机部署的 Go `/id` 身份模块:飞书网页 OAuth 授权后,向插件提供受限的 OIDC authorization code 流程。仅已启用的管理员配置可提供发现文档、JWKS 与发码;不把登录成功视为自动获得 VPN 权限。沿用现有 HTTPS 域名及数据库,不引入外部身份服务器。
## 2. 功能与约束
- FR-01:管理员配置飞书 App ID/Secret(密钥不回显)、允许的 tenant key;系统生成并仅在服务端使用 VPN OIDC Client Secret,管理页面只显示 Client ID;复用现有 TLS 域名。
- FR-02:提供 discovery、JWKS、authorize、飞书回调、token、userinfo;只接收登记的一个 HTTPS 回调地址,发放一次性短时 code;签发 RS256 ID Token。飞书返回的 open_id 与 tenant_key 组合成稳定 subject。
- FR-03:OpenVPN 插件通过机密客户端交换授权码;客户端凭据、回调、nonce、state 绑定,存在 code_challenge 时校验 S256;不接受外部指定的上游 URL。
- FR-04:前端展示 issuer、飞书回调及 VPN 回调、准备状态,允许选择内置 issuer 填写专线配置,但不覆盖既有配置。
- FR-05:Nginx 仅允许同域 `/id/` 的固定身份端点转发到管理进程;`/oauth2/` 转发到单条已启动的认证组件(仅就绪后启用);其他未知路径保持 444。
- NFR-01:签名密钥 0600、密钥材料不可回显,令牌与随机状态只保存哈希或受限数据;严格 TLS、过期时间、状态原子消费、请求限流及日志脱敏。
- NFR-02:未启用或配置不完整时不发布可用 issuer,不破坏现有 OpenVPN/LDAP/管理入口。
## 3. 方案与契约
发行者建议 `https://<现有域名>/id`;只按 issuer 文档发布实际 URL,不假设根目录 discovery。飞书上游回调 `https://<现有域名>/id/feishu/callback`;插件回调 `https://<现有域名>/oauth2/callback`。飞书 App ID/Secret 只用于上游;插件使用系统生成的独立 VPN 凭据。数据加密利用现有 `secret.key`;RSA 签名私钥独立文件,备份必须同时包含数据库和密钥。
独立 `internal/identityprovider` 包承载协议逻辑和存储;`api` 管理路由只对管理员开放;Nginx 模板明确路由优先级。JWT 仅签发 `openid` 授权范围,不在令牌里包含飞书访问令牌。用户授权初期先采用飞书应用可用范围 + 明确租户约束;后续如需逐用户允许名单再增加独立配置。
接口参考 `/Users/logan/devops/demo/id/Feishu-OIDC-Workers` 的飞书官方端点定义与 JSON 换码格式;授权状态和客户端凭据隔离参考 `/Users/logan/devops/demo/id/dex` 的协议边界。没有复制其实现;Workers 示例把原始飞书 code 转交客户端的做法不用于本项目。
## 4. 风险与验收
| 风险 | 防护 / 恢复 |
|---|---|
| 伪造授权回调 / 重放 code | 随机 state 与 code、短有效期、数据库原子消费、精确 redirect URI 和客户端绑定 |
| 泄露私钥或飞书密钥 | 0600 与 AES-GCM、API 不回显、部署时不传入对话中曾公开的旧密钥 |
| 多专线共用 `/oauth2/` | 网关只选择唯一运行中的同域 OIDC 专线,冲突时不启用转发 |
| 网关修改影响管理入口 | 先预览、备份现有站点、`nginx -t` 后 reload;失败恢复旧站点 |
验收:禁用与错误配置拒绝授权;模拟飞书服务测试完整码流、重放、错误租户、错误回调/nonce/PKCE、JWT 验签;真实飞书应用授权和 OpenVPN WebAuth 需单独联调。发布顺序:完成本地测试 → 部署但默认禁用 → 管理员轮换并保存飞书凭据 → 预览并启用网关 → 测试专线正/负向登录 → 再决定生产切换。恢复:禁用 issuer、恢复 Nginx 旧站点和旧二进制;不删除现有专线或密钥。