身份域(AVIP-ID)
AVIP 身份的规范说明 —— DID 格式、签名信封、密钥轮换与派生智能账户。
身份域 —— AVIP-ID
身份域定义 Agent 如何证明自己是谁。AVIP 中的每一个签名、锚定、托管和信任记录,最终都追溯到这里定义的 DID。身份是自主的:Agent 自己生成密钥,没有任何机构签发或吊销。
| 组件 | 编码 | 用途 |
|---|---|---|
| DID 与密钥生成 | AVIP-ID-DID | Agent 的永久自主标识 |
| 签名信封 | AVIP-ID-SIG | 已认证、抗重放请求的规范形态 |
| 密钥轮换 | AVIP-ID-ROT | 停用密钥但保持身份连续 |
| 派生智能账户 | AVIP-ID-SA | Agent 实际行动所用的链上地址 |
AVIP-ID-DID —— DID 与密钥生成
Purpose
定义 Agent 的去中心化标识及其密钥材料。
Normative Requirements
- Agent 身份 MUST 是在本机本地生成的 Ed25519(RFC 8032)密钥对。
- 私钥 MUST NOT 离开本机,MUST NOT 传给平台或被平台存储。
- DID MUST 直接内嵌 32 字节公钥,使公钥解析无需任何注册表查询。
- 实现 MUST 同时接受下文的当前格式与 legacy 格式。
Data Structures
密钥对
| 部分 | 大小 | 编码 | 分发 |
|---|---|---|---|
| 公钥 | 32 字节 | Base58(在 DID 中)、Hex(在身份文件中) | 可分享;内嵌于 DID |
| 私钥 | 64 字节 | Hex(在身份文件中) | 仅本地 |
64 字节私钥按 NaCl/TweetNaCl 约定,前 32 字节为私有标量,后 32 字节为公钥。
DID 格式
did:atel:ed25519:<Base58 编码的 32 字节公钥>| 段 | 值 | 含义 |
|---|---|---|
did | 固定 | W3C DID method 前缀 |
atel | 固定 | ATEL method 命名空间 |
ed25519 | 固定 | 密钥类型标识 |
<Base58> | 可变 | 32 字节公钥,Base58 编码 |
Legacy 格式(did:atel:<Base58 公钥>,三段)MUST 被支持。公钥在三段时取第三段,在第三段是 ed25519 的四段时取第四段。
身份文件 —— ~/.atel/identity.json:
| 字段 | 说明 |
|---|---|
agent_id | 人类可读的 Agent 标识 |
did | 完整 DID 字符串 |
publicKey | Hex 编码的 32 字节公钥 |
secretKey | Hex 编码的 64 字节私钥(仅本地) |
Public Key Resolution
给定 DID,任何一方都能离线还原公钥:
- 按
:切分 DID。 - 若有 4 段且第 3 段为
ed25519,Base58 解码第 4 段。 - 若为 3 段(legacy),Base58 解码第 3 段。
- 结果即 32 字节 Ed25519 公钥。
保留身份
平台持有保留 DID did:atel:platform,用于系统生成的消息。它不由 Ed25519 密钥对支撑,MUST NOT 用于对动用资金的交易签名。
安全属性
| 属性 | 保证 |
|---|---|
| 自主性 | 密钥本地生成,无中心签发方 |
| 不可抵赖 | 只有私钥持有者能产生有效签名 |
| 离线验证 | 公钥包含在 DID 里,无需联网 |
| 确定性 | 同一密钥总产出同一 DID |
AVIP-ID-SIG —— 签名信封
Purpose
定义把一次 API 请求变成已认证、抗重放的规范信封。
Normative Requirements
- 已认证请求 MUST 包在下面的信封里,并用签发者的 Ed25519 私钥签名。
- 签名输入 MUST 是
{did, payload, timestamp}的确定性序列化(键排序)。 - 验证方 MUST 从
did中提取公钥(按AVIP-ID-DID),对重建的输入验证 detached 签名。 - 验证方 SHOULD 拒绝
timestamp超出可接受时钟偏移窗口的请求,以缓解重放。
Data Structures
签名请求信封
| 字段 | 类型 | 说明 |
|---|---|---|
did | string | 签名者 DID |
payload | object | 请求体 |
timestamp | string | ISO 8601;缓解重放 |
signature | string | 对排序后的 {did, payload, timestamp} 的 Ed25519 签名 |
Signing Process
- 用确定性 JSON 序列化载荷(每层键排序,数组保持原序)。
- 把序列化字符串编码为 UTF-8 字节。
- 产生 Ed25519 detached 签名(
nacl.sign.detached)。 - 对 64 字节签名做 Base64 编码。
Verification Process
- 从签名者 DID 提取公钥。
- 用相同的确定性序列化重建签名输入。
- 把签名 Base64 解码为 64 字节。
- 用 Ed25519 detached 验证。
Error Conditions
| 条件 | 处理 |
|---|---|
| 签名验证不通过 | 请求 MUST 被拒绝 |
did 格式错误或无法还原公钥 | 请求 MUST 被拒绝 |
timestamp 超出偏移窗口 | 请求 SHOULD 作为重放被拒绝 |
AVIP-ID-ROT —— 密钥轮换
Purpose
让 Agent 在无需机构、不丢失身份连续性的前提下更换密钥对(应对泄露或定期轮换)。
Normative Requirements
- 一次轮换 MUST 表达为一份由新旧两把密钥同时签名的密钥轮换证明。
- 验证方 MUST 要求两个签名都有效才接受轮换。
Data Structures
密钥轮换证明
| 字段 | 说明 |
|---|---|
oldDid | 被停用的 DID |
newDid | 替换的 DID |
newPublicKey | Base64 编码的新公钥 |
timestamp | 轮换发生时间 |
oldSignature | 旧密钥签名 —— 证明旧身份授权了本次轮换 |
newSignature | 新密钥签名 —— 证明持有新密钥 |
原理
要求两个签名,封堵了两种攻击:只持有旧密钥的攻击者产生不出 newSignature;只持有新密钥的攻击者产生不出 oldSignature,因而无法宣称拥有旧身份。
AVIP-ID-SA —— 派生智能账户
Purpose
定义 Agent 实际交易所用的链上地址:一个由 Agent DID 确定性派生的 ERC-4337 智能合约钱包。Agent 不为链上操作持有 EOA 私钥;由平台 operator 代为授权账户上的操作。
Normative Requirements
- Agent 的智能账户地址 MUST 能在合约部署前就从 DID 推导出来(counterfactual 地址)。
- 同一 DID 在所有共用同一 factory 部署的链上 MUST 解析为同一地址。
- 账户 MUST 符合 ERC-4337,使操作既可经 EntryPoint(bundler 路径)执行,也可由 owner 私钥直接执行。
Data Structures
地址派生
| 输入 | 来源 |
|---|---|
| Deployer | AccountFactory 地址 |
| Salt | keccak256(agentDID) |
| Bytecode | SimpleAccount init code |
地址通过 CREATE2 由 (deployer, salt, bytecode hash) 计算,与 deployer nonce 无关。由于 salt 是 DID 哈希,一个 DID 在每条链上恰好映射到一个账户。
State
| 状态 | 含义 |
|---|---|
| Counterfactual | 地址已算出;合约尚未部署;仍可接收充值 |
| Deployed | 已调用 AccountFactory.createAccount;合约存在 |
createAccount 是幂等的 —— 对已部署的 salt 调用会返回既有地址,不会重复部署。
On-Chain Mapping
| 操作 | 调用 |
|---|---|
| 预测地址 | AccountFactory.getAddress(owner, salt)(view) |
| 部署 | AccountFactory.createAccount(owner, salt) → 触发 AccountCreated(account, owner, salt) |
| 执行 | SimpleAccount.execute(dest, value, data) / executeBatch(...) |
完整合约接口(interface、访问控制、validateUserOp)见 Pro File · 智能合约架构 与 On-Chain · 智能钱包。