SCIM 目录同步
SCIM 目录同步可以把 AISIX 组织连接到你的身份提供方(IdP),由目录创建、更新和停用成员账号。AISIX 实现 SCIM 2.0 协议(RFC 7643/7644),Okta、Microsoft Entra ID 以及其他企业身份提供方都原生支持该协议。
目录同步适用于需要把网关用量归因到大量人员的组织,包括数百或数千名成员,同时不要求每个成员都登录控制台。
预配的用户会成为什么,取决于 AISIX 是否信任组织的身份提供方断言该用户的邮箱地址,这与单点登录的判断相同。On-Premises 控制面信任所有地址;SaaS 服务只信任组织已验证域名内的地址。
- 受信任的地址会立即成为成员。 如果该邮箱 在 AISIX 中尚不存在,目录同步会创建一个无登录成员,与 On-Premises 管理员可以直接创建的成员相同:它可以拥有 API Key、携带限流和预算,并出现在用量报表中,但在管理员为其启用登录或本人通过 SSO 关联之前不能登录控制台。如果该邮箱已属于某个尚未加入本组织的 AISIX 账号,目录同步会改为把新的成员资格关联到该账号,因此此人可以使用该账号现有的凭据登录。在 SaaS 服务上,为该地址注册却从未验证邮箱的账号会被接管:它失去密码、会话、尚未使用的邮箱验证链接和 SSO 关联。账号名称改为新建账号时会从请求中取得的名称,即
displayName或name,都没有时使用邮箱地址;账号对《用户协议》和《隐私政策》的同意记录被清除,邮箱地址被标记为已验证。接管会记录为一条verified_domain_claim审计记录,参见审计记录。 - 其他地址会成为等待加入的成员。 不会创建或关联任何账号。AISIX 向该地址发送邀请,本人接受邀请或关联组织的 SSO 后即可加入。参见等待加入的成员。
当某个人在 IdP 中被停用或移除时,AISIX 会停用该成员,并禁用该成员拥有的所有 API Key。该变更会传播到网关数据面,因此这些凭证会在网关本身停止工作,而不只是无法在控制台中使用。
启用目录同步
-
打开 Settings,找到 Directory sync (SCIM) 卡片。
-
开启 Enable SCIM provisioning(仅组织 Admin 和 Owner 可操作)。
-
复制卡片中显示的 SCIM base URL,例如:
https://<your-cp-api-host>/scim/v2 -
选择 Generate SCIM token(仅组织 Owner 可操作),并在离开页面前复制明文值。该值只会显示一次。
如果要从 shell 测试 SCIM 端点,请导出这些值:
export AISIX_SCIM_BASE_URL="https://<your-cp-api-host>/scim/v2"
export AISIX_SCIM_TOKEN="YOUR_SCIM_TOKEN"
在 IdP 的 SCIM 连接器中配置同一个 base URL,并把该 Token 作为 Bearer 凭证。该 Token 是一个具有独占 scim 权限范围的 Admin Token。它只能调用 SCIM 端点,在所有其他 AISIX Cloud Admin API 路由上都会被拒绝,因此即使 IdP 凭证泄漏,也不能读取或变更网关资源。
如需轮换凭证,请生成新的 SCIM Token,更新 IdP 连接器,然后在 Admin tokens 页面吊销旧 Token。
用户如何映射为成员
| SCIM 属性 | AISIX 成员字段 |
|---|---|
userName / emails[].value | 邮箱地址(身份标识) |
displayName 或 name | 目录同步所创建账号的显示名称 |
externalId | 稳定的 IdP 标识符,在组织内唯一 |
active | false 会停用成员并禁用其 API Key |
groups | 团队成员关系(只读,通过 Groups 端点管理) |
SCIM 响应返回身份提供方发送的 userName、name、displayName 和 emails,以及 AISIX 的 id、externalId、active 和 groups。响应从不返回 AISIX 账号的名称或邮箱地址,因此不会暴露某个地 址是否已有账号。不是由目录同步创建的成员,或在控制面开始保存身份提供方原始值之前创建的成员,返回的是账号中存储的邮箱地址和名称。
只有当成员背后的账号没有密码、且不属于其他任何组织时,SCIM 才会修改该账号的名称和邮箱地址。在 SaaS 服务上,还要求新的邮箱地址位于某个已验证域名内。否则,账号保留原有的名称和地址,AISIX 保存身份提供方发来的新值,并在响应中返回这些值。
如果要创建的用户邮箱已经属于该组织中的某个成员,AISIX 会返回 409 唯一性错误。在控制台中创建的成员仍由控制台管理。它们会出现在 IdP 的列表响应中,但 SCIM 不能修改、停用或删除这些成员。目录同步永远不能修改组织 Owner。
通过 SCIM 删除用户时,AISIX 会先禁用该成员的 API Key,再将成员从所有团队中移除,最后移除成员资格。用量历史会保留用于报表。该邮箱会重新可用,因此后续重新预配会创建一个新的成员。
停用与删除
active: false会保留成员及其 Key,但这些 Key 会在网关侧被禁用。再次设置active: true时,只会重新启用目录同步禁用的 Key。由操作人员手动禁用的 Key 会保持禁用状态。DELETE会永久移除成员资格。Key 保持禁用,并保留其用量历史。
停用成员会失去什么
被停用的成员会保留成员记录和角色,但会失去对组织的访问权限,包括通过控制台会话或个人访问 Token 的访问:
- 该组织不再出现在
GET /api/orgs的结果中,组织的路由会返回403和错误码NOT_A_MEMBER。 - 不能把 API Key 绑定到该成员。以该成员的
user_id创建 Key,或把现有 Key 的user_id改为该成员,会返回400和错误码INVALID_REQUEST。编辑已经绑定到该成员的 Key 时,只要不修改user_id,仍然可以正常编辑。 - 所有者已被停用的 Key 不能重新启用。将
disabled设置为false会返回400和错误码INVALID_REQUEST。如需把 Key 交给其他人,请在启用它的同一请求中把它绑定到一个活跃成员,或移除它的user_id。这种转交是有意允许的。 - 邀请无法恢复访问权限。兑换邀请会返回
403和错误码MEMBER_DEACTIVATED,邀请保持待接受状态,成员也保持停用。请改为在身份提供方中重新激活该成员。 - 组织为该成员签发、尚未使用的设置密码链接失效。通过 SCIM 删除该成员同样会使这些链接失效。
- 成员处于停用状态时无法签发新的设置密码链接:
POST /members/{user_id}/set_password_link返回400和错误码INVALID_REQUEST,Members 列表也不会为该成员提供登录相关操作。
等待加入的成员
在 SaaS 服务上,地址位于组织已验证域名以外的预配用户,会被记录为等待加入的成员。它有一个身份提供方可以像其他用户一样使用的 id,但在本人加入之前,不会创建或关联任何账号。
AISIX 以 SCIM Token 所有者的名义向该地址发送邀请:
- 这些邮件计入组织的每小时邀请邮件数量限制,目录同步的邮件按组织计数。超出限制时,邀请照常创建但不发送邮件,管理员可以在 Pending invitations 标签页中重新发送。
- 该地址已有待接受的邀请时(例如管理员在控制台中发出的邀请),会直接使用该邀请,不再发送新邮件。目录同步从不撤销不是由它创建的邀请。
- 以
active: false预配的用户,在身份提供方将其设为active: true之前不会收到邀请。
等待加入的成员通过以下任一方式加入,并成为保留同一个 SCIM id 的正式成员:
- 本人接受邀请,登录的账号使用相同的邮箱地址。目录自己的邀请过期或被撤销后,管理员向该地址重新发出的邀请同样有效。
- 本人在关联页面关联组织的 SSO,且其身份的 NameID 等于目录发送的
externalId。请配置身份提供方让两者发送同一个标识符。
无论哪种方式,此人都会带着目录分配的角色、externalId、身份提供方属性和团队成员关系加入,目录同步发出的未使用邀请会被撤销。如果该账号已经是组织成员,则保留现有成员资格,并删除等待加入的记录。
在此之前,身份提供方的变更只作用于等待加入的成员:
active: false保留等待加入的成员及其id,并撤销其邀请;active: true会重新邀请。- 修改其邮箱地址会撤销发往旧地址的邀请;成员处于激活状态时,还会邀请新地址。新地址不能属于组织中的其他 SCIM 用户。
DELETE删除等待加入的成员,并撤销目录同步发出的邀请。
GET /Users 会把等待加入的成员与正式成员一起列出,过滤条件同样适用,组也可以引用它们。它们显示在 Members 页面的 Waiting to join 区块中,也可以通过 AISIX Cloud Admin API 的 GET /pending_members 操作查询,该操作接受与 GET /members 相同的 page 和 page_size 参数。希望目录同步直接预配成员的组织,应先验证自己的域名。
将组映射到团队和角色
SCIM 组会同步为 AISIX 团队:推送一个组会创建同名团队,组成员关系变化会添加或移除团队成员。
Directory sync (SCIM) 卡片控制角色映射:
- Default role:当同步成员不属于任何已映射组时获得的组织角色,可以是
member、admin或自定义角色。 - Group → role mappings:每个映射将一个目录组的成员分配到一个角色,按组显示名称匹配。任何可分配角色都可以作为目标,包括自定义角色。当成员属于多个已映射组时,
admin映射优先;否则使用组名称排序最靠前的映射。
目录同步成员的角色会在每次组变化时重新计算,包括组重命名;映射或默认角色变更时也会重新计算。在控制台中手动修改的角色会在下一次同步时被覆盖,因此应将目录视为同步成员的事实来源。目录同步永远不能分配 owner 角色,也不会修改由 SSO 角色映射写入的角色。
与单点登录配合使用
目录同步不负责登录。要让同步成员通过同一个身份提供方登录控制台,请配置单点登录。请让 SCIM 的 externalId 与 SAML 的 NameID 使用同一个标识符,这样等待加入的成员在本人关联 SSO 时即被激活。通过 SSO 登录的同步成员仍由目录同步管理,只是由 SSO 角色映射规则写入的角色不会被组到角色映射覆盖。
使用同步成员进行归因
目录同步会创建成员;归因方式与其他成员相同:
当 IdP 停用该人员时,这些 Key 会在数秒内停止通过网关认证。
成本归属标签不会从 IdP 同步。目录同步既不读取也不写入成员的标签,因此即使是由目录同步管理的成员,也请在控制台或通过 Admin API 设置其标签。
支持的端点
SCIM 接口位于 /scim/v2 下,并以 application/scim+json 响应:
| 端点 | 方法 |
|---|---|
/Users | GET(列表,以及对 userName、emails.value、externalId 的 eq 过滤)、POST |
/Users/{id} | GET、PUT、PATCH、DELETE |
/Groups | GET(列表,以及对 displayName、externalId 的 eq 过滤)、POST |
/Groups/{id} | GET、PUT、PATCH、DELETE |
/ServiceProviderConfig、/ResourceTypes、/Schemas | GET |
PATCH 遵循 SCIM PatchOp 结构,包括 Okta 和 Microsoft Entra ID 会发送的路径形式(active、members[value eq "..."],以及不带 path 的操作)。列表响应使用 startIndex 和 count 分页(每页最多 200 条)。没有 AISIX 映射的属性(例如电话号码或地址)会被接受并忽略,因此不需要精简 IdP 属性映射。
示例:使用 curl 预配用户:
curl -sS "${AISIX_SCIM_BASE_URL}/Users" \
-H "Authorization: Bearer ${AISIX_SCIM_TOKEN}" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "dev@example.com",
"displayName": "Developer One",
"emails": [
{
"value": "dev@example.com",
"primary": true
}
]
}'
下一步
继续阅读连接 AISIX 网关,将网关接入环境。之后如需调查目录驱动的变更,请使用日志与审计。