智能体需要独立凭据,方便你在不替换个人登录方式的情况下,轮换或撤销它的访问能力。Sudomimus 的同一个智能体(Agent)身份可以使用访问密钥(AccessKey)或 Ed25519 公钥登录。选择哪种方式,取决于运行环境如何保管秘密和签名请求。
智能体归你的账户所有,不是另一个用户账户。会读取上下文、选择工具或决定下一步的软件适合使用智能体;定时备份等固定流程适合使用自动化(Automation)。两类身份都支持这两种凭据。产品概览见智能体与自动化。
1. 选择运行环境能够保护的凭据
| 问题 | 访问密钥 | Ed25519 公钥 |
|---|---|---|
| 运行环境保存什么? | 凭据标识符和长期秘密值。 | 凭据标识符和私钥。 |
| 登录时向 Sudomimus 提交什么? | 通过 HTTPS 提交标识符和秘密值。 | 短期有效的签名断言,私钥保留在你自己的系统中。 |
| 能向哪些应用认证? | 创建时选择的一个应用。 | 注册时确定的应用和扇区范围,之后不能直接修改。 |
| 运行环境需要实现什么? | 从受保护环境通过 HTTPS 交换凭据。 | Ed25519 签名、每次更新的防重放标识符,以及精确请求体的哈希。 |
| 如何轮换? | 创建替代凭据,切换运行环境,再撤销旧凭据。 | 注册替代公钥,切换签名密钥,再撤销旧公钥。 |
如果受保护的运行环境已有秘密存储,且你希望尽快接入,可以选择访问密钥。如果已有可靠的私钥存储和签名能力,可以选择公钥登录。私钥仍需妥善保护;公钥登录不能消除运行环境被入侵后的风险。
公钥断言只认证会话签发请求。取得的访问令牌仍是持有者令牌,持有者即可使用。Ed25519 登录不会自动增加 DPoP、mTLS,也不会为每个应用资源请求附加签名。
如果是用户主动启动 CLI,并且能够在浏览器确认登录,可优先考虑设备授权,避免保存长期凭据。
2. 创建智能体,允许准确的凭据类型
在 With 门户打开「程序化访问 → 智能体」,按任务和环境创建独立身份。创建访问密钥或注册公钥时,选择这个智能体。为账户创建的凭据仍属于账户,不能重新分配给智能体。
目标应用需要允许准确的认证方式:
| 主体 | 访问密钥方式 | 公钥方式 |
|---|---|---|
| 智能体 | AGENT_ACCESS_KEY_DIRECT |
AGENT_PUBLIC_KEY_DIRECT |
| 自动化 | AUTOMATION_ACCESS_KEY_DIRECT |
AUTOMATION_PUBLIC_KEY_DIRECT |
允许账户访问密钥,并不会同时允许智能体访问密钥。身份准入规则还需允许其所属账户,返回规则需要允许 DIRECT_ISSUE。测试前启用应用。这三层规则都必须满足。
个人资料来自所属账户,仍受当前应用声明策略和用户授权约束。无界面的运行环境不能自行取得用户同意。创建访问密钥时,门户可以收集目标应用的共享决定。如果公钥签发因缺少授权或账户资料而受阻,应先完成返回的浏览器补充流程,再重试。
3. 将凭据范围限制在任务所需之内
一个访问密钥对应一个应用。公钥可以覆盖指定应用或扇区。扇区范围还会包含以后加入该扇区的应用。如果智能体只需要一个应用,就选择应用范围。
公钥注册后不能直接修改适用范围。需要变更时,注册替代凭据、更新运行环境,再撤销旧凭据。开发和生产环境使用不同凭据。
范围决定凭据能向哪里证明身份,不授予业务角色、数据库访问权或某项操作权限。应用校验会话后,再判断这些权限。所属账户的成对 sub 和智能体的成对 act.sub 表达不同身份;不要将智能体当作账户所有者本人,也不要信任未经校验的令牌字段。
4. 从受保护的运行环境交换凭据
创建访问密钥后,立即保存标识符和秘密值。门户之后不能重新展示秘密值。只从受保护的运行环境提交它们:
const response = await fetch( "https://native-api.sudomimus.com/direct-issue/access-key", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ applicationAnchor: process.env.SUDOMIMUS_APPLICATION_ANCHOR, accessKeyIdentifier: process.env.SUDOMIMUS_ACCESS_KEY_ID, accessKeySecret: process.env.SUDOMIMUS_ACCESS_KEY_SECRET, }), },);if (!response.ok) { throw new Error(`Agent sign-in failed (${response.status})`);}const { accessToken, refreshToken } = await response.json();使用公钥登录时,可以在门户或自己的系统中生成 Ed25519 密钥对,只注册公钥。在已安装 OpenSSL 的 macOS 或 Linux 上,可执行以下命令:
umask 077openssl genpkey -algorithm Ed25519 -out agent.private.pemopenssl pkey -in agent.private.pem -pubout -out agent.public.pem将 agent.public.pem 粘贴到门户,并选择智能体及其范围。门户会将公钥 PEM 转换为服务接受的公钥 JWK。不要粘贴私钥 PEM。在运行环境中配置保存后取得的公钥凭据标识符,以及私钥文件路径。
下面的 Node.js 示例对即将发送的精确请求体计算哈希,并为这次请求生成新的签名断言。该 Ed25519 凭据属于智能体,与应用的 Connect 客户端认证签名密钥相互独立。
import { createHash, createPrivateKey, randomBytes, sign } from "node:crypto";import { readFileSync } from "node:fs";
function requiredEnvironment(name: string): string { const value = process.env[name]; if (!value) { throw new Error(`Missing runtime environment variable: ${name}`); } return value;}
const credentialIdentifier = requiredEnvironment("SUDOMIMUS_PUBLIC_KEY_ID");const privateKey = createPrivateKey(readFileSync( requiredEnvironment("SUDOMIMUS_PRIVATE_KEY_FILE"),));const body = JSON.stringify({ applicationAnchor: requiredEnvironment("SUDOMIMUS_APPLICATION_ANCHOR"),});const now = Math.floor(Date.now() / 1000);const encode = (value: object) => Buffer.from(JSON.stringify(value)).toString("base64url");const header = encode({ alg: "EdDSA", typ: "vnd.sudomimus.public-key-assertion+jwt", kid: credentialIdentifier,});const payload = encode({ iss: credentialIdentifier, aud: "sudomimus-native-public-key", iat: now, exp: now + 60, jti: randomBytes(16).toString("base64url"), requestHash: createHash("sha256").update(body).digest("base64url"),});const signingInput = `${header}.${payload}`;const signature = sign(null, Buffer.from(signingInput), privateKey).toString("base64url");const response = await fetch( "https://native-api.sudomimus.com/direct-issue/public-key", { method: "POST", headers: { "Content-Type": "application/json", Authorization: `SudomimusPublicKeyJWT ${signingInput}.${signature}`, }, body, },);if (!response.ok) { throw new Error(`Agent sign-in failed (${response.status})`);}const { accessToken, refreshToken } = await response.json();每次重试都应生成带有新 jti 的断言,不要重发已使用的断言。保持运行环境时钟同步。按令牌校验指南校验返回令牌,将凭据保留在服务端,再通过 Session API 刷新和退出。两个示例都不会记录秘密值或令牌。
5. 分别测试轮换和撤销
测试范围内的应用、范围外的应用,以及已暂停的智能体。公钥方式还应测试修改请求体和重放断言,这两种请求都应被拒绝。
常规轮换时,先创建并测试替代凭据,再撤销旧凭据。可能泄露的凭据应立即撤销。暂停或撤销智能体会使旧会话的认证权限失效;恢复智能体不会让旧会话重新有效。只使用离线 JWT 校验的应用无法立即观察到撤销;需要确认当前会话仍有效的操作,应调用 Session 的在线检查端点。
接入步骤见访问密钥管理或公钥注册。如果是固定后台任务,参考定时任务身份指南。