阅读需 8 分钟

如何安全撤销正在执行任务的 AI 代理权限

了解如何在 AI 代理执行任务期间安全撤销权限、遏制远程工作、保留证据、审查日志,并安全恢复开发。

如何安全撤销正在执行任务的 AI 代理权限

活跃的 AI 代理不需要恶意意图也可能造成事件。错误指令、过于宽泛的工具授权、被投毒的仓库文件,或判断失误的操作员,都可能让它在仍拥有访问权限时陷入破坏性循环。响应措施必须迅速阻止新的操作,同时保留能够解释事件经过的记录。

常见的错误做法是关掉终端,撤销眼前所有凭据,第二天早上再凭记忆重建事件。这样会造成更大的中断,还经常破坏三者之间的区别:代理试图做了什么,远程服务接受了什么,以及实际发生了什么变化。应把代理事件当作一项需要遏制和处理证据的工作,而不是需要掩盖的尴尬插曲。

撤销权限必须先阻止后续授权,再清理现场

撤销代理,意味着阻止它执行下一次特权操作,同时保留足够状态,以判断之前的操作是否成功。关闭可见的聊天窗口或终端窗口可能两件事都做不到。进程可能拥有子进程,代理可能保持着远程连接,HTTP 请求也可能在本地进程消失后继续运行。

在操作控制措施前,先区分以下四件事:

  • 代理进程是生成决策和工具调用的本地程序。
  • 会话是授予这次特定进程运行的权限。
  • 凭据是外部系统接受的秘密或身份。
  • 远程操作是 API、队列、主机或云控制平面已经接受的工作。

人们经常混淆会话撤销和凭据轮换,后果可能很严重。如果为了停止一个代理而轮换共享部署令牌,可能会中断生产自动化,而代理已经提交并被接受的请求仍会继续运行。如果代理把令牌复制到工作区后,你只是结束代理进程,也可能留下可重复使用的秘密。

因此,遏制措施应沿着离代理最近且可靠的控制点展开。先拒绝当前运行的新操作,再停止或取消已经进入远程系统的工作。当证据表明秘密可能不再受控,或你无法信任会话边界时,再升级到禁用凭据。

提前写下一条简单的事件规则:看到可疑行为的人可以立即停止代理,无需等待会议。事后再进行审查。延迟审批适合部署,不适合撤销活跃进程的权限。

在第一次事件发生前建立操作地图

无法识别的对象就无法撤销。每次代理运行都需要一个标识符,并且该标识符要出现在本地进程记录、工具日志和到达远程系统的请求中。只要始终传递一致,随机生成的运行 ID 就够用。不要使用人名或 coding-agent 这样的模糊标签,它们会把互不相关的活动混在同一个类别里。

针对代理可以采取行动的每条路径,记录以下五个操作问题的答案:

  1. 哪个本地进程拥有这条路径,如何停止它?
  2. 哪个会话或令牌代表该进程访问操作网关?
  3. 本地撤销后,哪些远程操作仍可能继续?
  4. 哪些独立服务日志会记录这些操作?
  5. 正常负责人无法处理时,谁可以禁用这条路径?

这不是为了填表而填表。发生事件时,操作员不应临时查找数据库迁移究竟是通过 shell 子进程、CI 任务、HTTP 请求,还是独立的云工作流执行的。

只要 API 支持,就把运行 ID 作为请求头传递。对于运行 ID 为 run_2025_04_18_7f3c 的代理,包装器可以添加关联请求头,而无需把秘密放进代理提示词或环境变量:

export AGENT_RUN_ID="run_2025_04_18_7f3c"
curl -sS -X POST "$ACTION_ENDPOINT" \
  -H "X-Agent-Run-ID: $AGENT_RUN_ID" \
  -H "Content-Type: application/json" \
  --data @request.json

接收服务应将运行 ID 与正常的请求 ID、调用者身份、端点、响应状态和时间一起记录。记录可以采用这样的形式:

time=2025-04-18T14:12:09Z request_id=req_91a run_id=run_2025_04_18_7f3c caller=agent-gateway method=POST path=/deployments status=202

202 很重要。它表示服务接受了工作,不表示工作已经完成。事件审查经常在这里出错:团队把代理最后一次工具输出当成结果,但远程系统可能只是确认已经提交到队列。

对于 SSH,要记录远程账户、目标主机、强制命令,以及记录登录和命令活动的位置。本地终端记录很有用,但不能证明某条命令没有在远程运行。这个问题应由主机自身的日志和相关服务审计轨迹来判断。

按照能保留控制权的顺序停止活跃运行

先记录时间和撤销的直接原因,然后拒绝新操作并终止代理。具体命令取决于操作系统和运行环境,但顺序不应改变,因为这样可以把遏制和清理分开。

  1. 在事件记录中写下运行 ID、本地进程 ID、操作员、观察到的行为和当前时间。关闭界面前,复制代理当前记录以及最后一次可见的工具调用。
  2. 在负责授权操作的网关处撤销或锁定活跃会话。如果存在安全的只读操作,确认同一进程发起新的测试调用会收到拒绝。
  3. 如果操作系统允许,先挂起本地进程,再结束它。挂起可以保留稳定的进程树和打开的文件列表。只有在继续运行会造成直接损害时,才在收集这些状态前立即结束进程。
  4. 找出并停止与该运行有关的子进程、后台任务、容器和远程会话。
  5. 使用服务自身的取消机制取消已经接受的远程工作,并保留响应和状态。

在 macOS 或 Linux 上,先检查,不要盲目执行 kill -9。把示例进程 ID 换成你记录的 ID:

ps -o pid,ppid,pgid,lstart,command -p 48192
pgrep -P 48192 -a
lsof -nP -p 48192
kill -STOP 48192

第一条命令记录父子关系和启动时间。pgrep 显示直接子进程,lsof 通常能显示值得保留的工作区文件、套接字和管道。kill -STOP 会冻结一个配合运行的进程,不给它再次发出清理命令的机会。但它不会冻结已经脱离的子进程、远程任务,或已经跨过网络边界的 API 请求。

把输出复制到事件目录后,枚举整个进程组。进程可能启动一个改变了进程组的子进程,因此不要只执行一条命令就结束检查。如果代理可以使用容器运行时或后台任务管理器,也要检查这些组件。代理拥有 SSH 访问权限时,还应在每台目标主机上检查活跃会话。

任务涉及远程工作时,使用远程系统返回的操作 ID。例如,API 接受请求时可能返回:

{
  "operation_id": "op_4e2b7c",
  "status": "queued"
}

保存该响应,然后调用文档中的取消端点,或在人工控制下使用服务控制台。记录取消结果。cancel_requested 表示你仍需轮询该操作,直到它报告 cancelledcompleted 或其他终态。不要因为本地进程消失,就在事件记录中写下“已停止”。

在重置工作区前保留证据

删除分支、重启服务或运行自动清理脚本前,先把证据保存到独立的事件目录中。你需要一份按时间排序的记录,让其他开发者无需依赖操作员的回忆也能检查事件。

尽可能保留原始时间戳,并收集以下材料:

  • 代理记录、工具输入、工具输出,以及本次运行使用的配置。
  • 进程检查输出、父子进程 ID、开放连接,以及与本次运行有关的 shell 历史。
  • 网关会话记录和操作日志,包括撤销后的拒绝记录。
  • 远程服务审计事件、操作 ID、取消结果,以及发生变化的资源标识符。
  • 仓库状态:当前提交、差异、未跟踪文件和生成的构件。

收集后为文件生成哈希。简单的清单可以帮助后续审查者发现文件在值班工程师、安全人员和受影响系统负责人之间传递时是否被意外修改:

mkdir -p incident-run_2025_04_18/evidence
cp agent-transcript.txt incident-run_2025_04_18/evidence/
ps -o pid,ppid,pgid,lstart,command -p 48192 \u003e incident-run_2025_04_18/evidence/process.txt
shasum -a 256 incident-run_2025_04_18/evidence/* \u003e incident-run_2025_04_18/SHA256SUMS.txt

输出清单应类似这样:

8f7c...  incident-run_2025_04_18/evidence/agent-transcript.txt
30b1...  incident-run_2025_04_18/evidence/process.txt

哈希不能让文件变得真实可信,它只能证明审查者收到的是你计算哈希时的同一份文件。应将其与代理无法编辑的系统日志交叉核对,例如 API 提供商的审计轨迹或只追加的集中式日志服务。

NIST 的《计算机安全事件处理指南》SP 800-61 将遏制、根除、恢复和事件后工作视为不同活动。这种区分很适合代理事件。团队经常直接进入根除阶段,删除工作目录或轮换令牌,之后才发现被删除的记录里有定位远程资源所需的精确请求正文。

不要因为要保留上下文,就把秘密复制到事件目录。记录凭据标识符、负责人、范围、创建时间和最后使用记录。只有在现有事件流程明确允许并且能够保护秘密时,才保存实际秘密值。事件归档应减少不确定性,而不是制造第二次秘密泄露。

父进程死亡不代表工作停止

检查证据链
使用 sp audit verify 离线验证导出的审计链,无需保险库密钥。

在确认相反情况前,应假设活跃代理可能留下了仍在运行的工作。最麻烦的案例往往不是戏剧性的 shell 命令,而是开发者在正常工作中几乎不会注意到的普通异步操作。

设想一个编程代理提交部署请求,启动 SSH 命令执行后台迁移,然后等待测试结果。操作员看到异常的生产目标后停止父代理。部署服务已经接受了请求,远程 shell 也已经通过 nohup 启动命令。两者都会继续运行。终端最后一行可能只显示连接已关闭。

审查需要三类不同检查:

检查 API 已接受的工作

使用运行 ID、请求 ID、账户身份和时间范围,在受影响的服务中搜索。确认每个请求是被拒绝、排队、运行、完成还是取消。对于已经完成的变更,列出具体资源 ID,并将最终状态与请求状态进行比较。

不要只依赖 HTTP 状态。200 可能表示同步变更、状态文档,或中间层返回的响应。202 通常表示已接受处理,但最终含义由服务文档定义。在为服务编写取消流程前,先阅读该文档。

检查脱离代理的工作

在目标系统上检查远程账户的会话、进程树、计划任务、临时目录和服务日志。搜索已记录的命令行、工作目录、运行 ID 或唯一生成文件。如果远程任务使用任务调度器,应通过调度器取消它,而不是结束一个可能已经不再拥有该任务的 shell。

还要检查回调。生成的脚本可能配置了 webhook、创建了拉取请求工作流,或触发了 CI。这些都是拥有独立凭据和时间表的独立执行者。撤销原代理并不会撤销它们。

这正是窄范围操作网关比向代理提供带有宽泛环境的通用 shell 更安全的原因。你可以枚举数量受限的通道,并要求每次特权调用都经过控制点。一个充满继承凭据的 shell 会让每个子进程都变成单独的事件分支。

只有在暴露风险足够高时才轮换凭据

如果有理由相信代理、其子进程、日志或工作区可能保留了秘密,就应轮换凭据。不要只是为了营造响应的样子而轮换。大范围轮换会中断正常用户,还可能改变你仍需要检查的记录,使审查更加困难。

以下情况足以支持立即禁用或轮换:

  • 代理在提示词、环境变量、配置文件、命令行或工具输出中收到明文秘密。
  • 凭据出现在记录、仓库差异、临时文件或 CI 日志中,且事件团队之外的人员也能访问。
  • 你无法确认某个可能读取秘密的子进程、远程会话或出站连接的情况。
  • 凭据拥有广泛权限,并且缺少可靠的逐次使用日志。
  • 受影响的提供商告诉你,该凭据曾被无法解释的身份或位置使用。

如果网关注入凭据,并且只把操作结果返回给代理,情况就完全不同。代理可能执行了未授权操作,但不一定持有可重复使用的秘密。先禁用活跃会话和受影响的操作路径,检查审计记录;如果审查发现绕过边界的路径,或提供商层面存在风险,再轮换底层凭据。

不要建议每次代理犯错后都轮换所有秘密。这个建议很流行,因为它看起来果断,也因为凭据泄露确实会带来严重后果。但它不应成为默认做法,因为它混淆了未授权使用和凭据泄露,会造成可以避免的生产故障,还会让团队跳过仔细的范围判断。凭据可能泄露时应果断轮换,否则就要保留区分受影响运行和其他运行的能力。

需要轮换时,记录旧凭据标识符、禁用时间、使用它的下游系统、新凭据负责人,以及证明旧凭据不再有效的测试。不要把任何一个值放进工单或记录。应由秘密管理器或提供商的受保护轮换机制处理替换。

事件记录必须经得起怀疑式审查

识别每个新进程
每个会话只需批准一次新进程,批准卡会显示其代码签名权限。

事件审查应让未参与值班的开发者能够重建事件顺序,而不是依赖某一份可变日志。先从代理意图和本地进程记录开始,再将这些内容与网关记录和远程服务证据进行比较。

建立一条带有明确可信度标签的时间线。例如,“代理提出请求”来自记录,“网关执行请求”来自网关操作记录,“提供商接受操作”来自提供商审计条目,“资源发生变化”来自资源最终状态和变更历史。这些是不同的主张,应由不同证据支持。

只写入、哈希链式的审计日志在这里很有价值:执行操作的组件无法在事后悄悄改写自己的历史。对密文进行验证,也能让审查者在不接触所有秘密或操作载荷的情况下检查连续性。但这不能让日志变得完整。它仍然只能记录经过网关的活动,因此远程服务日志仍是审查的一部分。

Sallyport 从一份加密、哈希链式审计日志中记录代理会话和单次操作,sp audit verify 可以在没有保险库密钥的情况下离线检查链。事件审查者可以对导出的日志副本执行以下测试:

sp audit verify /path/to/exported-audit-log

验证成功,说明你收到的加密记录保持了连续性。验证失败时,应停止随意清理并启动证据处理流程,因为你必须确定断裂是由导出损坏、存储故障还是蓄意篡改造成的。

审查应给出答案,而不是列出一份模糊的观察结果。确定触发事件的指令或输入、授予该运行的权限、每个已确认的外部操作、仍不确定的操作、可能逃逸的凭据,以及本可以更早阻止事件的控制改进。如果团队无法指出第一个失效的控制点,很可能只会增加一个令人疲劳的批准提示,而不是修复暴露的路径。

用新的边界恢复开发,不要重新打开原会话

控制 SSH 权限
通过 Sallyport 及其无状态的 sp-ssh 辅助工具路由 SSH 命令,而不是暴露 SSH 密钥。

完成遏制后,开发者可以继续工作,但不应通过同一进程、同一工作区状态或同一权限授予来恢复。中断的运行可能仍在内存中保留未经审查的指令、过时的任务上下文、生成的脚本,或第一次响应遗漏的子进程。

使用新的会话身份创建一次新的运行。在让新运行接触凭据或生产目标前,先审查仓库差异和生成文件。如果需要继续之前的任务,应向新运行提供简短的书面交接,说明哪些远程操作已经完成,哪些仍处于取消状态,以及哪些资源需要检查。

为恢复的任务使用更窄的权限集。代码审查任务很少需要部署权限。必须查询生产环境的任务通常不需要写入权限。这不是要求每个开发者都使用复杂的策略语言,而是拒绝把昨天的宽泛授权带到事件发生后启动的新运行中。

按会话授权在停止事件后启动新本地进程时尤其有用,因为它会迫使人工确认这是一次不同的运行。对于错误写入代价足够高、值得中断的操作,可以采用逐次调用批准。如果批准卡没有明确显示调用进程和具体操作,应先修正这一点,再在事件期间信任它。

第一次演练应控制在十五分钟内:启动一个无害的代理任务,在 API 调用期间撤销其会话,保存本地和远程记录,并确认该任务无法以旧权限恢复。对一次性目标进行演练。这样可以在成本较低时发现缺少的请求 ID、脱离的子进程和日志访问问题,而不是等到真正的生产错误发生。

让撤销成为普通的操作员动作

把撤销当作罕见紧急措施的团队,在代理行为异常时往往会犹豫。控制措施应让安全决策变得快速:锁定操作边界,撤销会话,检查已经跨过边界的内容,并留下不会在清理过程中消失的记录。

最重要的设计选择很简单,就是分离权限。代理可以规划和请求操作。本地控制点持有凭据,识别发起请求的进程,记录请求,并且可以拒绝该进程,而不把秘密交给它。操作员按下停止后,下一次特权调用必须失败,而此前的调用必须仍可审查。

用代理实际使用的工具验证这一点。如果团队无法在不轮换共享凭据的情况下停止一次活跃运行,无法将远程操作关联到该运行,或无法在事后验证其操作历史,那么事件流程就还没有完成。

常见问题

代理仍在执行命令时,可以撤销它的权限吗?

先终止代理进程或撤销其当前会话,然后阻断它用于执行特权操作的路径。如果代理可能已经复制凭据或创建了远程会话,请在收集理解暴露范围所需的证据后,再禁用或轮换该凭据。

结束代理进程后,所有操作都会立即停止吗?

不能。停止本地进程不会撤销 API 已接受的请求、已经交给 SSH 服务器的命令,也不会停止已经脱离父进程的子进程。应先把撤销当作遏制措施,再检查已经在执行或等待执行的操作。

停止 AI 代理后应保留哪些证据?

完整的证据集应包括代理记录、进程元数据、命令历史、批准记录、工具输入和输出、时间戳,以及受影响服务的审计事件。删除工作区、重置终端或轮换账户前先收集这些材料,否则可能丢失重要上下文。

撤销代理后是否应该轮换 API 密钥?

如果代理收到了凭据明文,将其写入文件或日志,传给无法确认情况的子进程,或者在日志不可靠的主机上使用了它,就应轮换凭据。如果网关始终在代理之外保存密钥,并且能够记录每次使用,则可以先禁用受影响的路径,再根据审查结果决定是否轮换。

撤销会话和撤销凭据有什么区别?

会话撤销只会停止一个已识别的运行。凭据撤销则会让所有持有者都无法使用该认证方式,包括正常运行的自动化任务,因此影响范围要大得多。如果能够信任负责执行边界的控制措施,应先使用范围更小的控制。

AI 编程代理的父进程退出后还能继续工作吗?

可以。代理可能启动 shell 子进程、后台任务、容器、远程命令或回调,这些都可能在父进程结束后继续运行。应检查进程树、任务控制、远程会话列表和出站活动,不要假设可见的代理就是唯一执行者。

代理事件发生后,开发者如何安全地恢复工作?

不要继续使用中断运行所用的工作区、长期访问令牌或宽泛权限。启动一个带有新会话的新进程,只授予它所需的能力,再让人工审查上一次运行留下的待处理变更。

批准提示足以控制 AI 代理吗?

只有当批准者能看到足够的身份和操作上下文时,批准提示才有用。缺少调用进程、目标、方法和范围的批准提示会让人习惯性点击确认,因此不适合作为遏制措施。

审查期间如何防止代理日志被篡改?

将日志保存在一次写入位置,或导出到受限的事件存储中,并为原始文件生成哈希。哈希可以证明后续审查者收到的是同一份证据,而服务日志和时间戳则能帮助核对事件顺序。

AI 代理事件审查应确定哪些问题?

严肃的审查应确定哪个进程执行了操作、它获得了什么权限、哪些请求到达了外部系统、发生了哪些变化,以及凭据是否离开了原定边界。审查还应产出一项具体的控制改进,而不是只说团队以后会更加小心。

Sallyport

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

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