Files
homelab-wiki/services/hydra.md
T
2026-09-28 12:31:40 +00:00

162 lines
11 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.
---
title: Hydra 与 OIDC 上游适配器
lifecycle: experimental
evidence: live-verified
last_reviewed: 2026-09-27
last_verified: 2026-09-25
sources:
- https://git.ddupan.top/panxiao81/iam-login/pulls/2
- https://git.ddupan.top/panxiao81/iam-login/commit/9cf2d235dff0cd33f98012b0a114f14a8f9bfcda
- https://git.ddupan.top/panxiao81/homelab-infra/pulls/142
- https://git.ddupan.top/panxiao81/homelab-infra/pulls/143
- 2026-09-25 部署、discovery、重定向与网络隔离检查
- 维护者于 2026-09-25 确认 Hydra 登录成功返回原 Gitea 账号且仓库权限正常
---
# Hydra 与 OIDC 上游适配器
第一轮人类登录 PoC:Hydra 负责 OIDC 签发,薄的 Login/Consent 服务通过标准 OIDC
验证上游身份。当前配置的上游是 Authelia,它继续连接 Samba AD 并执行人类 MFA。
适配器没有直接连接 LDAP,也不与 Authelia 专有认证协议绑定。
本服务独立于 Ayatori。现役 PoC 代码仍作为 homelab-infra 中的独立 Go module 保存。
下一阶段直接连接 AD 的 Java/Spring 登录服务已建立独立仓库
[iam-login](https://git.ddupan.top/panxiao81/iam-login),已建立 Spring Native 构建验证基础,人类界面方向见
[浏览器登录设计](../architecture/independent-iam-draft.md#人类浏览器登录界面),
尚未替换现役 Go/Authelia 链路。应用代码、测试与 Native 构建发布归新仓库,环境部署归
homelab-infra;首轮实现由 [issue #1](https://git.ddupan.top/panxiao81/iam-login/issues/1) 跟踪。
完整的多主体 IAM 仍是[草案](../architecture/independent-iam-draft.md);
本轮不实现 SPIFFE 登录、agent 专用认证、动态授权或统一组迁移。
## 入口与首次使用
| 入口 | 用途 |
|---|---|
| <https://hydra.ad.ddupan.top> | Hydra 公共 OAuth2/OIDC API |
| <https://hydra-login.ad.ddupan.top> | Login/Consent 适配器,仅处理具体流程路径 |
| <https://git.ddupan.top/user/oauth2/hydra> | 从 Gitea 发起 Hydra 人类登录 |
Hydra 两个域名仅通过 LAN/Tailscale 可达,无公网 tunnel。请从 Gitea 的 `hydra`
登录源进入,在 Authelia 完成既有认证,然后返回 Gitea;旧 `authelia` 登录源保留。
Gitea 继续按原有账号关联、仓库权限与 gitea-admins 组映射执行授权。
```text
Gitea → Hydra → OIDC Login/Consent → Authelia → Samba AD
← OIDC ← 已验证的人类身份 ← OIDC callback
```
## 验证范围
2026-09-25 已现场验证:Hydra 数据库迁移成功、两个 Deployment 就绪、ESO SecretSynced、
TLS discovery 的 issuer/endpoints 正确、Flux hydra Kustomization Ready/Healthy;
HTTP 登录链路可从 Hydra 经适配器到达 Authelia 登录页。
无效 login、callback、consent 请求返回 403。Gitea Pod 能访问公共 discovery,不能
直连 Hydra admin Service;公共 HTTPS 入口的 admin API 返回 404。
Gitea 的新增登录源经 PR #143 接入,Helm revision 19 UpgradeSucceeded、Pod Ready;
登录页同时显示 hydra/authelia,从真实 Gitea 入口到达 Authelia 的整段跳转已验证。
**第一轮人类登录 PoC 已通过验收。** 维护者于 2026-09-25 实际使用 Hydra 登录入口后
确认:“已成功返回原账号,仓库权限正常”。这补齐了人类认证后的回调、原账号关联与
仓库权限验收;依据为维护者实际操作反馈,而非 agent 代为输入人类凭据。
`last_verified` 覆盖上述明确列出的检查及维护者登录反馈,不表示机器或 agent 路径已验证。
## 实现与维护
- Hydra 固定 `v26.2.0` 与镜像 digest,使用独立 hydra PostgreSQL database/role。
- 源码 `apps/hydra/login-consent`:标准 OIDC 上游适配器。校验 ID token issuer、audience、
签名、有效期和 nonce,使用 PKCE S256 与单次、cookie 绑定的 state。
- 当前只允许 Gitea client 和 openid/profile/email/groups;按请求 scope 释放 claims,
不签发 refresh token,不提供通用自动 consent。主体为上游 issuer/sub 的稳定哈希。
- 单副本短期登录事务保存在内存;重启使正在进行的登录失效,用户重新发起即可。
- Hydra admin 无 HTTPRoute,NetworkPolicy 仅允许适配器访问;维护时通过受控本地
kubectl port-forward,不对外开放 admin。
- 秘密保存在 OpenBao `kv/k8s/hydra`,ESO 投射给 Hydra/适配器和 Gitea。禁止重建
system_secret 来处理普通启动问题。
- Authelia 的新 hydra-login client 通过现有 Helm release 的增量 values 更新,保留全部
已有客户端与 two_factor 策略;Authelia 暂未由 Flux 接管。
源码、构建、claims/client 配置和恢复说明见
[Hydra README](https://git.ddupan.top/panxiao81/homelab-infra/src/branch/main/apps/hydra/README.md)。
Hydra 部署见 [PR #142](https://git.ddupan.top/panxiao81/homelab-infra/pulls/142),
Gitea 接入见 [PR #143](https://git.ddupan.top/panxiao81/homelab-infra/pulls/143)。
依赖共享 PostgreSQL、OpenBao/ESO、Authelia、Envoy、Samba DNS 与 zot。独立于 Ayatori
不等于已完成共享基础设施之外的灾备;恢复需保留 Hydra 数据库和秘密。
回退时先撤 Gitea 新登录源,沿用旧 Authelia 入口,不删除用户或原有认证配置。
### 独立登录服务的 AD 接入
`iam-login` 的人类界面沿用内联上下文与原生表单,新增 AD 第一因素验收入口;
以用户身份 LDAPS bind,读取 objectGUID 和直接 `memberOf`,组名保持原样。
当前不展开嵌套组或主组,不能视为已完成与 Authelia 的有效组集合等价验证。
密码成功仅代表第一因素通过;Gitea 仍使用上面已验收的 Go/Authelia 路径。
按 2026-09-27 明确的实现边界,React 只替换 Spring Security 默认 UI,密码 POST、
因素状态和认证会话交由框架管理。待 MFA 页面要求近期密码因素,尚未实现的应用入口拒绝访问。监控 Basic 认证与人类登录会话隔离。
本轮开发验证通过 JVM 测试,并从 JVM 通过 CA/域名验证读取真实 AD RootDSE。
2026-09-25 维护者已在 HTTPS 开发入口完成真实密码验证,成功进入待 MFA 页面,
并反馈目录标识、邮箱及六个直接所属组的查询结果。此人类验收只覆盖 AD 第一因素与
属性读取,不包括 MFA 或 Hydra 登录。新增路径尚未跑 Native;日常迭代不要求每轮原生编译。开发入口使用受限 Tailscale HTTPS,属于临时验收实例,不是生产入口。
AD 接入与 Spring Security 重构统一见 [iam-login PR #4](https://git.ddupan.top/panxiao81/iam-login/pulls/4);
2026-09-27 通过 18 项 JVM 测试和 1 项浏览器回归,后续真实人类验证反馈见下方 WebAuthn 开发验证。
配置、边界与使用方式见
[iam-login AD 接入文档](https://git.ddupan.top/panxiao81/iam-login/src/branch/main/docs/ad-login.md)。
### WebAuthn 开发验证
2026-09-27 的 [iam-login PR #6](https://git.ddupan.top/panxiao81/iam-login/pulls/6) 将第二因素接入
Spring Security 官方 WebAuthn 流程,并以官方 JDBC 仓储和本地 PostgreSQL 持久卷保存凭据。
该实现仍在开发 PR,生产 Go/Authelia 链路未切换。
开发入口仍为 `https://laptop.tail7e769.ts.net:18082/signin`,限 Tailscale 可达。
先验证 AD 密码,首次使用注册 passkey,再实际验证 passkey;注册成功本身不通过 MFA。
已有凭据后的新增注册要求现有 MFA;本轮 UI 不开放凭据管理、删除或自助恢复。
当前真实 AD 开发实例的 `/signin/complete` 显示双因素结果,尚未配置 Hydra 授权接入;
新增 Login/Consent 的代码与隔离验证见下文。
2026-09-28 维护者明确首轮自用边界:AD 用户、密码和组继续使用 RSAT/命令行管理;
丢失全部 MFA 时由管理员核实身份后人工操作目标主体的数据库凭据恢复。
不开发目录管理、自动恢复或完整 self-service UI,也不将其作为核心人类链路验收前提。
22 项 JVM 测试与 Chromium 虚拟认证器流程通过,覆盖再次登录、注册限制、会话轮换、
challenge 过期/消费、断言重放及跨主体凭据拒绝。真实开发 HTTPS 页面的证书与表单回归
已检查。维护者随后在该开发入口完成验收,反馈“我验收完了,看样子能工作”;
据此记录 AD + passkey 人类浏览器路径已获维护者确认。此反馈不构成 Native、数据库
重启恢复或 Hydra/Gitea 新链路验收,也未限定认证器型号与跨设备兼容范围。
数据库开发操作、数据卷保留与失败边界见
[WebAuthn 文档(开发分支)](https://git.ddupan.top/panxiao81/iam-login/src/branch/feat/webauthn-mfa/docs/webauthn.md)。
### 独立登录服务的 Hydra 接入
双因素后的 Login/Consent、客户端管理与统一注销已提交至
[同一 iam-login PR #6](https://git.ddupan.top/panxiao81/iam-login/pulls/6),源码版本为
[62b6e9d](https://git.ddupan.top/panxiao81/iam-login/commit/62b6e9d),尚未合并或切换生产入口。
2026-09-28 已通过 36 项 JVM 测试与隔离 Hydra v26.2.0 的浏览器授权码及注销流程:
模拟 AD → WebAuthn → 原生表单确认 → Hydra code → 客户端兑换并验签 ID token。
验证覆盖 issuer、audience、nonce、显式配置的旧 subject、直接组 claims 与授权码重放拒绝;
独立 MFA 路径此前也通过浏览器回归。本轮另验证客户端 CRUD、Hydra 重启后的 PostgreSQL
持久化、更新保留密钥、管理权限/CSRF 拒绝、再次授权确认、注销通知签名与 sid 关联,以及
Spring 本地会话失效。这些是测试夹具结果,不是生产 Gitea 验收。
生产主体按 AD authority + objectGUID 显式绑定现役 Hydra sub,未绑定账号拒绝授权;
不靠邮箱、用户名或自动新建账号迁移。生产映射值尚未取得并核实,现役入口未切换,
AD/WebAuthn/Hydra 的 Native 完整链路也仍待验收。配置与迁移条件见
[Login/Consent 文档(开发分支)](https://git.ddupan.top/panxiao81/iam-login/src/branch/feat/webauthn-mfa/docs/hydra-login.md)。
Hydra 持有客户端注册表并提供 CRUD Admin API;新增客户端不依赖修改服务器配置文件。
管理能力由 iam-login 的 `clients` 领域模块包装:Spring session、有效 MFA 与显式直接管理组
控制访问,写操作保留 CSRF;不公开 Hydra admin 或任意代理。本地实现中的客户端与密钥只存
Hydra PostgreSQL,启用标记写入 client metadata 并在授权时重新读取。旧配置 allowlist
只作无标记客户端的过渡兼容,不是第二份注册表。暂不建设完整自助管理 UI。
统一注销计划沿用 Hydra 登记的 front/back-channel 协议;登录服务通过 Spring 清除当前
本地会话。Hydra 必须保留登录会话以关联注销;仅凭 issuer 的 remembered-login 标记不能
绕过本地 MFA。下游不支持注销协议、通知失败或 issuer 会话已过期时,不能声称所有应用均
已退出;不等同撤销全部 token 或其他设备会话。
正式入口目标是替换现役 `auth.ddupan.top`,Hydra public 与 iam-login UI/API 按路径共用
origin,仍保持独立部署。不能把整个 `/oauth2/**` 都路由给 Hydra,也不发布 admin 路径。
上线前需审查 issuer 与现有账号关联、cookie/TLS 转发、WebAuthn RP ID 与凭据重新注册、
回退路由;这是部署计划,现有 Go/Authelia 生产链路未改变。