Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions docs/02-domain-model.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,15 +245,18 @@
| avatar_url | varchar(512) | |
| status | enum | `ACTIVE` / `PENDING` / `DISABLED` / `MERGED` |
| merged_to_user_id | varchar(128) | 合并目标用户 ID,仅 MERGED 状态有值 |
| system_account | boolean | 系统服务账号,禁止交互式 Web/OAuth 登录 |
| created_at | datetime | |
| updated_at | datetime | |

- 状态语义:
- `ACTIVE`:正常使用
- `PENDING`:等待管理员审批(AccessPolicy 返回 PENDING_APPROVAL 时创建)
- `PENDING`:等待管理员审批(AccessPolicy 返回 PENDING_APPROVAL 时创建);批准时必须在同一事务补齐 `@global` membership 后转为 `ACTIVE`
- `DISABLED`:管理员封禁,登录后拒绝所有操作,返回 403
- `MERGED`:已合并到其他账号,保留记录不物理删除,登录时自动跳转到合并目标账号
- `MERGED`:已合并到其他账号,保留记录不物理删除;登录直接拒绝且不向调用方泄露合并目标,也不允许通过管理员状态接口重新激活
- 授权层在每次请求时检查用户状态,非 `ACTIVE` 用户拒绝所有写操作
- system account 可按独立 Token Policy 使用非交互凭证,但不能通过本地密码或外部 OAuth
建立普通用户 Session

### identity_binding

Expand Down
26 changes: 20 additions & 6 deletions docs/03-authentication-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,10 @@ astron:
### 2.2 准入失败处理

- `DENY`:抛出 `OAuth2AccessDeniedException`,由 `failureHandler` 重定向到 `/access-denied` 页面。不创建用户,不建立 Session。
- `PENDING_APPROVAL`:创建 `user_account`(status=`PENDING`),但不建立业务 Session。抛出 `AccountPendingException`,由 `failureHandler` 重定向到 `/pending-approval` 页面(纯静态提示页,无需登录态)。管理员在后台审批后状态变为 `ACTIVE`,用户下次 OAuth 登录才会正常建立 Session。
- `PENDING_APPROVAL`:首次登录创建 `user_account`(status=`PENDING`),但不建立业务 Session。抛出 `AccountPendingException`,由 `failureHandler` 重定向到 `/pending-approval` 页面(纯静态提示页,无需登录态)。管理员在后台审批时,系统在同一事务内把状态变为 `ACTIVE` 并补齐 `@global` 的 `MEMBER` membership;任一步失败都回滚。后续登录以已绑定账号的持久化状态为准:`ACTIVE` 正常建立 Session,`PENDING` 继续等待,`DISABLED` 拒绝登录;准入策略持续返回 `PENDING_APPROVAL` 不会覆盖已完成的管理员审批

安全边界:PENDING / DISABLED 用户绝不会拥有有效的业务 Session,从根源上杜绝"待审批账号已认证"的风险。
安全边界:PENDING / DISABLED / MERGED 用户和 system account 绝不会通过交互式登录获得
业务 Session。外部身份命中这些账号时,在更新用户资料或加载角色前直接拒绝。

### 2.3 扩展性

Expand Down Expand Up @@ -352,16 +353,29 @@ public class OAuthClaimsExtractor {

同一个员工通过不同 OAuth Provider 登录时,可能产生多个 `user_account`。

一期策略:默认关闭自动合并,仅支持管理员手动合并。
当前策略:不自动合并,旧的手动合并流程也已临时隔离。旧流程把次账号 verification
token 直接返回给主账号会话,不能分别证明两个账号的控制权,因此不能继续作为管理员或
用户合并入口。

- 一期 GitHub-only:不需要自动合并,每个 Provider 登录独立创建用户
- 多 Provider 上线时,再引入显式绑定/合并流程(用户主动发起 + 邮箱验证确认)
- 管理员可在后台手动合并两个 user_account(合并 identity_binding、迁移 skill ownership、合并角色取并集)
- 多 Provider 上线时,再引入显式 Identity Link 和安全 Account Merge
- email、username、display name 或主账号会话拿到的 token 均不能证明次账号所有权
- 安全 Account Merge 必须要求主、次账号分别完成 fresh reauthentication
- 在安全流程上线前,`/api/v1/account/merge/initiate`、`verify`、`confirm` 对已认证请求
统一返回 `503 Service Unavailable`

合并操作规则:
- 合并操作写入审计日志
- 合并后原 user_account 标记为 `MERGED`,保留记录不物理删除
- 预留扩展位:未来可配置 `astron.identity.auto-merge-on-verified-email=true` 开启基于已验证邮箱的自动合并
- 不提供按 email 自动合并;即使 Provider 声明 email 已验证,也不能替代对两个账号控制权
的分别证明。未来绑定/合并必须使用显式、可审计的重新认证流程。
- 旧 `account_merge_request` 记录保留用于审计和未来迁移,但不得通过 SQL 手工改为
`VERIFIED`/`COMPLETED`,也不得手工迁移身份、角色、membership、凭据或 Token
- 回滚到仍包含旧合并实现的镜像会重新暴露该安全问题;如必须回滚,应先在网关阻断
`/api/v1/account/merge/*`

未来安全流程的完整验收条件见
[`22-secure-account-merge-acceptance-design.md`](./22-secure-account-merge-acceptance-design.md)。

## 5. CLI 认证(OAuth Device Flow + 平台凭证)

Expand Down
6 changes: 3 additions & 3 deletions docs/10-delivery-roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
### 后端

- 本地认证体系(用户名密码注册/登录 + BCrypt + 密码策略 + 账号锁定)
- 多账号合并流程(发起 → 验证 → 确认 → 数据迁移
- 多账号合并流程(旧实现已因控制权证明不足临时隔离,等待安全重构
- 技能治理(隐藏/恢复 + 已发布版本撤回 YANKED)
- 审计日志查询 API(多条件筛选 + 分页)
- Prometheus 指标暴露(Actuator + Micrometer 自定义业务指标)
Expand All @@ -109,7 +109,7 @@
### 前端

- 注册页、登录页扩展(用户名密码 + OAuth 双模式)
- 密码修改页、账号合并页
- 密码修改页、账号合并安全隔离提示页
- 审计日志查询页
- 技能隐藏/恢复/已发布版本撤回操作(管理员可见)
- 前端代码分割(TanStack Router lazy routes)
Expand All @@ -125,7 +125,7 @@

### 验收

本地认证可用,多账号合并可用,技能隐藏/恢复/已发布版本撤回可用,审计日志可查询,Prometheus 指标可拉取,`docker compose up` 一键启动,K8s 清单可部署,开源基础设施齐全
本地认证可用;多账号合并在主、次账号独立控制权证明完成前保持关闭;技能隐藏/恢复/已发布版本撤回可用,审计日志可查询,Prometheus 指标可拉取,`docker compose up` 一键启动,K8s 清单可部署,开源基础设施齐全

## Phase 5:治理闭环 + 社交

Expand Down
Loading
Loading