AuthProof 是面向 AI 智能体的审计与归因层。它让你能够证明用户在该智能体行动之前授权了什么,并记录该智能体针对该授权实际执行了什么。
其机制很简单。用户用自己的私钥签署一份委托回执。该回执包含范围、边界、操作者指令(已哈希)以及时间窗口。执行前验证器会根据该回执检查每一项拟执行的操作,而仅追加的操作日志会记录实际运行的内容。其结果就是证据:将已授权的内容与实际发生的事情进行比对。
这并不是针对恶意操作者的安全控制。验证器与智能体运行在同一进程中,不诚实的操作者完全可以不调用它。在同一运行时内部,没有任何密码学属性能够解决这一点。AuthProof 为运行该闸门的部署证明授权,并为审计人员、监管机构和用户提供一份事后可核查的记录。
它的不同之处:
用户是签署权威。 授权对象由用户的私钥签署,而不是写入由操作者管理的策略中。回执中已签署的范围和程序哈希始终优先于操作者日志元数据。如果操作者元数据与已签署的回执冲突,闸门会拒绝该操作,而不是遵循元数据。
两阶段模型状态承诺。 模型在授权时被测量,并在执行前重新测量。这些测量由软件计算并自我证明,并非基于硬件根信任。它们是对诚实部署的防篡改证据,而不是针对恶意主机的证明。
区分提供方更新与恶意替换。 模型状态变化被分类为合法的提供方更新(PROVIDER_UPDATE_REQUIRES_REAUTH)和未经授权的替换(MALICIOUS_MODEL_SUBSTITUTION)。每种情况都会产生机器可读的拒绝原因代码,指明哪些组件发生了变化。
在任何智能体操作执行之前运行的闸门。
PreExecutionVerifier.check() 会根据已签署的委托回执验证每一项拟执行的操作。在你的智能体进程中,让每一项操作在执行之前都经过它。验证器会将自己的允许/拒绝决定签署到审计日志中,因此每个结果都是记录的一部分。
有一个必须围绕其构建的硬事实:验证器是同进程的。它验证证明;它无法阻止拒绝调用它的操作者。在你想要证据的地方使用它,而不是在你需要对运行代码的操作者进行强制执行的地方使用它。
如今大多数智能体授权都只是操作者的一面之词:由操作者编写的策略,由操作者控制的代码来执行。当出现问题时,没有记录表明用户实际授权了什么,只有操作者对此的重构。AuthProof 扭转了这一点。用户签署的回执先于执行,而操作日志记录了针对它实际运行的内容。“用户是否授权了这件事?”这个问题变得可核查,而不是可争辩。
import { PreExecutionVerifier, DelegationLog } from 'authproof-sdk/pre-execution-verifier'
import { RevocationRegistry } from 'authproof-sdk'
// 1. Set up the gate
const delegationLog = new DelegationLog()
const revocationRegistry = new RevocationRegistry()
await revocationRegistry.init({ privateKey, publicJwk })
const verifier = new PreExecutionVerifier({ delegationLog, revocationRegistry })
await verifier.init({ privateKey: verifierKey, publicJwk: verifierPub })
// 2. Register your delegation receipt
delegationLog.add(receiptHash, receipt)
// 3. Gate every action â before the agent runs
const result = await verifier.check({
receiptHash,
action: { operation: 'read', resource: 'calendar' },
operatorInstructions: 'Summarize meetings. Stay within scope.',
programHash, // optional: prevents code substitution attacks
})
if (!result.allowed) {
throw new Error(`Blocked: ${result.blockedReason}`)
}
// Agent runtime only reaches here after all thirteen checks pass
| # | 检查 | 阻止条件 |
|---|---|---|
| 1 | 收据签名 | ECDSA P-256 签名无效或收据被篡改 |
| 2 | 撤销 | 收据已通过 RevocationRegistry 被撤销(级联:被撤销的祖先会拒绝其后代) |
| 3 | 时间窗口 | 收据已过期或尚未生效(日志时间戳预言机,而非客户端时钟) |
| 4 | 范围 | 操作不在 ScopeSchema.allowedActions 中;若无结构化模式,关键字匹配仅为建议性,绝不作为门控 |
| 5 | 操作员指令 | 提供的指令与签发时锁定在收据中的哈希不匹配;当调用方省略时跳过并发出警告 |
| 6 | 程序哈希 | 提供的 programHash 与提交的 executes 哈希不匹配(可选) |
| 7 | 会话风险 | 信任/风险阈值被超出(可选) |
| 8 | 工具模式完整性 | toolSchemaHash 与收据不匹配(可选) |
| 9 | 模型状态 | 检测到模型漂移(可选;软件计算、自我证明的测量) |
| 10 | 工具输出哈希绑定 | 输出哈希与收据不匹配(可选) |
| 11 | 指令来源 | 指令来源不在收据的 trustedSources 中(可选) |
| 14 | 父范围包含 | 子收据超出父范围(仅限子收据);撤销任何祖先会在检查时拒绝子收据 |
| 15 | 权限状态漂移 | authorityStateCommitment 自签发以来发生漂移(可选) |
槽位 12 和 13 从未实现;编号空缺是历史遗留。门控在首次检查失败时停止。一次性使用消耗在所有检查通过后最后运行,因此消耗槽位绝不会因其他原因被拒绝的收据而被消耗。
每个检查结果,无论通过或失败,都会自动记录到使用验证者自身密钥签名的不可变 ActionLog 中。
签名数据优先。 签名收据的范围和程序哈希始终优先于操作员日志元数据。如果未签名的 DelegationLog 元数据与签名收据不一致,门控会拒绝该操作(SCOPE_METADATA_MISMATCH / PROGRAM_METADATA_MISMATCH)。仅当收据不携带结构化范围或签名的 executes 值时,日志元数据才作为回退。
引导式委托由观察引导。 ScopeDiscovery.guided() 和 AuthProofClient.delegateGuided() 在一次调用中运行 observe → generateScope → approve → finalize,并且完整的观察草稿范围会自动批准,无需人工审查。对于真正的人工授权时刻,请传入 reviewDraft 钩子(在签发前批准、修改或拒绝草稿),或使用显式的 approve() 分别运行各步骤。
常见框架的即插即用包装器。每个包装器在被包装代码执行之前,通过 PreExecutionVerifier 对每次调用进行门控。
invoke() 方法的代理// LangChain
import { authproofMiddleware } from 'authproof-sdk/middleware/langchain'
const guardedAgent = authproofMiddleware(agent, { receiptHash, verifier })
// Express
import { authproofMiddleware } from 'authproof-sdk/middleware/express'
app.use(authproofMiddleware({ verifier, getReceiptHash: (req) => req.headers['x-receipt-hash'] }))
// Any function
import { guardFunction } from 'authproof-sdk/middleware/generic'
const guardedExecute = guardFunction(executeAction, { receiptHash, verifier, action })
在决定 AuthProof 能为你证明什么之前,请先阅读本节。
ScopeSchema 时,范围匹配只是一种关键词重叠信号,记录用于可观测性。它从不允许或拒绝任何操作。真正的范围强制执行需要 ScopeSchema。operatorInstructions。ConsumptionStore(包含一个 Redis 适配器)。没有它,跨进程的重放检测无法保证。现有的每一个代理身份 IETF 框架——AIP、draft-klrc-aiagent-auth、WIMSE——都解决的是服务到代理的信任问题:下游服务如何验证某个代理有权调用它。它们都没有解决用户到操作者的信任问题。
当前代理系统中的委托链是:
User â Operator â Agent â Services
用户向操作者下达指令。操作者向代理下达指令。但在委托的那一刻,并不存在用户原始意图的加密记录。操作者成为一个受信任的第三方,拥有不受约束的权力,可以在指令到达代理之前对其进行扩展、扭曲或省略。
后果如下:
AuthProof 填补了这一空白。
委托收据是一个签名的授权对象,在任何代理操作开始之前锚定到一个去中心化的仅追加日志。它包含四个必填字段:
允许操作的显式允许列表。未列出的一切默认被拒绝。以结构化格式表达——而非自然语言。操作类别:
| 类别 | 描述 |
|---|---|
reads | 对指定资源的读取访问 |
writes | 对指定资源的写入访问 |
deletes | 删除指定资源 |
executes | 执行特定程序,通过其静态能力签名哈希引用 |
executes 是最危险的类别。它必须引用 Safescript 程序静态能力 DAG 的加密哈希——而不是名称、URI 或描述。哈希不匹配意味着不执行。
在任何情况下都不能被操作者指令覆盖的显式禁止。用户定义的硬性限制,在任何后续操作者指令下都持续有效。
授权的有效期。日志时间戳是时间预言机——而不是客户端时钟。客户端时钟被明确排除在时间验证之外。
委托时操作者所述指令的加密哈希。如果操作者随后向代理下达不同的指令,无需任何额外的信任假设,即可从日志中检测到这一差异。
用户使用其私钥对该对象进行签名。通过 WebAuthn/FIDO2 和设备安全隔区进行的硬件支持签名是推荐的托管模型;也支持软件密钥生成。签名在任何代理操作之前发布到日志。每个后续代理操作都引用该收据哈希。通过门路由但超出范围的操作会被拒绝。
三个协议层消除了三个受信任的第三方:
在当前的 MCP 生态系统中,没有加密证明表明工具服务器的描述与其实际行为相符。操作者可以呈现任意模式。
修复方法:工具服务器在任何用户授权发生之前发布加密签名的能力清单。委托收据的 scope 字段引用此清单的哈希——而不是操作者自我报告的模式。服务器行为与清单之间的差异可在日志层被检测到。
用户的原始意图在操作者指令到达代理之前被不可变地记录。操作者的偏离是可证明的。
Safescript 是一个用于 AI 代理执行的开源沙箱语言。其静态 DAG 结构意味着每个程序的完整能力签名在运行之前都是可计算的——没有动态分派,没有运行时能力扩展。
executes 范围类别引用特定的 Safescript 能力签名哈希。如果操作者提供的程序与已提交的哈希不匹配,执行将被阻止。委托之后,代理不能被替换为不同的程序。
import { AuthProof, Scope, KeyCustody } from 'authproof-sdk';
// Initialize with hardware-backed key custody (recommended)
const authproof = new AuthProof({
custody: KeyCustody.HARDWARE, // WebAuthn/FIDO2 via device secure enclave
log: 'https://log.authproof.dev',
});
// Define permitted operations â explicit allowlist, deny-by-default
const scope = new Scope()
.allow('reads', ['resource://calendar/events', 'resource://email/inbox'])
.allow('writes', ['resource://calendar/events'])
.deny('deletes', '*')
.execute('sha256:a3f1c9d8...', { program: 'scheduler-v1.sg' }); // Safescript hash
// Hard limits that survive any operator instruction
const boundaries = {
never: ['external-network', 'credential-store', 'payment-methods'],
};