From 17273bb6ca3dff384e1d6b649c5e443b0e072ba1 Mon Sep 17 00:00:00 2001 From: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> Date: Thu, 24 Sep 2026 15:44:56 +0800 Subject: [PATCH] docs(auth): decouple organization APIs from OIDC controls Signed-off-by: XiaoSeS <87064762+XiaoSeS@users.noreply.github.com> --- openspec/changes/enterprise-identity-platform/design.md | 2 +- .../changes/enterprise-identity-platform/rollout-plan.md | 6 +++--- .../specs/enterprise-identity-governance/spec.md | 2 +- .../specs/federated-authentication/spec.md | 2 +- .../changes/enterprise-identity-r1b-org-create/design.md | 2 ++ .../changes/enterprise-identity-r1b-org-create/proposal.md | 1 + .../specs/enterprise-organizations/spec.md | 7 +++++++ 7 files changed, 16 insertions(+), 6 deletions(-) diff --git a/openspec/changes/enterprise-identity-platform/design.md b/openspec/changes/enterprise-identity-platform/design.md index 0b66d0ef..20c5ecd2 100644 --- a/openspec/changes/enterprise-identity-platform/design.md +++ b/openspec/changes/enterprise-identity-platform/design.md @@ -180,7 +180,7 @@ OIDC client secret 不写入 typed configuration、API 响应、审计详情或 local login、公共 OAuth、Device Flow 和 API Token 的路由与响应保持不变。公共 OAuth 将已验证 facts 送入统一核心;身份核心支持 `LEGACY` 和 `ACTIVE` 模式。V54–V60 只做向前 schema/constraint/backfill,不删除旧表或旧 binding,因此回滚应用时无需执行 destructive down migration。 -动态企业 OIDC 把控制面装配开关、匿名登录数据面开关和 Organization allowlist 分开。控制面可以先启用来配置、探测和激活连接,同时保持匿名 discovery/start/callback 关闭;只有身份核心对目标 Organization 为 `ACTIVE`、登录数据面开启且 Organization 位于 allowlist 时,动态登录才可执行。身份核心切回 `LEGACY` 时公共 OAuth 完全走旧 binding。 +动态企业 OIDC 把连接管理开关、匿名登录数据面开关和 Organization allowlist 分开。Organization、Membership 和 Role 是协议无关的租户基础能力,不受 OIDC 开关控制。连接管理开关只控制 OIDC Login Connection 的配置、探测和激活等操作;成员范围的连接摘要读取仍按组织权限校验。连接管理可以先启用,同时保持匿名 discovery/start/callback 关闭;只有身份核心对目标 Organization 为 `ACTIVE`、登录数据面开启且 Organization 位于 allowlist 时,动态登录才可执行。身份核心切回 `LEGACY` 时公共 OAuth 完全走旧 binding。 认证专属的 Login Connection、revision、Secret、External Identity、认证操作和 Session origin 属于 `skillhub-auth` 安全边界。它们的聚合、Repository port 和 JPA adapter 在 auth 内闭合, diff --git a/openspec/changes/enterprise-identity-platform/rollout-plan.md b/openspec/changes/enterprise-identity-platform/rollout-plan.md index f18f9627..ebdfd857 100644 --- a/openspec/changes/enterprise-identity-platform/rollout-plan.md +++ b/openspec/changes/enterprise-identity-platform/rollout-plan.md @@ -161,7 +161,7 @@ V54–V60 是一条已经联合验证的 expand-only 迁移链: 1. 保持 R1-A 已验收的 identity core 模式。 2. 注入 Secret keyring 和固定的 OIDC public base URI 等运行配置。 -3. 设置 `SKILLHUB_ENTERPRISE_OIDC_ENABLED=true`,只装配控制面。 +3. Organization 创建、成员与角色管理按自身权限开放,不依赖 OIDC 开关;需要配置和测试 OIDC Login Connection 时,设置 `SKILLHUB_ENTERPRISE_OIDC_ENABLED=true`。此开关在后续连接管理批次实现,不是本批 Organization 创建 API 的运行前提。 4. 明确保持 `SKILLHUB_ENTERPRISE_OIDC_LOGIN_ENABLED=false`。 5. 保持 `SKILLHUB_ENTERPRISE_ORGANIZATION_ALLOWLIST` 为空。 6. 只创建测试 Organization,配置、测试并激活测试连接。 @@ -178,7 +178,7 @@ V54–V60 是一条已经联合验证的 expand-only 迁移链: #### 回滚 -设置 `SKILLHUB_ENTERPRISE_OIDC_ENABLED=false`,关闭控制面组件。已创建的 Organization、Connection、revision、Secret 和审计记录保留,不影响现有公共登录。 +设置 `SKILLHUB_ENTERPRISE_OIDC_ENABLED=false`,关闭 OIDC Login Connection 的配置、测试和激活等操作,而不是关闭 Organization 基础 API。现有成员范围的连接摘要仍可按组织权限读取。已创建的 Organization、Membership、Connection、revision、Secret 和审计记录保留,不影响现有公共登录或其他协议后续接入。 ### 4.3 R1-C:动态 OIDC 登录数据面 @@ -224,7 +224,7 @@ V54–V60 是一条已经联合验证的 expand-only 迁移链: 1. 从 Organization allowlist 移除受影响组织。 2. 设置 `SKILLHUB_ENTERPRISE_OIDC_LOGIN_ENABLED=false`。 3. 如问题位于统一身份核心,再将 `SKILLHUB_IDENTITY_CORE_MODE` 切回 `LEGACY`。 -4. 必要时最后关闭 `SKILLHUB_ENTERPRISE_OIDC_ENABLED` 控制面。 +4. 必要时最后关闭 `SKILLHUB_ENTERPRISE_OIDC_ENABLED` 所控制的 OIDC 连接配置操作;Organization 基础 API 不随之关闭。 回滚不删除 Organization、Membership、Connection、External Identity、Session origin 或审计数据。 diff --git a/openspec/changes/enterprise-identity-platform/specs/enterprise-identity-governance/spec.md b/openspec/changes/enterprise-identity-platform/specs/enterprise-identity-governance/spec.md index 850d8fff..d1173c45 100644 --- a/openspec/changes/enterprise-identity-platform/specs/enterprise-identity-governance/spec.md +++ b/openspec/changes/enterprise-identity-platform/specs/enterprise-identity-governance/spec.md @@ -82,7 +82,7 @@ Organization、Membership、Domain、Role Binding、Login Connection、revision ### Requirement: Rollout controls are independent and observable -身份核心模式、动态企业 OIDC 控制面开关、匿名登录数据面开关和 Organization allowlist SHALL 独立配置;默认 SHALL 为 legacy-compatible 且企业 OIDC 控制面与登录数据面关闭。系统 SHALL 暴露不含身份数据的启用状态、连接健康和固定类别指标。 +身份核心模式、动态企业 OIDC 连接管理开关、匿名登录数据面开关和 Organization allowlist SHALL 独立配置;默认 SHALL 为 legacy-compatible 且企业 OIDC 连接管理与登录数据面关闭。Organization、Membership 和 Role 的基础 API SHALL 独立于这些 OIDC 开关,继续按平台或组织权限授权。关闭连接管理开关 SHALL 阻断 OIDC 连接的配置、测试和激活等操作,但不影响已授权成员读取非敏感连接摘要。系统 SHALL 暴露不含身份数据的启用状态、连接健康和固定类别指标。 #### Scenario: Candidate is deployed with defaults - **WHEN** 新版本使用默认配置启动 diff --git a/openspec/changes/enterprise-identity-platform/specs/federated-authentication/spec.md b/openspec/changes/enterprise-identity-platform/specs/federated-authentication/spec.md index 73dc0f67..a0209856 100644 --- a/openspec/changes/enterprise-identity-platform/specs/federated-authentication/spec.md +++ b/openspec/changes/enterprise-identity-platform/specs/federated-authentication/spec.md @@ -214,7 +214,7 @@ local login、公共 OAuth、CLI Device Flow 和 API Token SHALL 保留既有路 ### Requirement: Dynamic enterprise OIDC is disabled by default -动态企业 OIDC SHALL 仅在身份核心对目标 Organization 为 `ACTIVE`、OIDC 登录数据面开关启用且目标 Organization 位于 allowlist 时公开和执行;控制面开关只决定连接管理组件是否装配,不得隐式开放匿名登录。默认配置 SHALL 不改变现有登录。 +动态企业 OIDC SHALL 仅在身份核心对目标 Organization 为 `ACTIVE`、OIDC 登录数据面开关启用且目标 Organization 位于 allowlist 时公开和执行;连接管理开关只决定 OIDC 连接配置、测试和激活等操作是否可用,不得关闭 Organization 基础 API 或隐式开放匿名登录。默认配置 SHALL 不改变现有登录。 #### Scenario: Global switch is disabled - **WHEN** operator 未开启动态企业 OIDC diff --git a/openspec/changes/enterprise-identity-r1b-org-create/design.md b/openspec/changes/enterprise-identity-r1b-org-create/design.md index a45cc694..671e9e39 100644 --- a/openspec/changes/enterprise-identity-r1b-org-create/design.md +++ b/openspec/changes/enterprise-identity-r1b-org-create/design.md @@ -2,6 +2,8 @@ 平台管理 API 只处理创建。租户内读写继续由 Organization Membership 和组织角色授权,平台 `SUPER_ADMIN` 不在租户 API 获得隐式通行权。 +Organization 及 Membership 是协议无关的租户基础能力。本批创建接口和已合入的成员范围只读接口不依赖企业 OIDC 开关;后续 OIDC 开关仅控制 OIDC Login Connection 的配置、测试和激活等操作,匿名登录另由数据面开关控制。现有成员范围的连接摘要读取仍按组织权限校验,不因关闭 OIDC 配置操作而失效。本批不实现这些开关。 + 控制器做请求校验和平台角色校验;应用服务编排现有聚合及仓储。保存 Organization、Membership、Role Binding 和审计均位于同一事务。slug 使用现有模型校验和数据库唯一约束;并发重名由现有 JPA adapter 映射为 409。 审计只持久化组织 ID、操作者、动作、成功结果和 requestId,不记录用户邮箱、密钥或请求体。初始 owner 的 Membership 来源为 MANUAL;创建成功后 Organization authority version 为 1。回滚无需删除数据:本批只有新 API,停用入口或回退应用版本即可,已创建组织保留。 diff --git a/openspec/changes/enterprise-identity-r1b-org-create/proposal.md b/openspec/changes/enterprise-identity-r1b-org-create/proposal.md index ea4fabaf..8026c6c0 100644 --- a/openspec/changes/enterprise-identity-r1b-org-create/proposal.md +++ b/openspec/changes/enterprise-identity-r1b-org-create/proposal.md @@ -7,6 +7,7 @@ R1-B 的只读 Organization API 已合入,但平台管理员还不能创建测 - 仅 `SUPER_ADMIN` 可创建 Organization,并指定一个已存在、ACTIVE、非系统、未合并的平台账号为初始 owner。 - 在一个事务中创建 Organization、ACTIVE Membership、`ORG_OWNER` role binding 和组织审计记录。 - 返回新组织的基本标识和状态;平台管理员不会自动取得该组织成员身份。 +- Organization 创建与成员权限属于协议无关的租户基础能力,不受未来的企业 OIDC 连接管理或登录开关控制。 ## Non-goals diff --git a/openspec/changes/enterprise-identity-r1b-org-create/specs/enterprise-organizations/spec.md b/openspec/changes/enterprise-identity-r1b-org-create/specs/enterprise-organizations/spec.md index eb9da420..b9b2c031 100644 --- a/openspec/changes/enterprise-identity-r1b-org-create/specs/enterprise-organizations/spec.md +++ b/openspec/changes/enterprise-identity-r1b-org-create/specs/enterprise-organizations/spec.md @@ -4,6 +4,8 @@ 系统 SHALL 只允许 `SUPER_ADMIN` 使用唯一 slug、显示名和一个已有且可用的平台账号创建 Organization。创建 SHALL 在单个事务中生成 ACTIVE Organization、该账号的 ACTIVE Membership、`ORG_OWNER` role binding 和组织审计记录。创建者不得因其平台角色自动成为组织成员。 +Organization 创建 SHALL 不依赖企业 OIDC 连接管理或登录开关;即使未启用企业 OIDC,已获授权的管理员仍可创建组织,成员仍可按组织权限读取组织信息。 + #### Scenario: Successful creation - **WHEN** 平台管理员指定有效 slug、显示名和 ACTIVE 的初始 owner @@ -18,3 +20,8 @@ - **WHEN** 创建者仅持有 `SUPER_ADMIN` 平台角色而不是新组织成员 - **THEN** 其访问新组织的租户详情接口被拒绝 + +#### Scenario: Enterprise OIDC is not enabled + +- **WHEN** 企业 OIDC 连接管理和登录均未启用,平台管理员创建 Organization +- **THEN** 创建和初始 owner 的组织读取仍按各自权限正常工作,不开放 OIDC 连接配置或匿名登录