# 开发者 Mac 丢失后的响应：安全撤销访问权限

丢失的开发者 Mac 首先是凭据事件，其次才是硬件事件。笔记本可能完好无损地回来，也可能处于解锁、离线或被他人持有的状态，而其中的浏览器会话、SSH 材料、云 CLI 缓存、本地代码库和代理进程仍然带有权限。

最糟糕的做法是等待确定结果。你几乎不会马上得到确定答案。先采取可逆的遏制措施，在嘈杂的变更抹去上下文前保留证据，然后轮换可能让入侵者扩大访问范围的凭据。冷静、有顺序的处理，比在每项服务中慌乱地修改密码更有效。

## 在遏制完成前，将设备消失视为仍在提供访问

假设丢失的 Mac 仍能发起经过认证的请求，直到你停止了关键的访问路径。这个假设不是在指责任何人，也不是在预测一定发生了入侵。它能避免一个常见错误：把设备找回工单当成普通设备问题，而不是一次访问控制事件。

立即记下四个时间点：最后一次实际看到 Mac 的时间、最后一次确认它处于锁定状态的时间、用户最后一次进行敏感工作的时间，以及报告丢失的时间。这些时间界定了审查窗口。不要让人们在会议室里寻找设备时，几个小时都靠记忆慢慢拼凑时间线。

记录最后一次确认安全时设备上打开的内容。具体细节才有用：终端是否连接到生产主机，代理是否正在编辑部署代码，浏览器是否打开云控制台，本地是否存在端口转发，代码库历史中是否有凭据，或者迁移过程中密码管理器是否处于解锁状态。「正在处理后端」几乎无法帮助响应人员判断情况。

在分配工作前，先对情况分类：

- 设备在受控办公室内丢失，且当时处于锁定状态。
- 设备处于解锁状态，或无法确定其锁定状态。
- 设备在公共交通工具、酒店或其他不受控地点消失。
- 设备拥有生产环境访问权限，或正在运行自主代理进程。
- 设备属于管理员、发布工程师或组织账户的所有者。

启用了磁盘加密且使用硬件保护秘密存储的锁定设备，情况会比解锁设备好一些。但这不是跳过撤销操作的理由。设备保护能限制从存储中提取数据，却无法撤回设备解锁时已经执行的操作、使远程会话失效，也无法告诉你设备锁定前是否有人使用过它。

指定一名事件负责人做决策，再指定一名记录人维护时间线。在小团队中，这两项工作可以由同一个人承担。记录人应记下账户、凭据类别、采取的操作、时间、执行者和证据位置。第一小时使用电子表格完全可以接受。带着表情回应的聊天线程不能算事件记录。

不要把丢失 Mac 的最后一个网络地址当成安全证据。网络位置可能已经过时，也可能经过代理或由多人共享。不要通过可能在设备上保持打开状态的账户联系或提醒疑似捡到设备的人。请使用独立的通信渠道。

## 在不破坏调查的情况下遏制设备

远程锁定和远程抹除都是合理操作，但它们只是遏制措施的一条路径。一旦报告信息足以支持这些操作，就通过设备管理服务或操作系统的设备查找服务发出命令。记录请求时间和任何送达确认。

远程命令必须等设备连接到服务后才能执行。如果 Mac 处于离线状态，命令可能一直处于待处理状态。只要有人让设备持续离线，命令就可能很久都无法执行。因此，凭据撤销不能等到抹除确认之后才开始。

请设备管理员在保留期限发生变化或后续抹除导致记录消失前，收集现有的管理记录。可用字段包括设备序列号或资产 ID、分配用户、最后签到时间、操作系统版本、最后报告的 IP 地址、组织记录中的 FileVault 托管状态，以及远程锁定或抹除请求的状态。工具能提供什么就收集什么，不要根据缺失字段编造一个看似完整的故事。

如果丢失的 Mac 使用了个人 Apple Account，应由设备所有者在事件负责人在场的情况下处理设备查找。团队不应要求对方透露个人账户凭据。组织需要确认锁定或抹除请求已经提交，而不是访问与事件无关的个人数据。

从其他系统中保留本地工作的上下文。如果服务商支持按设备阻断，请禁用该设备的 VPN 或零信任设备状态。若设备有证书，请撤销它。将设备从授予网络访问权限的端点管理组中移除。禁用与该端点关联的远程桌面和设备同步权限。

现在也应暂停与该设备相关的无人值守工作。关机后的本地定时任务无法继续运行，但从该设备启动的远程代理、云开发环境、 CI runner 或浏览器自动化可能会独立运行。先确定执行位置，再判断丢失的 Mac 是否仍在控制它。

不要采用「只改用户主密码」这种常见却薄弱的建议。人们喜欢它，因为操作快，也容易看见结果。如果密码可能被他人看到，改密码确实有帮助，但它经常会留下个人访问令牌、OAuth 授权、SSH 密钥、浏览器会话、CLI 刷新令牌和服务专用凭据。重置密码只是更大范围遏制计划中的一项任务。

## 在代理再次发起调用前撤销实时权限

拥有外部操作权限的编程代理，与交互式终端一样需要立即处理。只要代理进程仍在运行、会话仍获授权且设备可以访问网络，它就可能继续调用 API 或打开 SSH。请在网关以及接受其凭据的每个远程服务中停止代理权限。

首先找出可能源自丢失 Mac 的每次运行。记录进程身份、会话开始和结束时间、分配的凭据、目标系统以及最后完成的操作。如果代理主机提供会话列表，请撤销受影响的会话，不要等它们自然过期。如果无法区分丢失设备发起的运行，就撤销该用户的全部会话，之后再创建新的会话。

Sallyport 的 Sessions 日志可以立即撤销代理运行，Activity 日志则记录通过应用发起的单次调用。设备丢失响应期间应同时使用两份记录：前者告诉你要切断哪次运行，后者告诉你在切断前该运行尝试做了什么。

不要把代理名称当成可信身份。进程标签或终端标题中的「Claude Code」无法证明运行的是哪个可执行文件、由谁签名，也无法证明没有攻击者启动一个复制的进程。合格的审批记录应标明调用进程的代码签名机构。将该身份与会话一起记录，然后与已知正常的开发环境进行比对。

网关可以阻止未来的调用，却无法撤回已经到达 API 的请求。如果代理创建了部署令牌、添加了用户、修改了代码库设置或上传了数据，请直接调查对应服务。代理日志能提供线索，但目标服务才是判断操作是否成功的权威来源。

对于通过 MCP server 连接的代理，请在受影响的工作站身份上撤销或禁用连接路径。然后检查源代码库、 shell 配置文件、项目目录和受管理配置中的代理配置。移除旧令牌、审查命令钩子，并确认它没有指向个人账户或生产账户之前，不要把这些配置恢复到替换 Mac 上。

逐次调用审批在这里有明确价值。它要求人在使用凭据的当下做出决定，因此可以降低用户离开设备后的风险。但设备丢失后，它不能替代撤销操作。已经授予运行中会话的审批可能仍对该进程有效，而之前使用过的外部令牌可能已经被复制，或拥有自己的有效期。

## 按攻击者可能滥用的顺序轮换凭据

凭据轮换的核心，是按顺序移除通往权限提升的路径。先轮换能够创建更多访问权限的凭据，再轮换只能读取低风险开发服务的凭据。如果顺序反过来，你可能花一小时重置次要令牌，却让云管理员令牌继续可用。

先处理身份和控制平面访问：身份提供商会话、组织所有者账户、云管理员角色、机密管理器访问权限、源代码管理组织管理员权限、部署控制账户和设备管理管理员权限。如果同一个人拥有所有这些权限，这是遏制完成后需要修复的架构问题，但眼下先处理事件本身。

然后轮换能够移动代码或执行工作负载的访问权限： CI 凭据、软件包仓库发布令牌、签名凭据、部署密钥、云工作负载令牌、容器仓库令牌，以及用于堡垒机或生产主机的 SSH 密钥。最后再处理问题跟踪器、文档工具、低权限 API 令牌和个人服务密码。

为每项凭据使用下面的工作表。它能避免只轮换了秘密，却忘记仍然信任该秘密的系统。

| 字段 | 记录内容 |
| --- | --- |
| 凭据 | 令牌、密钥、证书、会话或 OAuth 授权的准确标识符 |
| 所有者 | 负责使用它的人或服务账户 |
| 权限 | 它允许访问的系统和执行的操作 |
| 位置 | 已知的存储位置、 CI 变量、设备文件和应用设置 |
| 操作 | 撤销、轮换、禁用账户、移除公钥或重新签发 |
| 验证 | 证明旧权限已经失效且合法工作仍能继续的测试 |

不要只覆盖秘密值然后寄希望于它已经失效。如果服务支持单独撤销，请撤销旧项目。以能维持预期工作流的最小范围创建替代凭据。更新获授权的使用方，然后验证旧凭据确实失败。在事件记录中只记录凭据标识符和时间，绝不要记录秘密值。

对于 bearer 令牌，可以调用一个无害的认证端点，验证旧令牌被拒绝而替代令牌被接受。对于 SSH，从每条授权路径中移除旧公钥，然后用该密钥测试连接并确认访问被拒绝。对于 OAuth 授权，在身份提供商中撤销授权，并检查应用的活动会话或令牌列表。

命令行测试可以让结果更加明确。请替换为一个能够返回认证主体的安全端点，并且只在干净设备上运行：

```
curl -i -H "Authorization: Bearer $OLD_TOKEN" https://api.example.internal/whoami
```

撤销之后，预期结果应是认证失败，例如 `HTTP/1.1 401 Unauthorized`，或服务商文档所述的无效令牌响应。返回 `200` 表示旧令牌仍然有效。不要把「我们已经在机密管理器中改过了」当成证据，因为远程服务可能仍接受旧凭据。

SSH 需要特别警惕。开发者经常记得 `~/.ssh/id_ed25519`，却忘记部署密钥、硬件保护的密钥、SSH 证书、转发的代理、登记在源代码管理服务中的密钥、 CI 中的密钥，以及复制到堡垒机上的公钥。要搜索的是访问控制端，而不只是丢失的磁盘。每个接受该公钥的位置都必须停止接受它。

## 检查丢失时间窗口前后的活动

审计审查应回答几个问题：是否发生过访问，使用了什么权限，发生了哪些变化，以及这些变化是否创建了新的回访路径。只查看明显的破坏性命令，会漏掉攻击者通常先做的准备工作。

将审查窗口设为从最后一次确认安全的时间，到所有高权限凭据完成撤销的时间。如果设备在丢失前已经出现无法解释的活动，就向前扩展窗口。如果旧会话或凭据仍然活跃，就向后延长。事件记录中的时间戳统一使用一个时区。

先审查身份提供商事件。关注成功和失败的登录、新增 MFA 方法、恢复设置变更、 OAuth 同意、新应用授权、会话创建、新设备注册和管理员角色变更。一次失败的登录并不一定无害，如果它与成功的刷新操作或来自相同上下文的新会话同时出现，就更需要调查。

接着检查云和基础设施审计轨迹，重点查看能够建立持久访问的操作：新访问密钥、服务主体、 API 令牌、角色分配、策略变更、防火墙变更、创建计算实例、读取机密、导出快照，以及审计日志配置变更。只有读取权限的令牌仍可能暴露足够多的配置，从而帮助攻击者找到更强大的凭据。

源代码管理记录同样需要仔细检查。关注部署密钥添加、个人访问令牌事件、 SSH 密钥变更、分支保护编辑、 Webhook、代码库转移、应用安装、发布、软件包发布以及工作流文件变更。被修改的 CI 工作流可能让未来的一次运行获得比被盗 Mac 本身更多的权限。

对于 SSH 目标，审查认证日志、在收集时可用的命令日志、仅作为辅助证据的 shell 历史、特权命令记录，以及 `authorized_keys` 中的新条目。报告丢失时间之后发生的成功密钥登录必须得到解释，即使来源地址看起来熟悉。企业 VPN 出口可能让许多人显示为来自同一个地址。

Sallyport 会在其日志之后保存一份写入不可篡改、经过加密且带哈希链的审计日志。在干净的 Mac 上，保留现有审计材料，并先运行离线完整性检查，再把其中内容当成证据：

```
sp audit verify
```

验证成功时应报告链条验证通过；如果失败，必须保留受影响的文件，记录错误，并调查验证失败的原因。该命令验证的是密文上的链条，不需要保险库密钥。它能证明记录顺序没有被修改，却不能证明每个远程操作都成功了。

不要把原始日志全部粘贴到聊天频道中，而应建立简短的事件表。包含时间戳、执行者或凭据 ID、来源、操作、目标、结果、证据引用和处置结论。将事件标记为预期、可疑、确认有害或未解决。「未解决」这一列很重要。团队常常因为找到了一个合理的无害解释，就在仍有多个账户变更未审查时关闭事件。

## 寻找持久化访问，而不只是被盗数据

能够使用开发者机器的入侵者，可能更喜欢留下安静的回访方式，而不是立即修改生产环境。寻找能在密码重置后继续存在的新凭据、被修改的自动化和控制变更。

检查每个控制平面最近创建的访问权限：新用户、 API 令牌、 OAuth 应用、 SSH 公钥、部署密钥、服务账户、个人访问令牌、恢复方式、设备注册和委派的管理员角色。如果有基线，就与基线比较。如果没有，请服务所有者逐项人工验证最近的条目，不要直接宣布列表正常。

搜索代码变更，检查被修改的 CI 定义、构建脚本、软件包发布设置、依赖 URL、 Webhook 端点和秘密引用。恶意工作流经常藏在一个很小的拉取请求中，或者伪装成日常维护配置。审查窗口内合并的变更，以及在该窗口内创建的开放分支。

也要检查数据流动。查看制品下载、服务商记录的代码库克隆、客户系统导出、对象存储列举和读取事件，以及新共享的文档。可见性可能并不完整，尤其是事件发生前已经创建的本地克隆。应在记录中明确说明这一限制，不要据此假设没有发生数据导出。

不要对每个异常都过度反应。异常时间的部署可能有经过批准的工单。通过与丢失笔记本无关的通信渠道，向执行该操作的人或自动化账户核实。不要向可能暴露的账户发送确认提示，再把它的回复当成证据。

如果发现持久化访问，就向外扩大范围。堡垒机上的新 SSH 密钥意味着要检查通过它可到达的每台主机。新的源代码管理应用意味着要检查它获准访问的代码库，以及使用其令牌的工作流。新的云角色意味着要检查它的角色分配和活动。先移除持久化访问并保留证据，再轮换它可能读取过的所有凭据。

## 从干净端点恢复访问，不要从备份镜像恢复

替换 Mac 应有计划地获得新的权限。恢复完整备份可能会同时恢复旧令牌、 SSH 密钥、浏览器 Cookie、代理配置、 shell 钩子和未知文件以及源代码。在调查仍在进行时，这种便利代价很高。

将新 Mac 注册到正常的设备管理系统，安装操作系统更新，启用磁盘加密和屏幕锁定，并从可信来源安装获批的开发工具。审查账户访问后，再从远程代码库恢复源代码。尽可能根据版本控制中经过审查的配置重新创建本地设置。

响应期间，使用独立账户或浏览器配置文件处理管理工作。日常开发访问应保持更窄的权限范围。这样，当开发环境最终运行了不可信的扩展、软件包脚本或代理指令时，损失会更小。

为新设备重新签发 SSH 凭据。如果基础设施支持，请优先使用组织管理的 SSH 证书，或为每台机器使用独立密钥。把同一个私钥从一台笔记本复制到另一台，会让每次设备丢失都变成一次大范围迁移。能标明机器和所有者的公钥命名约定，也会让未来的移除操作更快。

只有在工具确实需要时才创建新的 API 令牌。给构建系统单独的凭据，不要把开发者令牌复制进 CI。在服务支持的情况下设置过期时间。记录令牌所有者及其使用位置。无人能够归属的秘密，迟早会变成下一次事件的问题。

最后再恢复代理访问。确认将要连接的可执行文件、它提供的代码签名机构、可使用的通道，以及它能够申请的凭据。可能的话，先使用只读或开发凭据。观察最初的操作，不要因为团队进度落后，就批准一个范围很大的权限。

不要把凭据写进代理提示词、配置文本、问题评论或会进入历史记录的 shell 命令中。操作网关应保存秘密，只在执行请求时注入它。这个边界能避免代理直接获得明文凭据，但不能替你免除对具体操作进行谨慎授权的责任。

## 只有在旧路径确实失效后，才能关闭事件

当丢失的端点不再拥有通往重要访问权限的可用路径，审查窗口已经调查完毕，且替换设备没有重新造成旧暴露时，才可以关闭丢失 Mac 事件。找回实体设备还不够。如果设备保管情况不确定，即使找回，也可能仍需重新注册或抹除。

逐项检查凭据工作表。每项高权限凭据都需要记录撤销或轮换结果。与设备相关的每个活动代理会话都需要记录终止结果。每个可疑事件都需要解释、修复，或记录接受剩余风险的决定。

从受控环境对已经移除的访问路径执行否定测试。确认禁用的 VPN 访问会拒绝旧设备身份。确认撤销的 SSH 密钥连接失败。确认旧 API 令牌失败。若服务支持会话检查，确认旧组织会话无法访问管理页面。这些测试能发现旧凭据仍在次要区域、被遗忘的堡垒机或另一个身份租户中有效的情况。

趁细节还清楚时写一份简短的事件后记录。包括时间线、影响、受影响的凭据、审查过的证据、采取的操作、尚未解决的不确定性，以及将要进行的改进。不要追责。如果响应依赖某个人记得令牌存放在哪里，那么需要补充的是清单和所有权，而不是训斥。

实际测试很简单：如果有人明天打开丢失的 Mac，它还能执行哪些操作？继续处理，直到真实答案变成「没有任何重要操作」。这个标准比收到远程抹除回执更严格，也正是保护系统所需要的标准。
