阅读需 8 分钟

锁定的本地保险库访问:智能体工作运行手册

为自主智能体规划锁定的本地保险库访问,明确解锁窗口、运行授权、逐次调用决策、暂停规则和审查证据。

锁定的本地保险库访问:智能体工作运行手册

当人们把锁定的本地保险库当成不便时,自主工作往往会以一种非常可预测的方式失败。智能体在任务进行到一半时遇到凭据边界,有人觉得必须赶紧完成,于是机密被复制到 shell 变量、配置文件或聊天消息中。眼前的任务完成了,但团队也创建了一条未被追踪的凭据路径,它的寿命会超过这项任务。

智能体开始工作前,锁定的保险库就应该影响工作计划。操作员需要分别决定三件事:什么时候解锁访问权限,哪个智能体进程可以在本次运行中执行操作,以及哪些单独操作仍需要人工决定。把这些决定合并成一句含糊的“可以了”,团队要么会被提示淹没,要么最终绕过控制措施。

这不是要求有人盯着每条命令。重点是把人的注意力放在真正能改变结果的地方。只读发现通常可以在有边界的会话中运行。生产环境删除、权限变更或发布版本,应在操作发生的那一刻重新获得决定。其他部分则取决于一份操作员在智能体开始前就能看懂的运行计划。

解锁窗口需要负责人和结束时间

操作员应在明确的工作窗口内解锁本地保险库,指定一名负责做决定的人,并明确关闭窗口的条件。“我工作时一直开着”听起来很实用,但会议、午餐、电脑休眠或工作上下文切换都会让它失效。保险库一旦保持开放,就会变成没人主动关注的权限。

在这条链路中,解锁决定授予的是最广泛的访问权限。如果保险库保持锁定,任何智能体会话和任何单独请求都不应通过它。这样锁定状态才有实际价值,但前提是团队把它当成操作边界,而不是一次形式化的登录步骤。

让工作窗口配合任务自然的节奏。一次范围很小的修复可能只需要一个短窗口。计划中的迁移可能需要覆盖准备、执行和验证的窗口,并在任何不可逆阶段前安排暂停。只读取日志的调查,应使用与后续修改生产设置不同的窗口。

开放访问前,操作员应写下五项内容:

  • 谁负责授权决定;
  • 智能体可以执行什么工作;
  • 工作可以接触哪些环境和账户;
  • 什么条件会结束窗口;
  • 如果负责人必须离开,由谁审查结果。

这份记录不需要隆重的仪式。只要写出了真实边界,工单评论或运行备注就足够。“修复部署问题”不够具体。“检查失败的 staging 部署,只有在镜像摘要与已批准构建匹配时,才重试指定的部署”才给了审查者可以验证的内容。

不要只用时钟作为结束条件。明确的关闭时间很有帮助,但智能体发现意外依赖后,工作经常会延迟。把时间限制和状态限制结合起来:完成计划中的验证后关闭,发现第一个意外目标后关闭,或负责人离开时关闭。超出计划的任务应请求新的窗口。这个小小的中断会迫使某个人重新判断,原来的授权是否仍然适合当前工作。

常见的替代做法是追求永久便利:早上解锁,晚上锁定。团队选择它是因为解锁会打断流程。对于自主工作,这是错误的默认设置,因为智能体可以以机器速度继续运行,而原本支持授权的人的注意力已经转移到别处。如果反复解锁让人无法接受,就改进任务批处理和审批设计,不要移除边界。

保险库解锁、运行授权和操作授权回答的是不同问题

锁定的本地保险库需要三个不同的决定,因为每个决定控制的是不同的风险。解锁回答的是是否允许凭据操作发生。运行授权回答的是这个已识别的智能体进程是否可以在有限范围内使用可用的操作路径。单独调用授权回答的是这一次使用这项凭据,是否值得重新交给人来决定。

团队经常把前两个决定混为一谈。他们解锁保险库,就以为机器上的每个进程现在都有权执行操作。这样一来,原本的物理存在或本地存在检查,就变成了广泛的软件授权。另一种糟糕模式是对每个无害请求都进行批准,因为团队从未说明会话授权意味着什么。操作员随后批准几十个例行读取,最后不再阅读审批卡片。

当任务发生变化时,这种区分尤其重要。假设智能体获准检查失败的构建、查询部署 API 和收集日志。它发现缺少权限可能是失败原因。原来的运行不包括修改访问控制。即使保险库已经打开、进程会话仍然获准,智能体也应停止并请求新的决定。任务目的已经从诊断变成了管理。

合理的划分可以是:

  • 在负责的人员能够监督计划工作期间解锁访问权限。
  • 为本次运行批准一个已识别的智能体进程,包括符合运行约定的常规操作。
  • 对高影响调用单独审批,例如发布、删除、修改权限、轮换凭据或写入生产环境。

具体的操作类别因团队而异。重点是按影响后果分类,而不是按 API 调用数量分类。一次撤销生产账户的请求,比五十次获取构建元数据的请求更值得关注。

这正是 Sallyport 的固定决策阶梯刻意保持狭窄的地方:保险库锁定时,保险库闸门会阻止所有操作;逐会话授权会为一个新的智能体进程在其生命周期内提供授权;逐密钥设置则可以要求每次使用都获得批准。这个设计不要求操作员编写一种策略语言,也不会让策略语言在故障期间变成另一个需要排查的安全程序。

不要声称逐次调用闸门会让任何凭据都安全。它只是让人在使用点做出决定成为可能。操作员仍需要足够的上下文来判断请求。如果提示只有“使用生产令牌”,这个控制措施的大部分价值已经丧失。把目标、操作和预期影响写入运行计划,然后将请求与计划进行比较。

根据工作状态安排访问,而不是根据办公时间

团队应把智能体工作规划成一系列状态,并明确权限开始、暂停、收窄或结束的节点。办公时间有助于安排人员,但不能描述实际工作。任务可能在有人值守时开始,等待外部系统,然后在批准它的人离开很久之后恢复。

在任务记录中使用四种状态:准备、执行中、暂停和审查。准备状态不执行需要凭据的操作。智能体可以检查代码仓库、整理命令、验证输入,并在没有保险库访问权限的情况下说明计划调用。只有操作员打开访问窗口并批准运行后,执行状态才开始。暂停表示智能体遇到了等待条件、意外决定或已批准范围的终点。审查则在团队为相关后续工作授予权限前完成闭环。

这个简单的状态模型可以避免一个常见故障。工程师在 4:30 启动智能体清理部署。智能体运行测试,找出过期资源,然后等待云操作完成。5:15,它恢复运行,发现另一个账户也需要清理,并因为会话仍然存在而继续执行。原来的操作员已经离开。即使每次 API 调用都成功,团队也已经允许任务在没有责任人决定的情况下扩展到新的范围。

在运行前写好暂停规则。好的暂停规则应当可以观察和判断:

  • 如果目标账户、主机或环境与运行备注不同,就停止;
  • 如果智能体需要计划中没有列出的凭据类别,就停止;
  • 在任何创建、删除、发布或修改权限的操作前停止;
  • 写入失败后停止,等待操作员检查返回的错误;
  • 指定的操作员无法提供支持时停止。

暂停不是失败,而是一次清晰的状态转换。智能体应保存它原本要执行的确切命令或请求、收集到的输入,以及停止的原因。这样下一个操作员就能做出决定,不必从嘈杂的聊天记录中重新拼出任务。

这也能让紧迫性保持真实。如果一个非工作时间的任务需要执行某项操作,就必须有人决定业务影响是否值得打开新的访问窗口。团队有时会因为智能体已经工作了十分钟,就把每个受阻任务称为紧急任务。这是沉没成本思维。凭据边界应当在情况发生变化时,让人重新做出选择。

运行获得信任前,进程身份必须清晰可见

审批不应只通过终端标签或用户提供的名称来识别智能体进程。名为“deploy-agent”的进程可能是预期的可执行文件、本地脚本,也可能是由受攻击的依赖项启动的程序。操作员需要了解发起并启动请求权限的程序是谁。

代码签名身份很有用,因为它把审批决定绑定到可执行程序的权威身份,而不是任何进程都能打印出来的文本。它不能证明给智能体的每个提示都是明智的,但能更有力地回答一个基本的事故问题:哪个进程获得了使用保险库的权限?

要求运行备注写明智能体入口点,以及工作目录或代码仓库。这样操作员在批准前可以进行两项检查:系统显示的进程身份,以及团队预期的任务上下文。如果两者不一致,就拒绝请求并检查机器。不要因为任务看起来熟悉,就先批准再说。

干净的审批流程只需要适度的摩擦。来自新进程的首次凭据调用会触发审批。操作员确认进程身份和运行目的。只要进程没有退出、操作员没有撤销授权、保险库没有锁定,该进程就可以在已批准的会话范围内继续。新的进程需要重新请求。

最后一点可以阻止一种隐蔽的绕过方式。如果团队批准的是一个指定的终端会话,而不是进程,那么有人就可以在同一终端中启动无关程序,继承属于前一次运行的信任。应让授权绑定到实际的智能体进程,而不是窗口、用户账户或项目文件夹。

Sallyport 请求逐会话授权时,会显示进程的代码签名身份,这正是操作员批准智能体运行前需要看到的细节。团队仍应把书面的运行目的放在这个身份信息旁边,因为身份告诉你谁在请求,而运行约定告诉你这个请求是否属于当前任务。

不可逆权限应使用逐次调用闸门

无需解锁即可验证记录
使用 `sp audit verify` 在离线状态下检查密文中的审计链连续性,无需保险库密钥。

当逐次调用授权保护的是人可以在几秒内判断、却可能长时间后悔的操作时,它才真正有用。将它用于能够建立外部承诺、修改访问权限、销毁数据或影响生产服务的凭据。不要出于习惯给每个凭据都设置逐次授权。

常见错误是把整个生产账户标记为“危险”,要求每个请求都获得批准。智能体随后进行许多无害读取,操作员快速批准它们,而破坏性写入混在熟悉的提示中到达。控制措施变成了节拍器。人们很难在重复且信息量低的确认中持续保持注意力。

如果服务提供方允许,就拆分权限。使用读取凭据进行发现,使用范围狭窄的写入凭据执行普通维护,再使用影响更大的凭据处理需要逐次决定的操作。如果服务提供方只提供一个范围很广的令牌,就把每次使用它都视为广泛权限。不要假装 HTTP 方法本身就能说明风险低。设计不佳的 API 中,POST 可能用于获取数据,GET 端点也可能触发工作。

RFC 6750 直白地描述了 bearer token:任何拥有它的一方都可以使用它。这种属性解释了为什么即使只是“完成这项任务”,把令牌交给智能体仍然会带来比当前操作更大的问题。智能体的提示上下文、shell 历史、日志、插件和未来交接,都可能成为令牌泄露的地方。把令牌留在本地保险库中,只返回操作结果。

对于 SSH,不要把 agent forwarding 当成绕过本地控制的捷径。OpenSSH 的 ssh_config 手册提醒,转发认证代理后,远程主机可以使用本地代理,并指出用户必须信任远程主机。自主工作会放大这一问题,因为智能体可能通过一个自己没有完全检查其配置或目标的主机进行连接。使用直接的 SSH 操作路径,在运行约定中写明允许的主机,并在出现跳板机或新目标时暂停。

把逐次调用闸门放在凭据上,不要放在模糊的“生产模式”概念上。这样以后仍然容易理解。审查者可以看到,无论是哪个智能体请求、哪个项目提供提示,这个凭据都始终需要单独决定。

运行约定可以避免凭猜测审批

运行约定应能放进一条简短的工单评论,并让审批决定可以验证。它不是项目计划,而是记录最少的一组事实,让操作员无需阅读完整的智能体记录,就能批准、拒绝、暂停和审查工作。

操作员解锁访问前,可以使用以下模板:

Run ID: 2025-03-incident-cleanup-01
Owner: name of approving operator
Purpose: inspect failed release and remove only the listed temporary resource
Agent process: expected executable and repository directory
Targets: staging account, api.example.internal, named SSH host
Allowed actions: read deployment state; delete resource tmp-4821 after match check
Per-call actions: delete request, any permission change, any production request
Stop conditions: target mismatch; unexpected credential; failed write; owner unavailable
Expected evidence: request IDs, resource IDs, command output, final status
Review owner: name of reviewer

示例中的日期格式标识符只是为了便于阅读,不是安全控制措施。选择一个团队可以在任务系统和活动记录中搜索的标识符。真正重要的是目标、允许的操作和停止条件。这些内容可以防止智能体因为遇到一个看似合理的下一项任务,就不断扩大运行范围。

运行约定也能提前暴露糟糕的计划。“修复权限”没有目标、允许的变更或审查证据,操作员无法负责任地批准它。“在 staging 中将组 X 添加到角色 Y,然后通过读取请求验证角色绑定”足够具体,可以进行审查。如果智能体发现组 X 不存在,或角色 Y 属于生产环境,就必须停止。

不要把模板写得过于详细,以至于人们开始填写虚构的精确内容。列出大量端点,如果真正的风险是发布构建或删除账户这样的业务操作,只会制造虚假的控制感。端点能帮助明确边界时就写端点,否则写明资源、环境和影响。

对于重复性任务,可以保留带有修订历史的稳定约定。重复性约定不等于永久授权。操作员仍需打开窗口并批准特定的进程运行。稳定文本可以减少歧义,但不应变成没人重新阅读的笼统许可。

被阻塞的任务需要安全的暂停路径

授权进程,而不是终端
来自新智能体进程的首次调用会显示其代码签名身份,然后才请求会话授权。

当被阻塞的智能体没有可靠的停止方式时,团队就会开始寻找绕过办法。智能体可能已经收集了一半输入,操作员可能暂时无法响应,而任务看起来又太接近完成,似乎不该放弃。如果看起来只有“现在完成”或“所有进度都丢失”两个选项,就会有人导出机密。

建立一条能够保留上下文、但不保留凭据的暂停路径。智能体记录观察到的内容、想要执行的确切外部操作、恢复所需的非机密输入,以及审批边界阻止它的原因。它绝不能记录令牌、私钥、授权标头,或嵌入机密的命令行。

对于 HTTP 操作,暂停记录可以包含方法、主机、路径、资源标识符、预期状态类别和经过脱敏的请求体结构。对于 SSH 操作,可以包含主机别名、在不敏感的情况下记录远程用户名、计划执行的命令、预期输出和主机验证结果。操作员可以在打开下一个窗口前检查这些内容。

一份有用的交接备注可以是:

State: held
Reason: planned cleanup target was absent; agent found a second temporary resource.
Observed: tmp-4821 absent, tmp-5930 created by the same failed release.
Requested next action: delete tmp-5930 after operator confirms it belongs to this incident.
No external write occurred after the original target check failed.
Evidence to review: deployment query result and resource metadata IDs.

这份备注给了下一个操作员真正的选择。他们可以授权删除第二个资源,也可以拒绝,或要求进一步发现。智能体不能悄悄把“删除列出的临时资源”重新解释成“删除所有看起来相似的资源”。

不要让智能体不断重试被拒绝的操作。拒绝可能意味着操作员发现了不匹配、保险库已锁定,或逐次调用闸门要求的决定没有到达。重试循环会把清晰的暂停变成一堆提示。除非操作员明确重新授权同一操作,否则应把拒绝视为停止状态。

API 写入请求在超时后也是同样的规则。智能体不能直接假定失败并重复请求。在可能的情况下,它应通过安全的读取查询结果状态,记录不确定性,并在操作可能已经成功时等待。重复写入会造成一些最棘手的事故,因为在外部系统追上进度之前,它们在命令日志中看起来似乎没有问题。

在下一个访问窗口前审查证据

分别审查运行和操作
会话和单独调用显示在不同的日志中,共同来源于一份加密审计日志。

运行结束时,团队应先审查结果,再为相关工作授予新的权限。这样可以在操作员仍记得操作原因时发现偏移。如果拖到周末审查,工单、聊天、终端和智能体记录往往会讲出略有不同的故事。

审查者应将证据与运行约定比较,而不是凭“任务看起来已经完成”的感觉判断。检查实际目标、成功的操作、失败的操作、返回的标识符,以及任何超出预期顺序的调用。失败可能是可以接受的,但无法解释的目标不行。

审查应当简短但具体:

  • 智能体是否只联系了获准的环境和主机?
  • 每次写入是否都属于允许的操作,或获得了单独批准?
  • 外部系统是否返回了预期的资源或请求标识符?
  • 智能体是否在每个规定的停止条件处暂停?
  • 后续任务是否需要新的约定,而不是扩展本次约定?

审查输出不同于审查权限。会话记录可以显示某个进程在 10:02 获得批准,并在 10:19 结束。操作记录可以显示该会话中发生的单独 API 和 SSH 操作。要回答进程是否只做了运行允许的事情,就需要这两种视图。

哈希链式审计日志提供了另一项能力:让后续篡改变得可检测。Sallyport 从一份无法写入的加密审计日志中投影出会话和活动视图,sp audit verify 可以在离线状态下对密文验证链,而无需访问保险库密钥。当有人需要确认事件发生后记录是否被更改时,这很有用,但它不能代替操作员在事实仍然清晰时阅读结果。

利用审查来改进下一次约定。如果每次运行都因为遗漏了无害的元数据查询而暂停,下次就把该查询写进去。如果重复任务在只读端点上反复要求逐次授权,就把该凭据移到普通会话类别。如果审查者不断发现意外写入,就在再次运行前收窄智能体指令和凭据范围。

防篡改证据有助于争议之后,而不是争议之前

防篡改记录让团队能够检查历史是否仍然连续,但它不会决定某项操作是否获准、是否合理或是否安全。把审计证据当成预防性控制,会让团队因为相信以后可以再处理,而批准范围过大的运行。

在真实事故中,这个区别很重要。假设智能体联系了预期的部署 API,随后却对意外资源执行了删除。链式日志可以帮助确认删除请求出现在记录的操作序列中,但它无法恢复已删除的资源,无法说明进程为什么获得了广泛权限,也无法证明操作员本来就想把该资源纳入范围。

在需要保留记录后再升级事故、交接调查或审查可疑运行时,使用审计验证。针对保留的日志材料运行验证器,记录验证是否成功,并将验证结果与事故备注一起保存。不要为了让报告更容易阅读,就编辑或手动“清理”活动条目。解释性备注应放在记录旁边,而不是记录里面。

这条链也会改变团队处理日志访问的方式。人们有时认为,没有立即解密,日志就毫无用处。能够在密文上检查链连续性的验证器,可以让调查人员在不打开保险库的情况下,确认一个有限但重要的事实:保留的加密记录是否仍然符合原有顺序。要区分清楚:验证检查完整性连续性,解密显示内容,两者都不会授予再次执行操作的权利。

如果团队规划了解锁窗口、识别智能体进程、为高影响权限使用逐次调用闸门,并及时审查结果,就不需要经常依赖审计证据。需要记录时,团队也会拥有理解记录所需的运行约定和暂停备注。没有审批上下文的日志只能告诉你发生了什么。与有纪律的工作计划配套的日志,才能告诉你团队是否有理由允许它发生。

要做的第一项改变很小:任何人在为智能体解锁本地凭据前,都必须写下一条停止条件。这一行文字会迫使团队决定,当任务不再符合计划时,智能体应该做什么。它也消除了工作变得不方便时导出机密的常见借口。

常见问题

操作员应该让本地凭据保险库全天保持解锁吗?

不要这样做。只有在一名负责任的操作员能够监督智能体将要执行的工作时,才解锁保险库。因为之后可能用得上而一直保持解锁,会把一次明确的授权事件变成无人关注的后台状态。

一次智能体运行授权应该涵盖什么?

把会话授权视为同意一个已识别的智能体进程执行规定的运行任务。进程退出、操作员撤销授权,或工作发生重大变化时,授权都应失效。不要因为终端被重复使用,就把新提示当成新的授权,还应先确认哪个进程仍拥有该会话。

哪些智能体操作需要每次都获得批准?

对于错误结果会立即产生外部影响的操作,应使用逐次调用授权,例如生产环境写入、发布版本或破坏性管理请求。不要因为系统支持逐次授权,就对无害的读取调用也这样做。持续不断的提示会让操作员养成不阅读就批准的习惯。

自主任务在工作时间之外需要凭据时怎么办?

最安全的做法是暂停任务,记录当前状态,等待下一个有人值守的访问窗口。如果确实有截止时间,负责的操作员可以打开一个较短的新窗口,并批准范围清晰的后续操作。不要通过把令牌复制到文件或聊天中来解决延迟。

AI 智能体运行约定应该包含什么?

一份好的运行约定应写明操作员、任务目的、目标环境、允许的操作类型、停止条件、预期的外部变更以及审查节点。它让操作员有具体内容可以与活动记录比较。单独的工单标题通常不够详细。

为什么要分别记录智能体会话和单独的凭据调用?

两者都需要,因为它们回答的是不同的问题。会话记录说明哪个智能体进程获得了权限,以及权限何时结束;操作记录说明该进程实际要求凭据系统执行了什么。发生事故时,任何一者都不能替代另一者。

SSH agent forwarding 对自主编程智能体安全吗?

不要默认允许。SSH agent forwarding 会让远程机器请求本地代理进行签名,从而扩大攻击者可以使用你权限的范围。应改用直接的、指定目标的 SSH 操作路径。

如何确认自己批准的是预期的智能体进程?

只有在能够识别可执行文件及其代码签名身份,并且运行任务有书面目的和明确目标时才批准。单凭进程名称几乎不能证明什么,因为任何程序都可以取一个友好的名字。审批界面应帮助操作员回答:是谁启动了这个进程,以及它现在能做什么。

团队什么时候应该审查智能体的结果?

在重新开放访问权限以执行下一个相关任务之前审查结果,尤其是在发生写入之后。将变更的资源、返回的标识符、失败情况和意外目标与运行约定进行比较。如果结果不一致,应撤销会话并调查,再让智能体获得更多权限。

防篡改审计日志能阻止智能体执行错误操作吗?

不能。防篡改记录可以帮助你在争议发生后确认发生了什么,但无法在权限过宽时阻止错误操作。预防依赖较短的解锁窗口、有边界的运行授权,以及针对需要人工判断的操作设置逐次调用闸门。

Sallyport

Sallyport 替你的 AI 智能体执行 API 调用和 SSH 命令。密钥留在你 Mac 上的本地密钥库里;每次运行由你批准,每个操作都落入一份密封的审计日志。

© 2026 Sallyport · 依据 Apache-2.0 开源 · Oleg Sotnikov