每周代理安全审查:一套实用的 35 分钟流程
每周执行一次代理安全审查,检查会话、异常命令、失败调用、已撤销权限,以及即将轮换的凭证。

一次每周代理安全审查应在一小时内完成,得出少量明确决定,并留下日后可以检查的证据。如果审查变成在数千条记录中漫无目的地寻找,连要回答的问题都不清楚,那么设计从一开始就失败了。
我见过团队在自动化工作上犯同一个错误:他们知道应该收集活动记录,于是把记录存了下来,却只在发生令人不安的意外后才打开查看。到那时,有用的上下文已经失效。发起运行的工程师已经转去处理别的任务,临时凭证也已经消失,没有人说得清那条奇怪的命令究竟是一次合理修复,还是权限边界出现问题的第一个信号。
每周检查解决的是一个更具体的问题。它能在人和任务仍然容易识别时发现访问权限逐渐偏离。它也会迫使团队区分一个经常被混淆的事实:代理被允许执行某项操作的记录,并不等于该操作本身合理的记录。
每周审查能在偏离变成常态前发现问题
每周审查之所以有效,是因为代理权限往往通过一些容易被遗忘的小变化逐渐扩大。有人为了让测试通过,添加了一个令牌。一个编程任务扩大成了部署变更。代理不断重试 API 调用,直到备用路径成功。这些事件单独看未必值得启动事件响应,但连续几周累积后,可能形成一个没人有意批准过的访问模式。
实时审查每个事件听起来更安全,但大多数团队无法长期保持所需的注意力。审查人会开始按照模式批准或驳回记录。他们不再追问,为什么一个正在编辑文档的代理连接了生产主机。这其实是披着安全外衣的审批疲劳。
等到季度审查则会因为相反的原因失败。一个季度包含太多运行、太多变更过的代码库,也包含太多已经模糊的记忆。最后你只是在统计事件,而不是理解事件。
设定固定的每周时间窗口,每次在同一时间审查前七天。选择审查人能够联系执行异常任务的人员的时段。有些团队适合周五下午。如果周末自动化任务需要关注,周一早上可能更好。具体日期不如保持稳定重要。
审查应回答五个问题:
- 哪些新的代理进程获得了权限?
- 哪些操作偏离了任务要求或正常目标?
- 哪些失败说明集成出现问题,或存在探测行为?
- 哪些会话被人撤销,撤销是否真的阻止了后续使用?
- 哪些凭证需要负责人在下次使用前做出决定?
不要因为仪表板能显示某项数据,就额外增加第六个问题。每周流程只有在契约明确且范围有限时才能持续。一旦变成屏幕上放着日志的泛化安全会议,它就会逐渐失去作用。
NIST SP 800-92,《计算机安全日志管理指南》强调了一点,这里依然适用:组织需要明确的日志分析流程,而不只是一个存放日志的地方。代理记录让这一点更加明显,因为代理可以快速而反复地行动。存储提供证据,流程则让证据有机会改变决定。
先看新会话,不要从单个调用开始
先审查新会话,因为会话是权限开始生效的单位。你需要知道哪个进程获得了权限、它以什么身份出现、运行何时开始,以及这次运行是否有合理的目的。
会话审查不是清点库存。不要看一眼列表,认出一个熟悉的开发者姓名,然后继续往下看。经过签名的进程身份能提供有关进程的信息,却不能说明这个进程是否因合理任务而启动。把进程身份当作来源证据,而不是意图证据。
对每个新会话,在审查记录中回答以下问题:
- 谁发起或负责这次运行?
- 哪个代码库、工单、维护任务或调查为它提供了理由?
- 这次运行可以使用哪些类别的凭证?
- 任务结束时,会话是否也结束了?
- 是否出现了另一个使用不同身份、重复执行同一工作的会话?
最后一个问题能发现团队经常漏掉的一类故障。工程师发现工具在受限账户下失败,于是通过另一个代理进程重新运行并得到结果。活动记录可能只显示两个普通会话,但安全含义不同:第一个边界正确发挥了作用,第二次运行却可能绕过了设置该边界的原因。
如果会话没有可识别的负责人、没有任务引用、持续时间异常,或拥有与所述工作无关的权限,就标记为需要跟进。持续时间异常不代表所有长时间运行都可疑。大型重构和缓慢的测试套件本来就可能运行很久。一个在人类上下文已经消失很久后仍保持活动的会话值得关注,因为过期权限很容易被遗忘。
按用途维护一份小型的常规自动化许可清单,不要使用「可信」这样的模糊标签。例如,定期依赖更新任务可以合理地访问软件包仓库并创建拉取请求。这样的描述给审查人留下了可验证的依据。「可信编程机器人」则什么也没有说明。
异常命令需要上下文,而不是先追责
一条异常的 SSH 命令或 HTTP 请求是需要调查的证据,不是结论。审查人在这件事上常常会走向两个极端。有些人因为代理已经获授权,就忽略奇怪命令。另一些人把所有陌生命令都当作恶意行为。这两种反应都会让日志失去价值。
根据任务建立预期上下文。读取暂存环境部署状态的请求,可能适合发布调查。在调整 README 的任务中出现同样的请求,如果没有解释就不合理。归档构建输出可能很普通。归档用户主目录、读取 shell 历史记录,或修改远程启动文件,则需要仔细查看。
对于 SSH 活动,比较以下四个边界:
- 任务本应访问的主机。
- 任务实际需要的账户和目录。
- 任务允许进行的变更类型。
- 命令成功后预期产生的后果。
第四个边界很重要。在构建主机上执行 git status,后果通常很小。编辑服务定义、改变文件所有权或创建定时任务的命令,则会改变未来行为。这些调用应有具体任务引用和明确负责的人。
HTTP 记录也需要同样处理,只是线索有所不同。查看目标、请求方法、路径、响应类别和请求量。对预期服务发起新的 GET 可能很正常。大量收到授权失败响应、尝试访问管理路径,或向与任务无关的服务发起写入请求,都需要解释。
不要建立一份庞大的禁用字符串清单,然后把它叫作审查。代理可能在不合适的上下文中调用合法工具,而一条无害命令如果缺少参数信息,也可能看起来很吓人。审查人需要足够的周边证据,才能判断代理试图做什么。
一条有用的发现记录可以这样写:「会话 S-184 执行了一项代码库维护任务。它通过 SSH 访问部署主机,并修改了服务配置。任务记录没有包含部署工作。会话负责人确认这是误选命令造成的变更。我们撤销了该会话,并恢复了之前的配置。」这样的记录包含事实、解释和已完成的行动,其他审查人也能看懂。
较弱的记录则是:「发现可疑命令。」这句话只会制造焦虑,还会让下一位审查人重新还原整个事件。
失败调用既能显示故障,也能显示边界测试
失败调用值得单独审查,因为失败传递的信号与成功操作不同。成功写入可能改变系统,失败则可能暴露代理尝试访问一个本不应考虑的目标。
先把普通集成故障和可疑重复行为分开。过期令牌、变更后的 API 路径、网络超时或服务提供商限流,都会在正常工作中产生失败。修复可能属于运维问题,而不是安全问题。记录失败趋势,找出负责人,并在代理学会绕过故障路径前修复它。
然后查看会改变判断的模式:
- 同一个被拒绝的调用反复出现,期间没有有效退避,也没有任务变化。
- 代理在授权被拒后尝试相邻路径。
- 运行在被拒绝后改变目标,而不是报告拒绝结果。
- 失败调用的目标超出了任务边界之外的主机、服务或账户。
- 失败调用出现后,紧接着通过权限更宽的凭证成功执行操作。
最后一种模式往往隐藏着薄弱的凭证设计。假设代理尝试通过权限受限的令牌更新部署,却收到授权错误。随后它使用通用运维令牌并成功。日志可能显示这是一次「恢复成功」的任务,但审查应将其标记为权限范围失败。受限令牌正确拒绝了请求,宽权限令牌却掩盖了任务与允许访问范围之间的不匹配。
不要告诉团队每次 API 请求返回 401 或 403 就轮换凭证。这种建议很受欢迎,因为它看起来果断,但也很浪费。轮换无法修复缺失的权限范围、错误的端点,或代理反复选择错误操作的问题。它还可能用一个权限同样错误的新凭证替代证据链,让下一次审查更困难。
相反,把失败调用归入四种结果之一:预期的运维失败、配置缺陷、任务边界违规,或可能的凭证滥用。审查人应写明选择该类别的原因。如果证据不足以支持任何类别,就在运行情况仍然清楚时询问会话负责人。
撤销必须关闭引发担忧的路径
被撤销的会话应阻止活动进程继续使用已授予的权限,但它不会自动修复所有相关风险。每周审查需要检查撤销事件本身,以及周边的访问路径。
对每个被撤销的会话,记录触发原因。有人可能因为任务结束而撤销,也可能因为审批是误操作、进程身份看起来不对,或运行行为出乎预期。不同原因需要不同修复。正常的任务结束撤销可能无需进一步行动。异常进程身份则可能需要调查工作站和启动路径。
然后检查撤销后的活动。撤销后出现的任何调用都需要解释。它可能来自时间戳理解错误、独立获授权的进程,或审查人关联记录方式的缺陷。不要直接假定最坏情况,也不要轻描淡写地带过。撤销的意义在于让权限边界变得可观察。
还要检查并行权限。代理失去一个会话后,仍可能通过另一个活动进程、不同凭证、已打开的 SSH 连接,或独立的自动化账户继续行动。审查不需要证明整个公司不存在任何备用路径,但应确定同一任务是否能通过一个明显且未关闭的路径继续执行。
用清晰的语言写下撤销记录:
审查日期:2025-03-07
会话:[会话引用]
原因:SSH 命令超出了批准的维护任务范围
操作:已撤销会话
撤销后的调用:未观察到
相关凭证:已审查,无需轮换
负责人跟进:更新维护运行说明
使用实际日期和引用。模板很重要,因为它会迫使审查人说明自己是否检查了撤销后发生的事情。「已撤销」只描述了一个动作,并没有说明结果。
不要把每次撤销都变成纪律处分事件。如果工程师担心停止运行会受到惩罚,他们会一直犹豫,直到能够证明存在恶意意图。撤销的作用是快速停止不确定的操作。后续审查再决定原因究竟是提示词问题、审批错误、凭证设计问题,还是不当行为。
轮换从负责人和权限范围开始
需要轮换的凭证应在每周审查中作为等待负责人决定的事项出现,而不是一份恐慌清单。一个凭证应有轮换日期、系统负责人、明确用途和权限范围。缺少其中任何一项,就已经比应有的状态更难管理。
根据审查窗口内使用过的凭证建立一份小型轮换队列。对每个凭证记录负责人、服务、预期用途、下次轮换日期,以及本周活动是否仍符合该用途。开始时不需要复杂的数据库。一份持久保存且标明负责人的记录,比一份无人更新但看起来很完整的清单更有价值。
出现以下任一情况时,应优先轮换:
- 凭证已超过要求的轮换日期。
- 负责人无法解释最近一次使用。
- 凭证权限超过任务需要。
- 凭证曾在访问受到质疑或出现未知进程事件后被使用。
- 团队无法识别负责该服务账户或凭证的人。
没有切换计划的轮换会造成可以避免的中断。替换凭证前,先找出使用它的代理运行、脚本和集成。按照当前任务需要,以最小权限签发替代凭证。测试预期操作,迁移已知使用方,然后停用旧凭证,并确认没有新的活动继续使用它。
不要把「最近没看到它」当作凭证未使用的证明。有些维护任务每月运行一次,或者只在事件期间运行。删除前检查负责人和记录用途。如果两者都不存在,可以在受控时间窗口内禁用它,并观察由此产生的失败。这通常是最快的诚实答案。
还要保留另一个区别:轮换减少密钥的有效使用期限,权限范围则限制密钥能做什么。团队经常试图用频繁轮换来弥补过宽的权限,但这不起作用。新签发的凭证如果访问过多,仍然是访问过多。
在解释证据前先验证证据
每周判断是否可靠,取决于背后的记录是否可靠。导出的截图和手工复制的行很方便,但如果有人需要确认它们之后是否被编辑过,这些材料就不是理想证据。
Sallyport 通过一份加密、哈希链式的审计日志记录代理运行和单独调用,同时将它们显示在不同的会话日志和活动日志中。这种分离很有用,因为审查人可以从进程审批记录转到该运行期间的具体调用,而不会把两类记录混为一谈。
在正式开始审查前,或在关注事件后保存证据时,运行可用的离线完整性检查:
sp audit verify
该命令会对密文验证审计链,不需要保险库密钥。验证成功说明按照所记录的哈希,链条保持完整。但它不能证明获授权的人做出了明智审批,不能证明目标合适,也不能证明凭证权限范围合理。完整性和判断是两项不同的工作。
如果验证报告问题,就不要再把相关导出文件当作已经确定的证据。保留文件,记录命令的准确结果,然后调查存储和应用状态。不要为了让报告看起来正常而「清理」记录。在根据日志得出结论前,你需要知道问题来自损坏、复制不完整,还是人为干预。
对于普通每周审查,如果团队需要可辩护的记录,就把验证结果和审查记录放在一起保存。对于低风险的本地实验,也可以选择更轻量的做法,但决定应当明确。要避免的情况是,恰好在包含严重发现的那一周悄悄跳过验证。
审查需要固定的 35 分钟节奏
短时审查只有在你为决定预留时间时才有效,而不是在其他工作结束后才说「看看日志」。对于代理运行数量可控的团队,下面的流程已经足够。只有当数量或风险确实需要时,才增加时间。
- 用五分钟验证审计记录并设置日期范围。打开上次审查记录,让未解决事项保持可见。
- 用十分钟审查新会话。把每个陌生进程或持续时间异常的运行与负责人和任务对应起来。
- 用十分钟审查异常成功操作和失败调用。在对任何事件分类前,先调出周边上下文。
- 用五分钟审查被撤销的会话。检查触发原因、撤销后的活动和明显的并行权限。
- 用五分钟审查凭证轮换。为每一项需要行动的事项指定负责人和截止日期。
最终只保留一份审查记录,并使用三个标题:发现、决定、待办负责人。发现是观察到的事实。决定说明你要做什么。待办负责人写明必须完成某件事的人。混淆这些类别后,记录里就会充满「监控」和「审查」这样的模糊动词。
下面这种简洁格式通常很实用:
期间:[开始时间] 至 [结束时间]
审查人:[姓名]
审计验证:通过或需要跟进
发现
- [记录引用] [观察到的事件及上下文]
决定
- [已采取的行动及原因]
待办负责人
- [人员] 将在 [日期] 前完成 [具体行动]
一次每周审查没有发现问题,也可能是一次好的工作,但要写明检查了什么。「没有问题」无法告诉下一位审查人你是否检查了会话来源、撤销、失败或轮换。几行具体记录能为下周建立基线。
不要因为所有人无法出席就推迟审查。一位了解情况的审查人可以先完成证据检查,之后再把问题分派给负责人。等待所有人都到齐,正是七天流程变成六周空档的原因。
记录应当改变访问决定
如果审查只产生一份报告,它就失败了。每个反复出现的发现都应改变以下四项中的至少一项:任务说明、审批边界、凭证权限范围,或自动化本身。
对预期端点反复失败的调用,可能需要修复集成。代理在代码审查期间不断选择部署工作,可能需要更严格的任务说明,并且不应获得部署凭证。反复出现的未知会话,可能需要改变开发者启动代理的方式。反复使用宽权限凭证,则可能说明应按用途拆分凭证。
Sallyport 可以要求新代理进程获得审批,也可以要求每次使用指定凭证时都获得审批。对于需要人类检查每次尝试的操作,应使用第二种控制,而不是试图通过一套庞大规则表达这种判断。
不要对所有地方都增加审批。如果审查人每周都看到同一个无害调用,却无法把它和高风险调用区分开,说明审批设计有问题。应把低风险的重复工作放入边界明确的凭证中,把按次审批保留给那些后果需要人类决定的操作。
保留一份简短清单,记录反复出现的发现及其修复状态。当同一类别连续三次审查都出现时,不要再把它当作孤立观察。有人需要改变运行设计。日志已经告诉你,当前边界与实际工作不匹配。
第一次审查可能会有些尴尬,因为它会暴露缺失的任务引用、没有名称的凭证和不清晰的负责人。这种不适感是有价值的。写下未回答的问题,指定负责人,下周重复同样的流程。目标不是让日志毫无瑕疵,而是建立一个代理环境,让人仍然能够解释谁做了什么、为什么这么做、结果如何,以及哪些访问权限仍然存在。
常见问题
每周应该审查代理活动日志中的哪些内容?
两者都要审查,但应把它们当作不同的证据。会话告诉你哪个代理进程获得了权限,以及权限何时生效。操作记录则告诉你该进程尝试做了什么,以及结果如何。会话列表看起来没有问题,并不能证明其中的调用都合理。
应该多久审查一次自主代理的活动?
对于能够修改基础设施、处理资金或接触客户数据的生产代理,每天审查更合适。对于使用权限受限凭证,并且部署前有人审查的编程代理,每周审查通常更有效。间隔必须足够短,让你还能找出某个事件背后的人、任务和凭证。
代理 API 调用失败总是安全事件吗?
不一定。失败通常意味着权限范围缺失、端点过时、请求格式错误或凭证过期。当失败不断重复、目标指向预期之外的服务或主机、发生在会话本应结束之后,或者在通过其他路径成功调用之前出现时,它才会成为安全问题。
AI 编程代理使用 SSH 时,哪些命令可疑?
关注超出任务预期边界的命令,例如代理在处理文档任务时读取部署凭证、把归档文件复制到陌生主机、修改 shell 初始化文件,或反复探测文件系统路径。判断命令是否可疑要看上下文。单独看一条命令,通常无法公平地做出判断。
撤销代理会话后应该保留哪些证据?
记录撤销时间、被撤销的会话或进程、撤销原因,以及之后是否仍有操作。然后确认代理是否还能通过其他凭证或服务账户访问同一系统。只有当原有权限确实无法再次使用时,撤销才算完成。
应该轮换代理本周使用过的每个凭证吗?
如果轮换日期来自明确的负责人决定、凭证清单或服务提供商要求,就应当轮换。不要因为某个凭证出现在日志里就全部轮换,这会造成服务中断,也会让团队逐渐忽视审查。应优先轮换已过期、在不可信上下文中暴露、权限过宽且没有明确负责人,或用途难以追踪的凭证。
什么样的 AI 代理审计轨迹在调查中有用?
审查内容应包括代理进程身份、会话开始和结束时间、目标、操作、结果,以及发生审批时的审批人。保留原始审计证据,也保留你的审查记录。没有底层记录的电子表格摘要,在之后有人质疑某个发现时是不够的。
防篡改审计日志能取代人工审查吗?
验证只能说明记录后的证据是否被修改过。它无法判断一次经过授权的调用是否恰当、凭证权限是否过大,或失败请求是否无害。你仍然需要一位了解相关任务和系统的人来审查。
如何记录异常代理操作,又不制造文书负担?
每个标记项目保留一条简短记录即可:事件引用、你的预期、实际差异、可能解释、负责人和截止日期。如果不需要采取行动,也写明原因。最后这一行能避免每周五都为同一个无害异常浪费时间。
每周代理安全审查记录应该保存多久?
每周审查应产生决策,而不是一份冗长报告。根据保留要求保存原始审计轨迹,再保存一份简洁的审查记录,其中包括时间范围、审查人、标记事件、撤销操作、轮换决定和待跟进事项。如果读完后没人说得清发生了什么变化,这次审查就写得太含糊了。