Label Studio Enterprise SCIM2 配置实战:Okta 与 Microsoft Entra ID 的自动化用户与群组管理
【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio
导读:本文围绕 Label Studio Enterprise 的 SCIM(System for Cross-domain Identity Management)集成展开,讲解如何借助 SCIM 2.0 标准,让身份提供商(IdP,如 Okta、Microsoft Entra ID)自动化地向 Label Studio Enterprise 同步用户、群组与角色映射,实现用户开通(Provisioning)与停用(Deprovisioning)的全流程托管。读完本文,你将掌握 SCIM 集成的前置条件、Okta 与 Entra ID 两套完整的对接配置步骤、群组到角色/工作区/项目的三级映射方法,以及 SCIM REST API 端点的用法。
SCIM 是什么,为什么 Label Studio Enterprise 需要它
System for Cross-domain Identity Management(SCIM)是一种广泛使用的开放标准协议,用于在组织内部的各个服务与应用之间统一管理访问。其核心价值在于:把“谁可以访问什么资源”的身份管理逻辑集中到身份提供商(IdP)一侧,应用侧只需实现标准端点即可自动完成用户身份信息的同步。
对 Label Studio Enterprise 而言,SCIM 让管理员可以通过 SCIM 提供方统一完成以下工作:
- 批量添加用户(自动创建 Label Studio 账号);
- 移除用户(将其用户角色置为 Deactivated,从而撤销访问);
- 将用户分配到群组;
- 将用户从群组中移出;
- 将群组映射为组织级或项目级角色。
其中关键的一点是:群组的定义由 IdP 维护,Label Studio Enterprise 只负责维护“群组 → 角色”的映射关系。因此群组与角色的职责边界清晰,便于在大型组织中以群组为单位统一放权或收权。
Requirements 与 Prerequisites:SCIM 集成的硬性前提
协议标准
Label Studio Enterprise 采用SCIM Version 2.0标准,遵循 SCIM RFC 7644。
前置条件
在开始配置前,必须满足以下两个前提:
- SSO 已配置完成:SCIM 交互依赖于既有的 SSO 集成(例如 Okta 的 SCIM 集成就是建立在 SAML SSO 之上的,Okta 或其他类似的 SSO 提供方的 SCIM 集成都基于 SSO 应用)。如果尚未配置 SSO,请先按照 Set up SSO 完成配置。
- 准备 Legacy Token:需要提供一个与组织Owner 角色绑定的 Legacy token,SCIM 提供方将用它在请求头中完成身份认证。
关于 Legacy token 需要特别注意:它是相对“老式”的令牌,安全性不如 Personal Access Token,因为必须手动撤销;在 HTTP API 调用中,Legacy token 通常通过Authorization: Token <token>头传递。而在 SCIM 集成场景下,Okta / Entra ID 使用的是Authorization: Bearer <token>请求头——Label Studio 中Token与Bearer指向相同的令牌,但 SCIM 配置中必须使用Bearer前缀而非Token前缀。
从源码层面看,SCIM 的令牌认证与普通 API 认证有明确的协同处理逻辑:在 label_studio/core/middleware.py 中,InactivitySessionTimeoutMiddleWare会识别request.is_scim标记并跳过会话超时强制登出逻辑,因为 SCIM 请求是通过Authorization头隐式完成用户身份绑定的(源码注释明确写着 “scim assign request.user implicitly”),并不依赖浏览器会话。这意味着 SCIM 的系统调用不会被组织级的会话超时策略误杀。
设置 Okta SCIM 集成(分步指南)
第 1 步:将 Label Studio Enterprise 添加为应用
- 在 Okta 中导航到Applications > Applications,点击Create App Integration。
- 选择SAML 2.0,输入应用名称(例如Label Studio Enterprise)。
- 在Configure SAML中按照 Set up SSO guide 的步骤完成 SAML 配置。
- 确认 Label Studio Enterprise 出现在活跃应用列表中。
⚠️重要提醒:配置视频演示中使用了
userName作为“用户唯一标识字段”,但实际配置必须使用
第 2 步:启用 SCIM Provisioning
- 进入Applications > Applications,选择Label Studio Enterprise。
- 在General标签页勾选Enable SCIM provisioning。
- 进入Provisioning标签页,在左侧菜单中选择Integration,点击右上角Edit。
然后填写以下字段:
| 字段 | 值 / 说明 |
|---|---|
| SCIM connector base URL | https://<LABEL_STUDIO_BASE_URL>/scim/v2/,其中<LABEL_STUDIO_BASE_URL>是 Label Studio Enterprise 实例的 Base URL |
| Unique identifier field for users | 使用email。Label Studio Enterprise 以此字段作为用户标识 |
| Supported provisioning actions | 勾选以下项:Import New Users and Profile Updates、Push New Users、Push Profile Updates、Push Groups |
HTTP Header →Authorization: Bearer <token> | 填入与 Label Studio Owner 账号绑定的 Legacy token。Label Studio 中Token与Bearer是同一令牌,但请求头必须用Bearer而非Token |
第 3 步:配置 SCIM 设置与应用触发动作
- 在应用页面进入Provisioning标签页,左侧选择To App,点击右上角Edit。
- 启用以下三个项目:
- Create Users(创建用户)
- Update User Attributes(更新用户属性)
- Deactivate Users(停用用户)
第 4 步:将应用分配给单个用户
用户页与应用页都可以执行分配操作:
- 在应用页面进入Assignments标签页。
- 点击Assign,选择Assign to People。
- 勾选要加入 Label Studio Enterprise 的人员。
- 点击Done。
点击Done后,Okta 会向 Label Studio Enterprise 发送相应的用户创建请求,用户随即被自动开通。
第 5 步:取消用户的分配
- 在应用页面进入Assignments标签页。
- 在左侧选择People。
- 点击目标用户右侧的删除叉号。
- 确认取消分配。
第 6 步:将应用分配给群组(推荐做法)
通过群组管理访问是最便捷的方式:将 Label Studio 分配给群组,然后在 Okta 中管理群组成员,所有变更都会自动传播到应用侧(即 Label Studio Enterprise)。
在 Label Studio 中配置群组映射
- 在 Label Studio 中点击左上角菜单,选择Organization。
- 在右上角选择SCIM。
- 更新角色与工作区映射。注意:群组名称必须与 SCIM 提供方发送的群组名完全一致。
三种映射类型说明:
- Organization Roles to Groups Mapping(组织角色 ↔ 群组):将群组映射为组织级角色。组织级角色是用户的默认角色,会自动应用到工作区与项目中。角色说明详见 Roles in Label Studio Enterprise。
- 可以将多个群组映射到同一角色。
- 注意:Not Activated(未激活)或 Deactivated(已停用)用户不计入账号的 seat(席位)配额。
- Workspaces to Groups Mapping(工作区 ↔ 群组):将群组添加为工作区成员。Manager、Reviewer、Annotator 角色的用户只有被加入某工作区成为成员后,才能看到该工作区。
- 可以选择已有工作区或新建一个,多个群组可映射到同一工作区。
- Projects to Groups Mapping(项目 ↔ 群组):将群组映射为项目级角色。项目级角色可以是Annotator、Reviewer或Inherit。
- 一个群组可以在多个项目中映射为不同角色;多个群组也可以映射到相同角色和相同项目。
- 若选择Inherit,群组将继承“组织角色 ↔ 群组映射”中设置的角色;如果群组继承的是 Not Activated 角色,用户虽然被映射到项目,但在群组同步(即用户首次完成身份认证)之前并不会真正被分配进项目。
将群组分配给应用
- 在 Okta 中打开应用页面,进入Assignments标签页。
- 选择Assign → Assign to Groups,选择目标群组。
- 将属性Active设为true。
保存群组分配后,更新会进入队列并发送到 Label Studio。如需立即生效,也可以选择将变更即时推送(Push)到 Label Studio。
将群组同步到应用
- 在 Okta 中打开应用页面,进入Push Groups标签页。
- 点击Push Groups,选择Find groups by name。
- 找到要同步到 Label Studio 的群组。
- 选择Create Group(新建群组),或选择Link Group关联到已在SCIM >> Settings页面中指定了同名的既有工作区。
取消群组的分配
取消群组分配的步骤与取消用户分配类似(详见上文“取消用户的分配”):
- 在应用页面进入Assignments标签页。
- 在左侧选择Group。
- 点击目标群组右侧的删除叉号。
- 确认取消分配。
设置 Microsoft Entra ID(Azure AD)SCIM 集成
Label Studio Enterprise 支持与 Microsoft Entra ID(原 Azure AD)进行 SCIM 预配。整体流程与 Okta 类似,但必须配置特定的属性映射。
支持的 SCIM 用户属性(白名单)
Label Studio Enterprise 只支持有限的 SCIM 用户属性集合。在 Entra ID 中配置属性映射时,只能包含下表列出的属性:
| SCIM 属性 | 描述 | 是否必需 |
|---|---|---|
emails[type eq "work"].value | 用户邮箱(主标识符) | 是 |
userName | 用户名(在 Label Studio 中映射为邮箱) | 是 |
active | 用户是否处于活跃状态 | 是 |
name.givenName | 用户名字 | 否 |
name.familyName | 用户姓氏 | 否 |
⚠️不支持的属性会导致预配失败:如果映射了 Label Studio 不支持的属性,SCIM 预配期间会返回HTTP 501 (Not Implemented)错误。必须移除 Entra ID 默认携带的以下多余属性映射:
displayNamepreferredLanguagename.formattedexternalId
配置 Entra ID 预配步骤
在 Microsoft Entra admin center 左侧选择Enterprise apps。
选择你的企业应用。
在左侧选择Provisioning。
将Tenant URL设置为
https://<LABEL_STUDIO_BASE_URL>/scim/v2/。将Secret Token设置为与 Label Studio Owner 账号绑定的 Legacy token。
- 必须是Legacy token,而不是 Personal Access Token;且必须与 Owner 角色的用户关联。
在Mappings下打开Provision Microsoft Entra ID Users。
移除除上述受支持属性之外的所有属性映射,仅保留:
emails[type eq "work"].value→userPrincipalNameuserName→userPrincipalNameactive→Switch([IsSoftDeleted], , "False", "True", "True", "False")name.givenName→givenNamename.familyName→surname
在Mappings下打开Provision Microsoft Entra ID Groups:如需基于群组进行角色分配,请确保其已启用。
对于群组预配,请按上文“在 Label Studio 中配置群组映射”一节配置 SCIM 群组设置。
SCIM 在 Label Studio Enterprise 中的工作流与角色模型
SCIM 工作流一览
SCIM 支持的用户生命周期操作包括:添加用户、移除用户(角色置为 Deactivated)、将用户分配到群组、从群组移除用户、将群组映射为用户角色。群组定义在 IdP 侧,群组到角色的映射定义在 Label Studio 侧——这也是整套架构中职责最清晰的分界。
组织级角色与项目级角色
通过群组映射可以为用户分配两类角色:
- 组织级角色:可以是Annotator、Reviewer、Manager、Administrator。每个群组在组织级只能映射为一个角色;还可以将群组映射到Deactivated角色,这会立即撤销该群组用户的 Label Studio 访问权限。
- 项目级角色:可以是Annotator、Reviewer、Inherit(继承组织级角色)。与组织级不同,一个群组可以在多个项目中被分配多个角色,例如 Group A 在项目 1 中是 Annotator,在项目 2 中可以是 Reviewer。
从源码可以印证这套角色模型:在 label_studio/core/settings/base.py 中,可分配的组织角色枚举(AssignableOrganizationRoleEnum)包含 Owner、Administrator、Manager、Reviewer、Annotator、Deactivated、Not Activated;而RoleSourceEnum明确将角色来源划分为 manual、saml、scim、ldap、api、billing 六类——也就是说,通过 SCIM 分配的角色会在系统内被标记为scim来源,便于审计与后续的增量同步管理。
工作区映射的默认权限模型
将群组分配到工作区时,群组成员会以“工作区成员”身份加入,默认可以访问该工作区下的所有项目。项目内的具体权限取决于其组织级角色;如果需要更细粒度控制,可以通过 SCIM 的“项目级角色”映射覆盖默认行为。
SCIM REST API 端点速查
Label Studio 的 SCIM API 基于 django-scim2 库实现,可通过标准端点对Users与Groups两类资源进行控制。
Users 端点
| 操作 | 端点 | 说明 |
|---|---|---|
| 搜索用户 | GET /scim/v2/Users?filter=userName =<user@email.com>&startIndex=1&count=100 | 用户存在返回200,不存在返回404 |
| 获取用户 | GET /scim/v2/Users/user@email.com | 按邮箱获取用户详情 |
| 创建用户 | POST /scim/v2/Users/ | 请求体需包含邮箱、密码等用户信息 |
Groups 端点
| 操作 | 端点 | 说明 |
|---|---|---|
| 修改群组成员 | PUT /scim/v2/Groups/<group-name> | 更新群组成员列表 |
| 创建群组 | POST /scim/v2/Groups/<group-name> | 创建群组 |
| 获取群组 | GET /scim/v2/Groups/<group-name> | 获取群组详情 |
修改群组成员的请求体示例(SCIM 2.0 Group 标准 schema):
{ "BODY": { "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"], "id": "<group-name>", "displayName": "<group-name>", "members": [ { "value": "<user@email.com>", "display": "<user@email.com>" } ] } }SCIM Settings API
群组到角色、群组到工作区的映射除了可以在应用内Organization > SCIM页面配置外,也可以通过 API 管理:
- 获取 SCIM 设置:
GET /api/scim/settings - 更新 SCIM 设置:
POST /api/scim/settings
这些 API 与页面操作等价,适合在自动化运维或脚本化配置场景下使用。
常见注意事项与最佳实践
- 唯一标识必须用
email:无论是 Okta 还是 Entra ID 集成,用户唯一标识字段都应使用邮箱,而不是userName,否则 SCIM 集成之前已存在的用户无法被正确匹配。 - 请求头必须用 Bearer:Label Studio 中
Token与Bearer指向同一令牌,但 SCIM 提供方(Okta / Entra ID)必须使用Authorization: Bearer <token>头,使用Token前缀会导致认证失败。 - Legacy Token 必须绑定 Owner:SCIM 预配令牌必须是 Legacy token(而非 Personal Access Token),且需与 Owner 角色的用户关联。
- 属性映射白名单:Entra ID 集成中只能保留文档列出的 5 个受支持属性,多余映射会触发 HTTP 501 错误。
- 群组名一致性:Label Studio 侧的群组映射名称必须与 IdP 发送的群组名完全一致,否则映射不会生效。
- 席位与状态:Not Activated 与 Deactivated 用户不计入 seat 配额,可用于在配额紧张时管理用户存量。
- 会话策略豁免:从 label_studio/core/middleware.py 的实现可以看出,SCIM 系统请求被显式排除在会话超时强制登出逻辑之外,这保证了 IdP 触发的后台同步任务不会因会话过期而中断。
延伸阅读
- How SCIM works with Label Studio Enterprise —— SCIM 工作流、API 端点与角色模型的完整说明
- Set up SSO —— SCIM 集成前必须完成的 SSO 配置
- Roles in Label Studio Enterprise —— 组织级与项目级角色的权限矩阵
- Manage users —— 用户与群组管理总览
- Access tokens —— Legacy Token 的生成与使用说明
【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studio
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考