尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Label Studio Redact Annotator PII 插件:基于 whoami 角色鉴权的标注者身份脱敏方案
Label Studio Redact Annotator PII 插件:基于 whoami 角色鉴权的标注者身份脱敏方案【免费下载链接】label-studioLabel Studio is a multi-type data labeling and annotation tool with standardized output format项目地址: https://gitcode.com/GitHub_Trending/la/label-studioLabel Studio 提供了一款名为Redact Annotator PII的标注接口插件,用于在标注流与审核流中隐藏标注者的姓名、头像和日期等个人可识别信息(PII),从而降低多人协作标注中的身份偏见,并仅在用户为组织管理员时自动恢复可见性。本文以官方插件文档 Redact Annotator PII 为主线,完整给出其 Labeling 配置、插件脚本与示例数据,并结合开源仓库中whoami接口的真实实现(用户 URL 注册、接口实现),解析这套CSS 默认隐藏 脚本按角色解禁的脱敏机制底层原理。读完后,你将能够:为项目配置一套可复制运行的 PII 脱敏方案,并理解角色判定、样式移除等关键细节在源码中的落点。插件定位与双层工作原理该插件面向的核心场景是:当多个标注者在同一批任务上产出标注时,标注者之间可能因为知道这条标注是谁做的而产生从众、权威效应等偏见;在审核(Review)阶段,审核者知道被审标注的作者身份同样会引入偏差。因此该插件的目标是对普通标注者/审核者匿名化标注者信息,同时对管理员保留完整信息以便追溯。从文档给出的实现看,整套方案由两层机制配合完成:Labeling 配置层(默认隐藏):通过Style标签注入 CSS,把标注按钮上的用户名、头像、日期,以及评论、标注历史中的人名/日期/头像元素的display全部置为none。这一层不依赖任何脚本,只要配置生效,所有用户在标注流与审核流中看到的 PII 都是被遮蔽的。插件脚本层(按角色恢复):JavaScript 插件在每次标注展示时执行,通过平台的whoami接口获取当前登录用户的组织角色;如果角色是管理员(枚举值AD),就移除 Labeling 配置中注入的Style节点,从而反隐藏PII。需要说明的是,该文档在 front-matter 中标记为tier: enterprise,即这一完整能力在 HumanSignal/Label Studio Enterprise 的产品语境下提供;文档中脚本硬编码了 SaaS 域名的 whoami 地址,自建部署时对应的是站点自身的/api/current-user/whoami路径(下文结合源码说明)。插件本身的编写规范——包括事件订阅、LSI接口对象与调试面板——参见 Customize and Build Your Own Plugins;插件的通用背景与常见问题可查 Plugins for projects 与 Plugin FAQ。Labeling 配置:用 CSS 在标注/审核流中隐藏 PII文档给出的完整 Labeling 配置如下,这是一个文本情感分类示例:最外层View通过idAttrnoPII给整个视图容器打上noPII属性(供脚本定位),内部Style负责遮蔽 PII 元素,业务部分则是Text展示加单选Choices:View idAttrnoPII Style .lsf-annotation-button__user { display: none; } .lsf-userpic { display: none; } .lsf-annotation-button__userpic { display: none } .lsf-annotation-button__date { display: none; } .lsf-comment-item__name { display: none; } .lsf-comment-item__date { display: none; } .lsf-comment-item__userpic { display: none; } .lsf-history-item__name { display: none; } .lsf-history-item__date { display: none; } /Style Text nametext value$text / View stylebox-shadow: 2px 2px 5px #999; padding: 20px; margin-top: 2em; border-radius: 5px; Header valueChoose text sentiment / Choices namesentiment toNametext choicesingle showInLinetrue Choice valuePositive / Choice valueNegative / Choice valueNeutral / /Choices /View /View这组 CSS 选择器覆盖了三类界面元素,可整理为如下对应关系:选择器隐藏的对象.lsf-annotation-button__user标注/审核按钮上显示的用户名.lsf-userpic、.lsf-annotation-button__userpic各处头像图片.lsf-annotation-button__date标注按钮上的操作日期.lsf-comment-item__name、.lsf-comment-item__date、.lsf-comment-item__userpic评论区中的评论者姓名、时间与头像.lsf-history-item__name、.lsf-history-item__date标注历史条目中的作者名与时间其中idAttrnoPII的作用是把noPII这个属性写到根View渲染出的 DOM 元素上,使插件脚本能够用document.getElementById(noPII)精确找到这段配置所渲染出的容器,再删除它下面的Style子节点——这是CSS 隐藏与脚本解禁两层之间唯一的衔接点。相关标签的用法详见 View、Style、Text、Header、Choices。插件脚本:基于 whoami 的角色化恢复文档提供的完整插件脚本如下:/* Hide annotator personal information (PII) if the logged user is not an Admin */ /** * Fetch currently logged user via the HumanSignal API */ async function fetchUserInfo() { const whoamiUrl https://app.humansignal.com/api/current-user/whoami; const response await fetch(whoamiUrl, { method: GET, headers: { Content-Type: application/json, // No Auth credentials needed for same-origin given Session-Based Authentication is used in the API } }); if (!response.ok) { throw new Error(Error: ${response.status} ${response.statusText}); } const data await response.json(); return data; } /** * Give visibility to the given selector */ function displayEl(sel) { const els document.querySelectorAll(sel); if (els) { els.forEach(function (el, idx) { el.style.display block; }); } } /** * If the logged in user is an Admin, remove the styling added to the view that hides * the annotator identity */ async function hidePII() { let user, role try { const userInfo await fetchUserInfo(); user userInfo.username || Unknown; role userInfo.organization_membership.role || Unknown; } catch (error) { Htx.showModal(Error fetching user information: ${error.message}); } if (!user) { console.warn(Did not find a username and it was not Unknown); return; } if (role AD) { // console.log(Role is admin; displaying PII); // If admin, remove the nulled Style tag const firstChild document.getElementById(noPII).firstChild; if (firstChild.tagName STYLE) { firstChild.remove(); } } } (async () { await hidePII(); })();脚本的执行链条可以拆解为四步:fetchUserInfo():向 whoami 接口发起 GET 请求。按注释说明,由于该接口使用基于 Session 的认证且请求为同源的,浏览器会自动携带会话凭证,无需额外credentials配置;非 2xx 响应会抛错进入catch。hidePII():从响应中取出username与organization_membership.role两个字段,分别兜底为Unknown。如果拉取失败,通过Htx.showModal弹出错误提示(这是插件运行环境中可用的界面提示能力)。角色判定:仅当role AD时才执行恢复逻辑。样式移除:定位noPII容器的第一个子节点,确认其是STYLE标签后调用remove()将其从 DOM 中删除——注意是移除整个 Style 节点而非逐条改回display,因此恢复效果干净彻底。非管理员用户则不做任何操作,PII 保持 CSS 遮蔽状态。脚本末尾的 IIFE(async () { await hidePII(); })();使整个流程在插件被调用时异步自执行,契合插件运行在异步上下文、可使用await的执行模型。另外,脚本中保留了一个未参与主流程的displayEl(sel)工具函数,用于把指定选择器的元素重新设为display: block;它体现了一种备选恢复思路(逐个恢复元素),而当前主实现选择的是整块移除Style。whoami 接口在仓库源码中的落点文档脚本里写死了 SaaS 域名https://app.humansignal.com/api/current-user/whoami;对于自建部署,对应的就是本仓库中注册的同名路径。在 users/urls.py 中可以看到该路由:path(api/current-user/whoami, api.UserWhoAmIAPI.as_view(), namecurrent-user-whoami),其视图实现见 users/api.py:UserWhoAmIAPI继承自generics.RetrieveAPIView,要求IsAuthenticated,get_object直接返回request.user,即以当前会话用户作为查询对象,响应由WhoAmIUserSerializer序列化。该序列化器在 users/serializers.py 中定义为BaseWhoAmIUserSerializer,在基础用户字段之上额外附带了permissions字段:class BaseWhoAmIUserSerializer(BaseUserSerializer): permissions serializers.SerializerMethodField() class Meta(BaseUserSerializer.Meta): fields BaseUserSerializer.Meta.fields (permissions,) def get_permissions(self, user) - list[str]: return [perm for _, perm in all_permissions]脚本读取的username与organization_membership.role正是这一用户序列化输出的一部分。而role AD这个判定依据的角色枚举,在 core/settings/base.py 的 OpenAPI 枚举定义中可以得到印证:OrganizationRoleEnum包含OW(Owner)、AD(Administrator)、MA(Manager)、RE(Reviewer)、AN(Annotator)、DI(Deactivated)、NO(Not Activated)、VO(View Only),其中AD即文档脚本中用于判定管理员的取值。此外,前端模板(如 users/user_account.html)也通过{% url current-user-whoami %}调用同一接口,说明 whoami 是平台内通用的我是谁查询入口,插件只是复用了它。示例数据文档配套了三条文本分类样例,与 Labeling 配置中的$text字段对应,可直接用于导入测试:[ { data: { text: I recently purchased a portable Bluetooth speaker and have been impressed with its clear sound and long battery life. The speaker is compact and easy to use, making it perfect for outdoor adventures. } }, { data: { text: I bought a smartwatch from this vendor and it has exceeded my expectations. The device offers an intuitive user interface and tracks my daily activities accurately while looking very stylish on my wrist. } }, { data: { text: I ordered a pair of noise-cancelling headphones and they dont do anything to cancel out noise. Waste of money. } } ]配置上述 Labeling 配置与示例数据后:普通标注者/审核者进入标注流与审核流时,标注按钮、评论区与标注历史中的用户名、头像、日期均不可见;管理员进入同一界面时,Style节点被插件移除,身份信息完整可见。适用边界与限制文档特别强调了几条边界,配置该方案前应明确:遮蔽范围有限:Labeling 配置中的 CSS 只作用于标注流与审核流界面,不会遮蔽 Data Manager(数据管理界面)中的标注者信息。若需要连 Data Manager 也限制访问,文档建议通过 项目设置 禁止 Annotator 与 Reviewer 角色访问 Data Manager,从权限层面补齐。whoami 地址随部署形态变化:文档脚本中的 whoami URL 是 HumanSignal SaaS 域名,依赖同源会话认证;自建部署时应把该 URL 指向自身站点的/api/current-user/whoami路径(路由定义见 users/urls.py),否则会因跨域或域名不存在导致fetch失败并弹出错误提示。执行模型:按 自定义插件文档 的说明,插件在每次标注展示时都会执行一次(打开任务、切换任务/标注、查看历史版本等场景)。本插件的恢复逻辑是幂等的——非管理员路径不操作 DOM,管理员路径删除的是当前这一次渲染中的Style节点,下一次标注展示时 DOM 重新渲染、脚本重新执行,天然不会累积副作用;但如果你要在此基础上扩展(例如用displayEl逐元素恢复),仍需遵循避免重复订阅事件、做好运行间清理的插件开发规范。角色判定仅识别AD:当前脚本只把AD(Administrator) 视为可见 PII 的角色,OW(Owner)、MA(Manager) 等其他角色同样会被遮蔽;如需扩大解禁范围,需要自行扩展role的判定条件。参考与延伸阅读插件文档主体:Redact Annotator PII插件开发与调试(Testing 面板、LSI接口、debugger):Customize and Build Your Own Plugins插件总览与安全注意事项:Plugins for projects插件 FAQ:Plugin FAQ前端界面事件与结构参考:Frontend reference源码证据:whoami 路由、UserWhoAmIAPI、BaseWhoAmIUserSerializer、组织角色枚举【免费下载链接】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),仅供参考
RELATED

相关推荐

Ubuntu、RHEL、OEL谁更适合AI服务器?从GPU生态到实战踩坑分析

Ubuntu、RHEL、OEL谁更适合AI服务器?从GPU生态到实战踩坑分析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/9/13 16:59:59
Opik E2E 测试失败排查指南:基于 debugging-e2e-tests 技能的证据驱动调试方法论

Opik E2E 测试失败排查指南:基于 debugging-e2e-tests 技能的证据驱动调试方法论

Opik E2E 测试失败排查指南:基于 debugging-e2e-tests 技能的证据驱动调试方法论 【免费下载链接】comet-llm Debug, evaluate, and monitor your LLM applications, RAG systems, and agentic workflows with comprehensive tracing, automated evaluations, and p…

📅 2026/9/13 16:59:59
Java日志安全:防止敏感信息泄露的实践指南

Java日志安全:防止敏感信息泄露的实践指南

1. 为什么Java日志泄露如此普遍? Java应用中的日志泄露问题之所以普遍存在,根本原因在于开发过程中对日志功能的滥用和错误认知。根据OWASP的统计,超过60%的Java应用在生产环境中存在敏感信息泄露风险,而其中90%的案例与日志记录不…

📅 2026/9/13 16:54:59
MORE NEWS

更多资讯

📰

Refine + Ant Design useTable 列过滤实战:FilterDropdown 与 Radio 组件的完整实现

Refine Ant Design useTable 列过滤实战:FilterDropdown 与 Radio 组件的完整实现 【免费下载链接】refine A React Framework for building internal tools, admin panels, dashboards & B2B apps with unmatched flexibility. 项目地址: https://gitcode.c…

📰

蓝牙无线遥控器实现指南:SPP透传、AT指令与帧协议设计

简介:一套基于蓝牙技术的多路无线遥控设计资料,面向电子爱好者、嵌入式开发者以及智能家居、工业自动化领域初学者,围绕蓝牙模块、51单片机与继电器控制展开,帮助读者搭建由手机或专用遥控器远程操控设备的完整系统。压缩包共24个…

📰

嵌入式软件架构实战:轻量级模块化设计与事件驱动方法

1. 这不是讲理论的架构课,是嵌入式工程师每天要面对的真实战场 “嵌入式开发别再堆代码了!”——这句话我第一次听到是在三年前,当时正带着一个车载ECU项目赶交付,凌晨两点改第17版CAN报文解析逻辑,手边是三份不同版本…

📰

嵌入式硬件调试三支柱:示波器验证、设备树电路化、寄存器探针

1. 为什么“双非”背景做嵌入式,光靠刷题和简历包装根本走不通?“双非进大厂”这六个字,在嵌入式圈子里不是励志口号,而是实打实的生存压力测试。我带过37个应届生做过真实项目交付,其中21个来自双非院校——他们中最终…

📰

基于机器学习的恶意URL检测:从特征工程到模型调优全解析

简介:面向计算机相关专业学生与机器学习初学者的恶意URL检测项目资源,围绕基于机器学习算法识别恶意网址的核心任务,提供完整可运行的工程实现,适合课程设计、期末大作业或毕业设计参考。压缩包内共15个文件,包含Pytho…

📰

Zola 多语言站点搭建完全指南:配置、内容组织与输出路径

Zola 多语言站点搭建完全指南:配置、内容组织与输出路径 【免费下载链接】zola A fast static site generator in a single binary with everything built-in. https://www.getzola.org 项目地址: https://gitcode.com/GitHub_Trending/zo/zola Zola 静态站点…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬