# 域名注册商安全需要逐次调用批准

向 AI 智能体提供注册商 API 凭据，并不是授予它一种统一的权限。这个秘密背后其实有几种彼此无关的能力：重定向域名、为转移做准备、修改接收恢复通知的人，以及改变 DNSSEC 信任链。当批准层把这些调用都当成可互换的操作时，域名注册商安全就会失效。

每一次会改变状态的注册商调用，都应有一项与具体动作、域名、旧值和拟议新值绑定的决定。人工可以批准计划迁移期间替换名称服务器，同时拒绝同一次运行中的移除锁、修改注册人邮箱或删除 DS。仅靠会话批准表达不了这种区别。

## 一份凭据隐藏了多条安全边界

注册商凭据只是认证事实，不是人类意图的声明。即使服务商提供细粒度 API 权限，团队也常把自动化任务所需的多项写操作放进一个角色，以便任务完成。另一些服务商则提供权限很宽的注册商令牌。无论哪种情况，持有凭据只回答谁可以发起请求，无法回答此刻是否应进行这项具体变更。

底层协议也从未把这些操作视为等价。RFC 5731 定义了注册商与注册局之间使用的 EPP 域名映射，将名称服务器关联、联系人关联、状态值和授权信息列为独立的域名属性。它的更新命令可以添加或删除名称服务器和联系人、修改注册人、修改授权信息及客户状态值。方便的 API 可能把它们放在同一份凭据下，注册局状态仍会把它们的含义分开。

公共云注册商的命令列表也体现了这种差异。Route 53 Domains API 为 `UpdateDomainNameservers`、`UpdateDomainContact`、`DisableDomainTransferLock`、`AssociateDelegationSignerToDomain` 和 `DisassociateDelegationSignerFromDomain` 提供了独立操作。这些名称正是批准系统应保留的决策，而不是把它们压扁为 `registrar.write`。

在向任何智能体授予注册商访问权限前，我会问四个问题：

- 这次调用能否重定向整个域名的解析？
- 它会不会让之后的盗取或恢复更容易？
- 它能否修改接收控制或验证消息的人？
- 它会不会让验证型解析器拒绝原本正确的 DNS 响应？

如果两次调用的答案不同，它们就应是不同的批准动作。共用 API 密钥不会消除这种差异。

## 修改名称服务器等于委托整个区域

替换名称服务器会把 DNS 权威交给新的服务器集合，因此影响范围远大于编辑一条记录。RFC 8499 将委托定义为父区为子区起点添加一组 NS 记录。缓存沿着该委托查询后，新的权威服务器可以响应区域中的网站地址、邮件交换器、服务发现记录和验证 TXT 记录。

最后这一类很容易让人低估风险。RFC 8555 说明，ACME 客户端可以通过在 `_acme-challenge` 下配置 TXT 值来证明对域名的控制。控制被委托区域的操作者可以响应该挑战，并在证书颁发机构检查通过的前提下，为该域名下的名称申请证书。因此，修改名称服务器不只是托管设置。

批准界面应展示完整的旧服务器集和新服务器集，不能只写一句 `update DNS`。集合很重要，因为迁移常先添加服务器，再移除旧服务器，而某些注册商 API 会在一次调用中替换完整集合。审核人需要看到请求是否保留所有预期服务器、是否涉及 glue 地址，以及目标服务器是否已能为该区域提供权威响应。

批准前，应直接查询每台拟议服务器，不要相信递归缓存：

```sh
for ns in ns1.new-dns.example ns2.new-dns.example; do
  dig +norecurse +short @"$ns" example.com SOA
  dig +norecurse +short @"$ns" example.com MX
done
```

健康检查应从每台服务器返回一条 SOA 和预期的 MX 目标。空输出、序列号不一致或没有权威性的响应都需要调查。具体迁移计划决定序列号是否必须已一致，但审核人不应批准一台尚未为该区域响应的服务器。

批准记录应将动作标为 `nameserver.replace`，包含有序请求和标准化集合差异，并说明调用是否同时修改 glue。不要把它藏在通用域名更新中，因为一次看似合理的智能体失误就可能同时改道所有服务。

## 移除转移锁会打开窗口

关闭转移锁不会转移域名，但会移除一项防止转移的控制。ICANN 将常见的注册商锁称为 `clientTransferProhibited` 或类似状态。RFC 5731 规定，只要 `clientTransferProhibited` 或 `serverTransferProhibited` 生效，转移请求就必须被拒绝。

审核时必须理解这一差异。智能体在计划迁移前可能确实需要移除锁，但意外移除锁仍然危险，因为它为其他参与者创造了有用的前提。应将 `transfer_lock.disable` 视为独立动作，并要求请求写明目标注册商、变更工单和预期重新上锁或完成时间。这些字段不会强制注册商执行计划，却能让批准人有足够背景拒绝无法解释的移除锁请求。

授权码是另一份秘密，也应单独决策。获取它绝不能隐藏在批准移除锁之中。实用的控制平面会先询问是否移除锁，再询问是否获取或使用转移授权码。如果流程还会变更注册人，顺序尤为重要，因为 ICANN 的 Transfer Policy 要求，适用情况下注册人变更后会有 60 天的注册商间转移锁，除非注册商在变更前提供退出选项且注册人选择了它。

常见建议是保持域名锁定，因此注册商自动化就安全。锁确实有帮助，但这只看到了第一步。能够移除锁的凭据也能消除这层保护。逐次调用批准能在关键时刻让移除动作可见，而只检查当前锁定状态的常驻策略会被下一次 API 请求推翻。

开启锁通常是风险较低的修复动作，却仍是一项会带来运维后果的写入。它可能阻止正在进行的合法转移。除非事故流程明确授权紧急重新上锁，否则应展示待处理转移状态并让人工确认。

## 联系人变更会改变恢复路径

更新注册人或管理联系人会改变谁接收重要通知，也可能影响转移资格。它不会立即重定向流量，团队因此容易把它排在名称服务器工作之后。这种排序忽略了域名恢复的实际过程。

ICANN 建议注册人保持联系信息最新，因为注册商会通过电子邮件发送保护和管理通知。其 Transfer Policy 也会在适用情况下将注册人变更与 60 天转移锁关联。智能体若在计划转移前片刻替换注册人邮箱，可能延误工作。攻击者若更改可联系的联系人，可能干扰通知或未来恢复，具体取决于注册商和注册局流程。

批准卡片需要字段级差异。当一次请求同时改变邮箱、电话号码、组织、隐私设置和注册人身份时，`contact.update` 太过笼统。请展示每项旧值和新值，标注改变的联系人角色，并显示注册商报告的转移限制。日常日志可对个人数据脱敏，但批准敏感身份变更的人必须看到足以识别预期接收者的信息。

不要让智能体通过反复修改字段来解决失败的联系人更新，直到 API 接受为止。各注册局的验证规则不同，部分国家和地区顶级域名还有额外要求。更安全的流程是验证载荷、为最终差异申请批准、只提交一次，并记录服务商的操作标识符。若服务商异步处理变更，在读取确认目标状态前，该动作都应保持待处理状态。

联系人隐私是另一项独立动作。改变隐私暴露程度不同于修改底层注册人。审核人可能接受隐私开关，却拒绝所有权变更，因此批准系统不应只因供应商使用同一端点就把两者合并。

## DNSSEC 变更可能让正确响应失效

DNSSEC 委托变更会修改验证型解析器认证子区的信任链。RFC 4034 的定义很明确：DS 记录通过密钥标签、算法和摘要指向 DNSKEY，DS 记录位于委托的父侧，对应 DNSKEY 位于子区。由于注册人无法直接编辑父区，注册商 API 通常会把 DS 材料传给注册局。

错误的名称服务器会重定向响应，错误的 DS 记录会让解析器把真实响应标为伪造。这是不同的故障模式，需要不同审核。删除 DS 可能在缓存更新后让安全委托的区域变成不安全委托。添加与已发布 DNSKEY 不匹配的 DS 会破坏验证。密钥轮换时过早删除旧 DS，可能让仍依赖缓存数据的验证器失去可用路径。

对 `dnssec.ds.add`、`dnssec.ds.replace` 和 `dnssec.ds.remove` 的批准，应显示密钥标签、算法、摘要类型、摘要指纹，以及从每台权威服务器收集的 DNSKEY 证据。审核人还应看到请求是在轮换期间增加重叠，还是一次替换唯一的 DS。

这些命令展示了信任链的两侧：

```sh
dig +short example.com DS
dig +short example.com DNSKEY
dig +dnssec example.com A
```

第一条沿常规解析路径查询父侧 DS 数据。第二条获取子区 DNSKEY 集合。第三条展示用于验证的响应和 DNSSEC 记录，在验证路径上，解析器已认证数据时响应标志可能包含 `ad`。审核不能只核对数字密钥标签，摘要和算法必须匹配预期 DNSKEY，发布顺序也必须考虑缓存。

DNS 托管商的一键“启用 DNSSEC”流程可为人工协调这些细节。分别使用注册商和 DNS API 的智能体不会自动继承这些保障。应要求拟议顺序、新密钥已发布的证据，以及每次父侧变更的明确批准。

## 批准应绑定到标准化动作

批准对象应描述含义，而不是只暴露原始 HTTP 请求。URL、服务商操作名称和 JSON 结构各不相同。稳定的内部动作名称能让审核人在不同注册商中识别同一类安全事件，同时不假装各服务商行为完全一致。

下面是一种适合智能体工具边界的实用动作封装：

```json
{
  "action": "nameserver.replace",
  "domain": "example.com",
  "before": {
    "nameservers": ["ns1.old-dns.example", "ns2.old-dns.example"]
  },
  "after": {
    "nameservers": ["ns1.new-dns.example", "ns2.new-dns.example"]
  },
  "reason": "CHG-1842 registrar migration",
  "evidence": {
    "authoritative_checks": "passed",
    "checked_at": "2026-07-24T14:25:00Z"
  },
  "request_hash": "sha256:..."
}
```

网关应从方法、端点和经验证的请求体中推导动作。智能体不能一边选择友好的动作标签，一边发送不同请求。把批准绑定到规范请求哈希，避免智能体为一组名称服务器取得同意后提交另一组。若异步服务商要求第二次调用来确认操作，也应按该调用实际提交的内容分类并批准。

标准化还能揭示混合变更。RFC 5731 允许一次域名更新同时触及名称服务器、联系人、状态值和授权信息。若注册商端点允许在一个载荷中包含多个类别，API 允许时应在批准前拆分流程。无法拆分时，须在批准中展示所有动作并采用最严格的决定。`domain.update` 这样的标签几乎无法告诉审核人任何信息。

应拒绝未包含当前状态的请求。没有最新读取，差异可能基于过时假设，进而覆盖他人的修改。服务商提供版本令牌或条件请求功能时应使用它。若两者都没有，应在提交前立即读取，将标准化状态与获批的 `before` 值比较，任何不匹配都应停止。

## 读取和写入需要不同的阻力

逐次调用批准应覆盖注册商凭据的敏感使用，而不是让人们不断点击无害的资产清单读取。每一次列表操作都打断开发者，批准机制就会变成障碍，审核人也会停止认真阅读。正确边界取决于影响和披露。

公开 DNS 查询不需要注册商凭据。读取域名清单、私密联系人数据、转移码、账单数据或待处理操作等已认证数据，则应区别处理。域名详情读取可能暴露个人联系人信息。获取授权码会立即产生转移能力，即使 API 目录把它称为读取。

可采用简明的分类规则：

列出受管域名和读取脱敏状态通常可使用会话批准，因为它们披露清单而不改变状态。获取转移授权码需要逐次批准，因为它会产生可促成转移的秘密。

替换名称服务器、移除转移锁、修改注册人或管理联系人，以及增加、替换或删除任何 DS 数据，都需要逐次批准，因为它们会改变控制权或验证。续费则取决于策略：它会花钱，却通常保留控制权，因此团队可在设定的支出上限内预先授权。

最后一类不应被强行套用同一个答案。续费会影响资金和生命周期，但风险不同于重定向或转移域名。团队可以在支出上限内预先授权续费，同时对每次委托变更要求人工处理。这正是清晰命名动作的意义。

不要仅按 HTTP 方法分类。有些 API 对读取和写入都使用通用 POST。也不要使用 `Write` 这类宽泛服务商分类。Route 53 Domains 授权参考资料确实把替换名称服务器、更新联系人和移除转移锁列作独立权限，但批准层仍需要实际域名和数值差异。

## 审核人需要证据，不是智能体文案

智能体生成的说明只是背景，不是证据。批准界面应以独立收集的事实开头：已认证进程、准确域名、标准化动作、变更前后值和检查结果。智能体给出的原因应放在这些字段之后。

对于名称服务器请求，应从每台拟议服务器收集权威 SOA 和关键记录检查。对于 DS 请求，应收集当前父侧 DS 和子侧 DNSKEY 集合。对于移除锁，应收集当前状态和所有待处理转移。对于联系人变更，应展示改变的角色及注册商说明的锁定后果。收集证据的代码应位于受信任边界内，因为智能体可能意外概括了过时输出，或遗漏不方便的差异。

批准必须过期。五小时前的名称服务器差异可能已无法描述当前状态。有效期既要短到能限制漂移，也要长到让人工检查证据。不要把一个通用数字照搬到所有流程，应根据注册商并发模型和团队响应时间设定，并在 `before` 状态变化时拒绝请求。

批量批准只在每一项都可见且同质时才安全。如果卡片列出每个域名、每个域名的证据都通过，为二十个停放域名批准同一次名称服务器迁移可以合理。把名称服务器变更、移除锁和联系人更新合并成一个“批准迁移”按钮，会抹去审核人需要的区别。

批准被拒后，应停止调用，不能让智能体不断改写说法并重试，直到有人点击同意。记录拒绝及请求哈希。实质改变的请求可以再次申请，但系统应清晰显示差异。

## 验证也是动作的一部分

成功的 HTTP 响应往往只表示注册商接受了任务，并不表示注册局和 DNS 已公开预期状态。许多域名 API 会返回供后续轮询的操作标识符。日志应把提交、服务商完成和公开验证视为独立状态。

一次紧凑的验证流程可以捕获大多数敏感变更后的意外：

1. 保存服务商操作标识符，并按文档轮询状态，直到进入终止状态。
2. 再次读取注册商状态，并与获批的 `after` 对象比对。
3. 通过多个递归路径查询父侧 NS 和 DS 数据，再直接查询权威服务器。
4. 测试依赖该区域的一小组服务，包括邮件路由，以及存在时的证书验证记录。
5. 只有证据一致后才关闭变更，否则执行已准备好的恢复路径。

这是少数必须严格限制重试的场景。重试超时的读取很正常。未知响应后重试状态变更请求，可能创建重叠任务或把一个值切换两次。重试前，应通过幂等令牌查询，或读取当前操作和域名状态。若服务商不提供幂等机制，应上报这个含糊结果，而不是猜测。

回滚也因动作而异。恢复旧名称服务器可能恢复委托，但缓存会延迟收敛。若转移尚未推进，重新开启转移锁可关闭暴露窗口。恢复联系人可能触发新的确认或锁定。若匹配的私有签名密钥已不再有效，恢复旧 DS 也可能失败。恢复记录必须在批准前写明特定动作的反转方式及前提条件。

维护窗口不能替代验证。DNS 变更会按现有 TTL 经缓存传播，注册商操作也可能异步。应持续监控，直到旧状态和新状态都如迁移计划所预期地运行。

## 分离凭据不能替代逐次同意

最小权限依然重要。只让智能体访问所需的注册商账户、域名和操作，服务商允许时，不要给它账单或无关域名组合的访问权。短期凭据和进程隔离可进一步降低暴露。

不过，把一份宽权限令牌拆成四份凭据，并不能证明意图。智能体仍可在许可范围内滥用名称服务器凭据，受损进程也可等到合适令牌出现。分离凭据降低最大影响范围，逐次调用同意决定某一次影响是否应该发生。

会话授权和逐次调用批准解决的是不同问题。会话授权回答该智能体进程在运行期间能否通过网关执行操作。逐次调用批准会在少数需要人工将意图与精确影响对照的操作上暂停。读取和常规低影响调用可在会话中继续，而标记为需批准的注册商密钥会在每次使用时暂停。

Sallyport 通过保险库关卡、每个新智能体进程的授权，以及一项要求每次使用均获批准的密钥选项实现这种分离，同时不让注册商秘密进入智能体。对于宽权限注册商凭据，应把密钥设为逐次调用，并让请求描述携带上文的标准化动作和差异。

不要教智能体临时持有 API 令牌来完成一批任务。令牌一旦进入模型进程，批准就只能起建议作用，因为后续调用可以绕过关卡。存储凭据的组件必须自行执行获批请求，只返回结果。

## 审计记录必须能还原决策

一条写着“智能体调用了注册商”的审计记录无法解决事故。记录必须展示人工看到什么、批准什么、发送了哪些字节、服务商返回什么，以及之后验证观察到什么。否则团队只能证明发生过活动，无法证明曾获授权。

每次敏感调用都应保存进程身份、会话标识符、批准人、决定时间、标准化动作、域名、变更前后对象、请求哈希、服务商操作标识符、响应状态和验证结果。应按数据处理规则保护个人联系人值，同时保留稳定摘要或受控加密副本，以便调查人员区分两次变更。

也要保留拒绝和撤销事件。若操作员在看到意外的移除锁请求后撤销智能体会话，这段顺序能解释后续调用为何停止。只追加、哈希链式日志能让静默编辑变得可检测，独立导出或验证则避免依赖执行动作的同一界面。

Sallyport 会从同一份加密、哈希链式审计日志中记录智能体会话和单次调用。`sp audit verify` 可在没有保险库密钥的情况下对密文离线检查链条。验证能证明记录链未被篡改，动作封装则提供调查人员需要的域名特定含义。

批准记录也应跨越服务商抽象。把服务商操作名称与标准化动作并列存储，不要用前者代替后者。这样，调查人员可以把 `dnssec.ds.remove` 这样的可移植标签追溯到准确 API 调用，又不必要求每位审核人学习所有供应商术语。保留规范请求字节或其加密摘要，并记录生成动作所用的标准化版本。若分类器以后改变，调查人员仍能还原操作员当时看到的决定，而不是把新逻辑应用到旧事件上。

在信任这份记录前先测试它。让一个无害的测试域名变更走完批准流程，用相同说明拒绝一项已修改请求，撤销智能体会话，并确认日志按顺序保留这三类事件。然后模拟含糊的服务商超时，确认流程会读取状态，而不是盲目重新提交。只在成功调用时有效的审计设计，会在它本应解释的事故中失效。

第一个有用的改变，就是别再把注册商工具叫作“更新域名”。应分别命名名称服务器替换、移除转移锁、联系人变更、获取授权码和 DS 变更。然后，把人工同意放在承载各自影响的那次调用上。凭据仍可能很宽，因为服务商就是这样设计的，但决策不必如此。
