一、RPA 为什么是凭据泄露的重灾区
在财务共享中心、电商客服外包基地、车企研发外包团队、供应链审核部门,RPA 机器人早已不是试验项目,而是每天跑成千上万次的生产设施。它们最大的特点是要"替人登录系统干活"——一个对账机器人可能要登录网银下载流水、登录 ERP 读取应付单、登录银企直连平台发起付款;一个客服机器人要登录 CRM、工单系统、知识库来回切换。问题恰恰出在"登录"这一步:账号和密码从哪来?
1.1 脚本里硬编码口令的现状
在最普遍的做法里,凭据被直接写进代码或配置文件:
# 典型 RPA 脚本片段(存在明显风险)USERNAME="erp_admin"PASSWORD="Prod@2024!Sec"# 明文硬编码driver.find_element("id","user").send_keys(USERNAME)driver.find_element("id","pass").send_keys(PASSWORD)更隐蔽一点的,把密码藏进 Excel 变量表、JSON 配置文件或机器人工程的环境变量里。无论哪种形态,本质上都是"明文凭据随工程资产一起流转"。笔者在多个交付现场看到过这样的情形:机器人工程被提交到代码仓库,凭据随之进入版本历史;机器人镜像被打包分发到几十台执行器,凭据被复制几十份;离职的 RPA 开发者本地还存着一份带密码的工程压缩包。
1.2 硬编码的三类直接后果
第一类后果是泄露面随资产扩散而失控。一份硬编码密码 = 一个永远有效的后门。代码仓库被拖库、执行器被勒索扫描、开发者笔记本丢失,任何一处失守都会把"生产 ERP 管理员口令"直接交到攻击者手里,而且你往往很久之后才发现。
第二类后果是轮换几乎不可能。口令写死在脚本里,一旦要求每 90 天改一次密,你就得改几十个工程、重新打包、重新分发、重新验证,运维成本极高,于是很多团队干脆"能不改就不改",口令一用就是两三年。
第三类后果是操作无法定责。机器人用共享账号 erp_admin 登录,业务系统日志里只看到 erp_admin 登录成功,看不出是哪一个 RPA 流程、哪一台执行器、哪一班定时任务触发。真出了越权操作或数据泄露,责任追溯到"一个机器人"就断了,无法落到具体的流程负责人或审批人。
1.3 为什么传统凭据库救不了 RPA
有人会说:"我们把密码放进一个凭据管理服务,让机器人去读不就行了?"方向对,但只做一半。问题在于:
- 如果机器人读到的是明文口令再自己填,凭据依然会在机器人进程内存里长期驻留,并可能被写入日志或截图;
- 如果凭据库只做存储不做"代填",机器人仍然要把口令落到变量里,泄露窗口只是从"代码文件"挪到了"运行时内存 + 日志";
- 如果凭据库没有和操作身份绑定,系统日志仍然只看到共享账号,定责问题没解决。
真正要做的,是把"托管"和"代填"合二为一:凭据在库里是密文,机器人运行时拿到的只是一次性的填充动作或被加密的临时令牌,明文只在代填代理的内存里短暂出现、用完即清,且整个过程被双身份审计记录。这就是企业密码管理器在 RPA 场景的核心价值。
二、凭据安全供给的核心设计目标
把 RPA 的凭据供给重新设计,需要同时满足四个目标,缺一不可。
目标一:凭据集中托管,源头消除硬编码。所有业务系统账号的口令不再出现在任何脚本、配置、Excel 或镜像里,统一收口到加密保险箱。脚本里只保留"账号别名"或"凭据引用 ID"。
目标二:运行时动态取用,按策略授权。机器人启动流程时,向保险箱申请某个账号的登录能力,保险箱根据"哪个机器人、哪个流程、哪台执行器、是否在工作时段"做授权判定,而不是无差别返回口令。
目标三:密码不落地、内存零驻留。无论是 UI 注入还是 API 注入,明文口令只在代填代理的安全内存区出现于填充瞬间,填充完立即清零,不写磁盘、不进日志、不进剪贴板、不进命令行参数、不进截图。
目标四:操作留痕到人。每次自动登录不仅记录"用了哪个业务账号",还要记录"由哪个机器人身份、哪个流程负责人、哪台执行器发起",让无人值守的自动化也能定责。
三、双架构如何对接 RPA 机器人
RPA 要登录的目标系统形态很杂:既有浏览器里的 Web 后台(网银、CRM、ERP 自助端),也有桌面客户端(金蝶、用友客户端、SAP GUI、Putty、数据库客户端)。因此代填需要两套互补的代理形态——浏览器插件(BS)负责 Web 页面表单填充,桌面代理(CS)负责桌面应用与协议层填充,二者共用同一个加密保险箱与策略中心。
3.1 BS+CS 与 RPA 的三种集成面
| 集成面 | 代填主体 | 适用目标 | 机器人侧改动 |
|---|---|---|---|
| Web 表单 | BS 插件拦截并填充 | 网银、CRM、OA、ERP 自助端 | 机器人只需触发页面操作,不持有口令 |
| 桌面/协议 | CS 代理注入 | SAP GUI、金蝶、用友、Putty、数据库 | 机器人通过本地接口申请代填 |
| API 调用 | 凭据注入代理 | 开放 API、银企直连、内部服务 | 机器人拿到的为短期令牌而非长口令 |
这里的关键差异是:传统做法是机器人自己持有并输入口令,而新做法是机器人"请求一次代填动作",由 BS/CS 代理在受控内存里完成填充。口令的明文生命周期被压缩到代填代理内部。
3.2 凭据托管模型
托管侧需要满足几条硬约束,才能让人放心把生产口令交进去:
vault:cipher:SM4-CBC# 口令数据对称加密keyWrap:SM2# 密钥封装digest:SM3# 完整性校验masterKey:source:hsm-slot# 主密钥由硬件密码机持有,不可导出storage:format:ciphertext-onlyaccess:requireStrongAuth:truemfaOptions:[usbkey,qrscan,otp,fingerprint,face]# 7+ 认证方式可叠加authorization:dimension:[robot,flow,executor,timeWindow]# 多维授权以安当SYP为例,它的保险箱采用 HSM 级加密,主密钥由硬件密码介质持有,口令在库内始终是密文;对外提供的是"代填动作"而非"明文口令",并且支持 USBKey、扫码、动态口令、指纹、人脸等 7 种以上认证方式的可叠加组合,以及按机器人、流程、执行器、时段的多维授权。对 RPA 场景而言,这意味着生产口令从脚本里消失的同时,谁(哪个机器人)能发起对哪个账号的代填,仍然被严格策略约束,不会变成"谁都能代填"。
3.3 为什么代填比"读明文"更安全
代填的本质是把"取口令"替换为"申请动作"。保险箱返回给机器人的不是password=xxx,而是一个一次性的代填指令或临时令牌;真正的明文解密与填充发生在本地代理的安全内存区。即便机器人工程被反编译、执行器被入侵,攻击者拿到的也只是"申请代填的权限",而权限本身还受设备绑定、时段、复核等策略限制,且每一次尝试都被审计。攻击面从"全量口令明文"收敛为"受控的代填授权",量级完全不同。
四、RPA 代填的三条路径
根据目标系统的接口形态,代填可分三条路径落地,适用面与改造量各不相同。
4.1 路径一:UI 自动化注入(UI Automation Injection)
目标系统只有图形界面、没有开放 API(典型如老 ERP 客户端、SAP GUI、网银页面、Putty)。此时代填代理监听机器人的 UI 操作信号,在需要填用户名的控件出现时,由本地代理从保险箱取密文、本地解密、把明文写入控件,随即清零。机器人脚本里完全不出现口令,只描述"在用户名框输入 {cred:erp_admin}"这样的引用。
这种路径的最大优势是目标系统零改造——它收到的是和真人手工登录完全一致的输入事件。代价是依赖控件识别的稳定性,需要为不同系统的登录窗体做控件映射。
4.2 路径二:API 凭据注入(API Credential Injection)
目标系统提供 API(典型如银企直连、内部服务、开放平台)。此时代填代理不直接碰 UI,而是拦截机器人的 HTTP/SDK 调用,把长口令替换为短期令牌或动态签名。例如机器人要调用付款接口,脚本里写client.call(api, token=凭据引用),代理在出口处把"凭据引用"换成校验通过的短期令牌,并附上机器人身份标识。
这种路径更适合高频、无人值守的批量流程,且天然便于在请求头里带上"机器人身份"字段,使后端审计能区分自动化流量与人工流量。
4.3 路径三:凭证库按角色授权(Role-based Vault)
与前两条"怎么填"的路径不同,这条解决"谁有权填"。把 RPA 机器人按业务角色分组(财务对账机器人组、客服工单机器人组、研发物料机器人组),每个角色被授予一组明确的账号引用集合,而非具体口令。角色变更、人员离职时,只需在策略中心调整授权,无需改任何脚本,也无需重新分发口令。
角色: finance-bot-role 可代填账号: [netbank-readonly, erp-payable-ro, cbs-query] 不可代填: [erp-prod-admin, db-root] 角色: service-bot-role 可代填账号: [crm-agent, ticket-system, kb-readonly]三条路径的对比归纳如下:
| 对比维度 | UI 自动化注入 | API 凭据注入 | 凭证库按角色授权 |
|---|---|---|---|
| 适用系统 | 仅图形界面 | 提供 API 的系统 | 所有(授权层) |
| 目标系统改造 | 零改造 | 零改造(代理拦截) | 零改造 |
| 明文出现位置 | 代理内存(瞬时) | 代理内存(瞬时) | 不出现 |
| 机器人侧改动 | 口令改引用 | 口令改引用/令牌 | 按角色授予引用 |
| 身份粒度 | 机器人+账号 | 机器人+账号+请求 | 角色+账号 |
五、代填时序与伪代码
光讲路径还不够,下面用时序和伪代码把"一次安全代填"在计算机里到底发生了什么讲清楚。
5.1 代填时序(文本描述)
[RPA 机器人] -- 触发登录步骤,携带 credRef + 机器人身份 --> [CS/BS 代填代理] | | 1. 代理校验机器人身份(设备指纹/流程令牌)与时段策略 v [加密保险箱] <-- 申请 {credRef 的密文 + 授权判定} --> [CS/BS 代填代理] | | 2. 保险箱返回密文(不返明文),并记录"某机器人申请某账号" v [CS/BS 代填代理] -- 本地硬件介质解密,明文仅栈帧内 --> [目标系统登录框/API] | | 3. 把明文填入控件 / 替换为短期令牌,随即 memset 清零 v [目标业务系统] -- 登录成功 --> [代填代理写审计双身份] --> [审计存证(只写)]注意三步关键约束:第一步代理先验证"谁在申请",不验证就谈不上安全;第二步保险箱只返密文、不自揭明文;第三步填充完立即清零,明文存活窗口小于单次登录耗时。
5.2 代填伪代码(Python 风格)
defrpa_login_step(cred_ref:str,robot_ctx:RobotContext):# 1. 代理先校验机器人身份与策略policy=vault.check_policy(cred_ref,robot_ctx)ifnotpolicy.allowed:audit.deny(robot_ctx,cred_ref,reason=policy.reason)raisePermissionError("代填未授权")# 2. 向保险箱申请密文(注意:不申请明文)cipher=vault.fetch_cipher(cred_ref,token=robot_ctx.session_token)# 3. 本地硬件介质解密,明文仅存在于 with 块内withzero_resident(cipher)asplain:# 退出作用域自动清零target.fill("username",robot_ctx.account_alias)target.fill("password",plain)# 注入控件或换成 API 令牌target.submit()# 4. 双身份审计落存证(只写不可改)audit.record(robot_id=robot_ctx.robot_id,flow_owner=robot_ctx.flow_owner,executor=robot_ctx.executor_host,account=cred_ref,target_system=target.name,when_ms=now_ms(),result="success",)这段伪代码刻意体现了四个要点:不申请明文、明文用zero_resident上下文管理、填充后随作用域销毁、审计同时写机器人身份与业务账号。
5.3 内存零驻留的硬性要求
内存零驻留不是"用完不保存"这么简单,要落实到三条工程纪律:(1) 明文口令使用可变字节缓冲,填充后立即用零字节覆盖再释放,不能被 GC 的"幽灵副本"残留;(2) 明文不得进入任何会被持久化的对象——日志器、截图器、异常栈、序列化器都要在代填路径上被屏蔽;(3) 不同代填会话之间严格隔离,禁止复用同一明文缓冲跨账号跨系统。只要有一条没守住,零驻留就破了。
六、操作留痕到人:机器人身份 + 业务账号
RPA 的定责难,根子在"日志里只有共享账号,没有机器人"。解决思路是把两个身份同时写入审计。
6.1 双身份审计模型
| 身份维度 | 字段 | 含义 | 采集来源 |
|---|---|---|---|
| 机器人身份 | robot_id | 哪个机器人流程 | 流程定义与执行器注册 |
| 负责人身份 | flow_owner | 流程归属人/团队 | RPA 治理台账 |
| 执行器身份 | executor_host | 哪台执行器运行 | 设备指纹 |
| 业务账号 | account | 被代填的共享账号 | 凭据引用 |
| 目标系统 | target_system | 登了什么系统 | 代填协议层 |
| 时间 | when_ms | 何时发生 | 代理事件时钟 |
当一条审计同时包含这六个维度,监管或安全团队问"是谁用 erp_admin 在昨晚改了付款模板"时,答案不是"机器人",而是"财务对账机器人 R-019,归属张三团队,运行于执行器 EX-03,于 23:14:02 用 erp_admin 登录 ERP 生产后台"。自动化第一次变得可定责。
6.2 与共享账号审计的衔接
RPA 机器人本质上也是一种"共享账号使用者",它和人工外包人员共用同一套代填与审计基础设施反而是好事:无论登录来自真人还是机器人,审计五元组(谁、何时、哪个账号、登什么系统、从哪台设备)口径一致,避免"人走的审计和机器人走的审计对不上"的割裂。这正是账号审计追溯在工程上最该统一的环节。
七、与统一认证 / 零信任的边界
企业里往往已经有统一认证(SSO/IAM)和零信任网关,那么凭据安全供给和它们是什么关系?必须划清边界,否则容易职责重叠、出现安全盲区。
7.1 边界划分
统一认证/SSO : 负责"人"的身份——员工用 USBKey/扫码登录企业门户 零信任网关 : 负责"访问通道"——按设备 posture 与身份放行到业务系统 凭据安全供给 : 负责"账号口令本身"——共享/特权账号的托管、代填、审计三者的关系不是替代,而是分层:统一认证解决"你是谁",零信任解决"你这条通道能不能通",凭据安全供给解决"通了之后用的那个业务账号的口令如何安全呈现与留痕"。很多老系统并不支持 SSO、也不在零信任网关的纳管范围内(典型如专用终端、老 ERP、数据库客户端),这些恰恰是最需要代填兜底的地方。
7.2 边界对照表
| 能力 | 统一认证/SSO | 零信任网关 | 凭据安全供给(代填) |
|---|---|---|---|
| 身份对象 | 自然人员工 | 设备+自然人 | 业务账号+机器人 |
| 解决痛点 | 多系统重复登录 | 通道访问控制 | 口令明文与定责 |
| 对老系统 | 常需改造 | 需接入网关 | 零改造代填兜底 |
| 审计视角 | 人登录了门户 | 通道被放行 | 人/机器人登了某业务账号 |
| 互补关系 | 上游身份源 | 通道层 | 落地层凭据呈现 |
以安当SYP为例,它把代填放在"落地层",与上游统一认证、中游零信任网关形成互补而非竞争:上游给"真人身份"、中游给"通道放行"、代填层给"业务账号的安全呈现与留痕"。对于无法改造、不敢改造的老系统,代填层是让它们也能进入统一审计视野的关键一环,避免出现"零信任覆盖不到的老系统成了审计黑洞"。
八、落地指标:用数字衡量安全收益
一项安全改造值不值得做,要看能不能被量化。RPA 凭据供给改造后,建议跟踪以下三类指标,并用脚本持续度量。
8.1 三项核心指标
| 指标 | 定义 | 改造前典型值 | 改造后目标 |
|---|---|---|---|
| 硬编码消除率 | 含明文口令的脚本/配置占比 | 60%~100% | 0% |
| 泄露面收敛度 | 可独立导致口令泄露的资产数 | 数十份(代码/镜像/Excel) | 1 处(保险箱) |
| 审计覆盖率 | 自动登录被双身份审计覆盖的比例 | 接近 0% | 100% |
8.2 用脚本自测"硬编码消除"
落地的第一步是能自查。下面一段伪代码用于在机器人工程仓库里扫描是否还有明文口令残留,作为持续集成里的卡点:
importre,os# 匹配疑似硬编码凭据的模式(示例,可按企业规范扩充)patterns=[r'password\s*=\s*["\'][^"\']{6,}["\']',r'pwd\s*=\s*["\'][^"\']{6,}["\']',r'passwd\s*=\s*["\'][^"\']{6,}["\']']defscan_repo(root):leaks=0fordirpath,_,filesinos.walk(root):forfinfiles:iff.endswith((".py",".json",".yaml",".xlsx")):p=os.path.join(dirpath,f)forlineinopen(p,encoding="utf-8",errors="ignore"):ifany(re.search(pat,line)forpatinpatterns):leaks+=1print("LEAK",p,line.strip()[:80])returnleaksif__name__=="__main__":assertscan_repo("./rpa_projects")==0,"仍存在明文凭据硬编码"当这个扫描在 CI 里稳定返回 0,才说明"硬编码消除"真正落地,而不是停留在口头要求。
8.3 泄露面与审计覆盖的度量思路
泄露面收敛度可以用"可独立导致口令泄露的资产清单"条目数来度量——改造前这份清单可能有代码仓库、镜像、Excel、本地备份、聊天记录若干项,改造后理论上只剩"加密保险箱 + 硬件密码介质"一处,且这一处还有 HSM 与多维授权守护。审计覆盖率则用"被双身份审计覆盖的自动登录次数 / 总自动登录次数"来算,目标拉到 100%,任何一次未被审计的代填都要在治理看板上告警。
方案参考
面向要把 RPA/自动化流程机器人纳入凭据安全治理的团队,给出一套通用落地建议,不绑定具体产品,供架构、安全与 RPA 治理同学参考:
治理层面
- 先对全部 RPA 流程做一次凭据盘点,列出每个机器人登录了哪些系统、口令当前以什么形态存在(代码/配置/Excel/镜像),建立"明文凭据资产清单"。
- 把"口令不进脚本、代填不落明文、操作可追溯"写进 RPA 开发规范,作为流程上线前的强制检查项。
- 为机器人建立角色分组与流程负责人台账,让每一个自动登录都能对应到团队与执行器,避免无人定责。
技术层面
- 口令集中收口到加密保险箱,采用国密算法体系,主密钥来源于硬件密码介质,落库即密文、明文不驻留。
- 机器人脚本只保留账号引用或凭据 ID,运行时通过受控接口申请代填动作而非明文口令,明文只在代填代理内存里瞬时出现、用完即清。
- 代填按目标系统形态选路径:图形界面走 UI 自动化注入,开放 API 走 API 凭据注入,授权统一走凭证库按角色分配。
- 认证多因子可叠加、授权按机器人/流程/执行器/时段多维收敛,高危账号启用复核。
- 审计与凭据职责分离,审计只写不可改,每次代填同时记录机器人身份与业务账号双身份。
度量层面
- 以"硬编码消除率、泄露面收敛度、审计覆盖率"三项指标衡量改造成效,并在 CI 中加卡点扫描明文口令残留。
- 把 RPA 代填审计与人工共享账号审计统一到同一套五元组合规视图,避免自动化流量与人工流量在审计上割裂。
- 明确凭据留存与轮换策略,机器人使用的共享账号同样纳入定期改密与权限回收,到期自动回收授权并留记录。
上述治理、技术、度量三类要点,是任何企业密码管理器或共享账号管理方案在 RPA 场景落地时都应满足的方法论框架。把凭据从脚本里收回到保险箱、把明文窗口压缩到内存瞬时、把每一次自动登录都留痕到双身份,三件事串起来,就能在百度搜索关注的"凭据安全"“密码代填”“密码不落地”“运维密码管理”"账号审计追溯"等维度上,形成对自动化流程可管、可审、可定责的闭环。