内容
# 代理身份
## 这是什么
代理身份(agent-identity)为 AI 代理提供了一个持久、可验证的身份,其首项功能是基于 AWS SES 的仅接收邮件的邮箱。代理的身份是一对 Ed25519 密钥,在首次使用时在客户端生成,并存储在 `~/.config/agent-identity/<profile>.json` 中。注册时会分配一个永久的随机数字 ID;邮箱地址为 `<id>@<domain>` — 仅限数字,无名称。身份和邮箱同时创建,且不可变。驱动用例是 GitHub 入职:代理需要一个电子邮件地址来创建 GitHub 账户,以便其可以撰写提交、开启拉取请求和接收通知。该项目是开源的,可自行托管;参考部署是私有的,通过舰队密钥(fleet key)进行控制,因此只有操作员自己的代理可以注册。
## 快速开始(代理)
将 MCP 服务器添加到您的克劳德(Claude)或兼容客户端配置中:
```json
{
"mcpServers": {
"agent-identity": {
"command": "npx",
"args": ["tsx", "/path/to/agent-identity/packages/mcp/src/server.ts"],
"env": {
"AGENT_IDENTITY_API_URL": "https://<api-id>.execute-api.<region>.amazonaws.com",
"AGENT_IDENTITY_FLEET_KEY": "<from mailctl fleet-key create>",
"AGENT_IDENTITY_PROFILE": "default"
}
}
}
}
```
在每个会话开始时调用 `ensure_identity` — 它加载或创建您的密钥对,向服务器注册(幂等),并返回您的 `agentId` 和 `address`。其他工具包括 `list_emails`(返回包含 id、发件人、主题、接收时间的摘要)、`get_email`(返回给定 id 的完整文本正文和提取的链接)和 `wait_for_email`(轮询直到匹配的消息到达;当超时到期时,返回 `{timedOut: true}` 作为干净的结果,而不是错误)。检索的电子邮件中的链接由代理自行处理 — 服务器不会获取 URL。
## 部署(操作员)
SES 入站电子邮件仅在 **us-east-1**、**us-west-2** 和 **eu-west-1** 可用。将您的堆栈部署到其中一个区域。
1. 安装依赖项:
```bash
pnpm install
```
2. 部署 CDK 堆栈,替换您的域名:
```bash
cd infra && npx cdk deploy -c domain=mail.example.com
```
堆栈输出 API URL、MX 记录值和 SES 域名验证记录。注意 `MxRecord` 输出。
3. 在 SES 中验证您的域名并添加 DNS 记录。 为您的域名创建 SES 电子邮件身份:
```bash
aws sesv2 create-email-identity --email-identity mail.example.com
```
然后添加 DKIM CNAME 记录和 SES 控制台(或上述命令的输出)提供的域名验证 TXT 记录。添加一个 MX 记录到您的域名,指向堆栈的 `MxRecord` 输出的值。
4. 激活 SES 接收规则集。CDK 创建规则集但不激活它 — 您必须手动执行此操作:
```bash
aws ses set-active-receipt-rule-set --rule-set-name <ReceiptRuleSetName from stack output>
```
5. 生成一个舰队密钥,以便代理可以注册:
```bash
AGENT_IDENTITY_TABLE=<TableName output> npx tsx packages/admin/src/mailctl.ts fleet-key create --label <label>
```
通过 `AGENT_IDENTITY_FLEET_KEY` 环境变量将生成的密钥提供给代理。
其他管理员操作(列出代理、吊销身份)使用相同的 `mailctl` CLI,并直接使用操作员的 AWS 凭证对 DynamoDB 进行操作。没有管理员 HTTP API。
## CI/CD(GitHub Actions)
`.github/workflows/deploy.yml` 在每次推送到 `main` 或从 Actions 选项卡按需测试和部署堆栈。部署通过 GitHub OIDC 认证到 AWS — 没有长期存储的 AWS 密钥存储在 GitHub 中。
一次性设置(在 CloudShell 或任何具有管理员凭证的 shell 中运行,在目标区域 — SES 入站需要 us-east-1、us-west-2 或 eu-west-1):
1. 初始化 CDK 工具包:
```bash
npx aws-cdk@2 bootstrap aws://$(aws sts get-caller-identity --query Account --output text)/$AWS_REGION
```
2. 创建 OIDC 提供程序和部署角色(如果账户已经有一个 GitHub OIDC 提供程序,请添加 `CreateOidcProvider=false` 到参数覆盖中):
```bash
curl -sO https://raw.githubusercontent.com/critical-labs/agent-identity/main/infra/github-oidc.yml
aws cloudformation deploy --template-file github-oidc.yml \
--stack-name agent-identity-github-oidc --capabilities CAPABILITY_NAMED_IAM
aws cloudformation describe-stacks --stack-name agent-identity-github-oidc \
--query "Stacks[0].Outputs[?OutputKey=='DeployRoleArn'].OutputValue" --output text
```
3. 在存储库 **Settings → Environments** 中,创建一个名为 `production` 的环境(可选地,需要审查者来控制部署)。
4. 在存储库 **Settings → Secrets and variables → Actions → Variables** 中,设置:
- `MAIL_DOMAIN` — 邮件域名,例如 `mail.example.com`
- `AWS_REGION` — 例如 `us-east-1`
- `AWS_DEPLOY_ROLE_ARN` — 步骤 2 中的 `DeployRoleArn` 输出
5. 从 Actions 选项卡运行 **deploy** 工作流。作业摘要列出了堆栈输出和剩余的手动步骤(DNS MX 记录、SES 域名验证、舰队密钥)。工作流自动激活 SES 接收规则集。
如果部署作业在 `configure-aws-credentials` 处失败,通常的原因是信任策略不匹配:角色仅信任 `repo:critical-labs/agent-identity:environment:production`,因此环境名称和存储库必须完全匹配。
## GitHub 入职流程
GitHub 阻止自动化注册 — 其服务条款要求人工账户创建,验证码强制执行。因此,在恰好一个步骤中流程是人工协助的:
1. 代理调用 `ensure_identity` 并接收其永久地址,例如 `482913@mail.example.com`。
2. 代理请求其人类使用该地址完成 GitHub 注册表单。人类处理服务条款接受和验证码 — 这是唯一无法自动化的步骤。
3. GitHub 向代理的邮箱发送验证电子邮件。代理调用 `wait_for_email`(使用 `subjectContains` 匹配 GitHub 的主题行),然后 `get_email` 以检索完整消息并显示验证链接。代理或人类跟随链接以确认账户。
4. 账户上线。代理的人类配置凭证或个人访问令牌(PAT)。持续的 GitHub 通知电子邮件流到代理的邮箱,并可通过 `list_emails` / `get_email` 读取。
## 安全模型
**签名认证。** 每个 API 调用都使用代理的 Ed25519 私钥签名,私钥是对 HTTP 方法、路径、时间戳和正文哈希的串联进行签名的。服务器解析请求头中的公钥,查找代理,并验证签名。没有承载令牌。时间戳偏差容忍度为 ±5 分钟;吊销的代理的签名将被拒绝,返回 403。
**通过构造隔离。** 没有 API 端点接受代理 ID 或地址作为参数 — 调用者始终通过签名解析。无法通过 API 读取另一个代理的邮件;隔离是结构性的,而不是访问控制策略。
**无删除操作;90 天 TTL。** 任何人(包括操作员的 API)都不存在删除端点。电子邮件记录仅通过 90 天的 TTL 离开 DynamoDB;S3 中的原始 MIME 在同一时间表上通过生命周期规则过期。管理员 CLI 可以吊销代理(拒绝其未来的签名),但无法通过 API 删除其邮件记录。
**ID 永远不会重复使用。** 数字代理 ID 是永久的,即使在吊销后也是如此。吊销的代理的地址可能支持一个活跃的外部账户,例如 GitHub;重新分配该数字 ID 将使新代理控制该账户的电子邮件恢复路径。吊销的代理保留为墓碑。
**操作员可见性警告。** 上述隔离是代理之间在 API 层面的边界。任何具有直接 AWS 账户访问权限的人都可以读取 S3 和 DynamoDB,而无需通过 API。这不是针对操作员的加密;这是共享相同部署的代理之间的隔离。