aitp——节点.js SDK
节点.js 绑定 代理身份和信托协议(AITP),在
纯净的 aitp-rs
协议箱通过 国家反贪局。 。 。 .
一个瘦的SDK: 一个 AitpAgent 加上发起/响应会话对象。 他们
方法取回 JSON 字符串( HTTP 请求/响应机构) 和
紧凑-JWS字符串(TCT、赠款凭单、代表团代号)。 代理代码
从未处理过 FFI 边界的 Rust 类型 。 API 是骆驼Case
python SDK 的对应设备(buildManifest ↔ build_manifest;两个
不同的返回形状,列于
Python 对节点差异。 。 。 .
以每个能力为例的特写指南是
docs/sdk-node.md。 。 。 .
安装
npm install @agentidentitytrustprotocol/aitp
为macOS (x64, arm64)和Linux GNU (x64, )所建造的本地二进制船, (第64条).
从源头构建
这个箱子是 没有 页:1 aitp-rs 货物工作空间。 用它来建造
页:1 NAPI - rs CLI (英语) 和一股起落架:
npm install
npm run build:debug # default `.node`, as published
npm run build:experimental # adds the experimental features
npm run build:minimal:debug # without SPKI pinning
# Release:
npm run build
npm run build:minimal # --no-default-features
该建筑产生平台 .node 二进制和再生 index.js
财务报告和审定财务报表 index.d.ts,覆盖默认表面. build:experimental
写入 experimental.js 财务报告和审定财务报表 experimental.d.ts 相反,添加
实验性API,不在已发布的包中.
货物特性
发表 .node 默认构建 :
- 握手、TCT、授权、明确核查和OIDC身份
- 撤销列表签名和核查
- 信封签名和验证
- SPKI 披针( 地平面)
spki-pinning,默认情况下)
实验性功能默认关闭 而不在公布的
软件包。 源构建可以让他们一个接一个,或者全部使用 experimental
(单位:千美元)npm run build:experimental) (中文(简体) ). 它们没有稳定的承诺.
| 特性 | 启用 | RFC (RFC ) (法语) |
|---|---|---|
spki-pinning (默认) | computeSpkiHash, (中文(简体) ), SpkiPinVerifier | HPKP (RFC 7469) (中文(简体) ) |
experimental-renewal | AitpAgent.buildRenewalRequest 编号 : processRenewalRequest | RFC-AITP-0013(草案) |
experimental-session-bundle | SessionBundleBuilder, (中文(简体) ), verifySessionBundle | RFC-AITP-0010(草案) |
experimental-multihop-delegation | verifyDelegationMultihop | RFC-AITP-0011(草案) |
experimental-a2a-agent-card | a2aCardManifestUrl, (中文(简体) ), verifyA2aAgentCardBinding | RFC-AITP-0014(草案) |
使用量
import { AitpAgent } from '@agentidentitytrustprotocol/aitp';
const initiator = AitpAgent.generate();
const responder = AitpAgent.generate();
initiator.buildManifest({
displayName: 'initiator',
handshakeEndpoint: 'https://localhost:8100/aitp/handshake/',
offeredCaps: ['demo.echo'],
});
const respManifest = responder.buildManifest({
displayName: 'responder',
handshakeEndpoint: 'https://localhost:8200/aitp/handshake/',
offeredCaps: ['demo.write'],
});
// Each side trusts the other's pinned key by AID. Without `pinnedKeys`
// every pinned_key peer is rejected (fail closed).
const sess = initiator.newSession(null, { pinnedKeys: [responder.aid] });
const rsess = responder.newResponder(null, { pinnedKeys: [initiator.aid] });
// Four-message mutual handshake — each call's output is the next peer's input.
const hello = sess.buildHello(respManifest, ['demo.write']);
const { ackJson: helloAck, sessionId } = rsess.processHello(hello);
const commit = sess.processHelloAck(helloAck, sessionId);
const { ackJson: commitAck } = rsess.processCommit(commit, []);
const completed = sess.complete(commitAck, []);
// completed = { tct, claims, grantVoucher? }
// `tct` is an opaque compact-JWS string; `claims` is the decoded TCT.
// Each peer now holds a TCT the other issued it.
const ident = initiator.verifyTct(completed.tct, 'demo.write', undefined, []);
console.log(ident.peerAid, ident.grants);
// `completed.grantVoucher` (when present) is what you pass to
// `buildDelegation(grantVoucher, delegateeAid, scope)` to delegate.
在真正的部署中,每个消息都会移动到HTTP上. buildHello 返回时
机构为 POST /aitp/handshake/hello。 。 。 . processHello 返回响应
体外加数值 X-Aitp-Session-Id 头等.
API 密码
生成的 index.d.ts 描述整个公共表面; 下表
总结一下。 声明、撤销名单和握手信封
边界为 JSON 字符串. 临时合同、赠款凭单和代表团不透明
紧凑- JWS 符号字符串 (单位:千美元)header.payload.signature) (中文(简体) ).
| 导出 | 特性 | 页:1 |
|---|---|---|
AitpAgent | 默认 | generate(opts?) 编号 : fromSeed(buffer, opts?) (单位:千美元)opts.suite = "ed25519" | "p256", (中文(简体) ), aid, (中文(简体) ), buildManifest(opts) (单位:千美元)opts.revocationListUri, (中文(简体) ), newSession(jwks?, opts?), (中文(简体) ), newResponder(jwks?, opts?) (单位:千美元)opts.trustAnchors, (中文(简体) ), opts.pinnedKeys, (中文(简体) ), opts.insecureLocalhostDangerous, (中文(简体) ), verifyTct(token, grant, expectedAudience?, revokedJtis?, revocation?, pop?), (中文(简体) ), verifyTctCached(token, grant, store, expectedAudience?, revokedJtis?, revocation?, pop?) (单位:千美元)pop = { challenge, response }, 演示- TCT 路径), newPopChallenge(tctToken, ttlSecs?), (中文(简体) ), signPopResponse(challengeJson), (中文(简体) ), buildDelegation(voucherToken, delegateeAid, scope, ttlSecs?), (中文(简体) ), issueTctForDelegatee(verified, ttlSecs?) → { tct, grantVoucher? }, (中文(简体) ), signEnvelope(messageType, payloadJson, opts?) (单位:千美元)opts.extensionsJson, (中文(简体) ), opts.messageId, (中文(简体) ), opts.timestamp, (中文(简体) ), signRevocationList(entries, expiresInSecs?) |
JsInitiatorSession | 默认 | 归来 newSession。 。 。 . buildHello(peerManifest, grants, oidcMintJwt?), (中文(简体) ), processHelloAck(...), (中文(简体) ), complete(...) → { tct, claims, grantVoucher? } |
JsResponderSession | 默认 | 归来 newResponder。 。 。 . processHello(hello, oidcMintJwt?) → { ackJson, sessionId }, (中文(简体) ), processCommit(commit) → { ackJson, completed: { tct, claims, grantVoucher? } } |
TctStore | 默认 | 缓存 AitpAgent.verifyTctCached()。一个字节相同的、仍然有效的 TPT 跳过签名检查;密钥是符号字节的 SHA-256 |
JwksProvider | 默认 | OIDC JWKS地图. upsert(issuer, keys), (中文(简体) ), remove(issuer), (中文(简体) ), issuers() |
verifyDelegation(token, verifierAid, issuerManifests, revokedJtis?, revocation?, insecureLocalhostDangerous?) | 默认 | RFC-AITP-0006,严格单跳;拒绝任何多跳 chain在密钥下验证发包人说明书中指定的(issuerManifests数字 : {"manifest": ...} JSON弦乐团。 回返 { delegator, delegatee, issuedBy, grants, expiresAt, cnfJkt } |
verifyManifestJson(json, nowUnixSecs?, insecureLocalhostDangerous?) | 默认 | 丢出一个 Error 与 code (例如:. signature_invalid, (中文(简体) ), expired, (中文(简体) ), unknown_field, (中文(简体) ), malformed(中文(简体) ) |
verifyEnvelope(json, expectedSenderAid) | 默认 | 验证一个 aitp/0.3 在RFC-AITP-0001§5.4检查令中,信封的签名是针对被绑住的发件人的. 丢出一个 Error 与 code (单位:千美元)UNKNOWN_VERSION, (中文(简体) ), UNKNOWN_FIELD, (中文(简体) ), INVALID_ENVELOPE, (中文(简体) ), INVALID_SIGNATURE) (中文(简体) ). 重放和时间戳检查留在呼叫者那里;见 信封签名 |
verifyRevocationList(json, expectedIssuerAid, nowUnixSecs?) | 默认 | 校正对一个被钉住的发行商的撤销快照。 丢出一个 Error 与 code |
revocationSigningBytes(json) | 默认 | 撤销快照签名封面的确切字节 |
verifyPopResponse(challengeJson, responseJson, tctToken) | 默认 | RFC-AITP-0005 第6.2节只检查(不是TCT本身);返回被证明的持有者AID. 抛出 code POP_CHALLENGE_INVALID 或者说 POP_RESPONSE_INVALID |
computeAidJkt(aid) | 默认 | RFC 7638 一个AID键的拇指印,用于OIDC JWT的 cnf.jkt |
buildRenewalRequest() 编号 : processRenewalRequest() | experimental-renewal | RFC-AITP-0013 (草案). processRenewalRequest → { tct, grantVoucher? } |
SessionBundleBuilder, (中文(简体) ), verifySessionBundle(json, verifierAid, coordinatorManifestJson, nowUnixSecs?, revocationCheck?, insecureLocalhostDangerous?) | experimental-session-bundle | RFC-AITP-0010 (英语). 以关键方式核实协调员的《声明》指定的(coordinatorManifestJson数字 : {"manifest": ...} JSON, 所需) |
computeSpkiHash(), (中文(简体) ), SpkiPinVerifier | spki-pinning | HPKP 型出界针 |
verifyDelegationMultihop(token, verifierAid, issuerManifests, maxDelegationHops?, revokedJtis?, revocation?, insecureLocalhostDangerous?) | experimental-multihop-delegation | RFC-AITP-0011 多跳选入 |
a2aCardManifestUrl(cardJson), (中文(简体) ), verifyA2aAgentCardBinding(cardJson, selectedInterfaceUrl, manifestJson?, nowUnixSecs?) | experimental-a2a-agent-card | RFC-AITP-0014 客户端验证,无 I/O. 投放 error.code。见 docs/a2a-agent-card.md |
verifyTct 返回时 { peerAid, grants, expiresAt, jti }时 peerAid 实值
发行商.
撤销
verifyTct 财务报告和审定财务报表 verifyTctCached 带一个 revokedJtis 参数,一组
已撤销的 TPT jti 字符串,以及可选的终局 revocation 参数
(单位:千美元)'fail_closed',默认值,或 'fail_open') (中文(简体) ). 一个TCT的 jti 位于
数组被拒绝, 即使其签名、 受众和到期日不是
无效 :
// not executed: fragment; see docs/sdk-node.md § TCT verification for the runnable flow
const revoked = ['11111111-2222-4333-8444-555555555555'];
agent.verifyTct(tctToken, 'demo.write', null, revoked); // throws if revoked
义务. SDK会的 没有 获取或维护已撤销的集
你吗? 供应是打电话者的责任:来源于
您获取并检查的撤销快照 verifyRevocationList
(问题1) signRevocationList) (中文(简体) ).
该套套装是先行通过的,而不是通过每套套套装所援引的联署材料
jti,这样它就可以保持声音 在凝胶线程限制.
撤销是 fail_closed (RFC-AITP-0008 第3.1节):如果省略 revokedJtis, (中文(简体) ),
每一次TCT都会被拒绝 code 'TCT_REVOKED',因为身份不明
被取消。 过 [] 当发行商的列表为空,或者
'fail_open' 只有当部署没有撤销源时.
作为发行商,发布您的名单: buildManifest({ ..., revocationListUri })
设置 rfc-aitp-0008.revocation_list_uri 在您签署的宣言中
RFC-AITP-0005§11和RFC-AITP-0008§1.4要求. 使用绝对的 HTTPS URL,
一般来说,你的出身加 REVOCATION_LIST_PATH。 。 。 .
UUID 输入
签名或发送的标识符为 严格数字 : signEnvelope是因为
opts.messageId, (中文(简体) ), SessionBundleBuilder.sessionId() 编辑 jti 各笔捐款
signRevocationList 条目必须是小写连字符的 UUID v4 有线形式
(单位:千美元)xxxxxxxx-xxxx-4xxx-[89ab]xxx-xxxxxxxxxxxx) (中文(简体) ). 大写,立正, urn:uuid:, (中文(简体) ),
无连字符和非 v4 形式抛出, 命名字段; 它们永远不会
正常了,所以你通过的东西 就是线上的东西.
A 类 revokedJtis 列表 verifyTct, (中文(简体) ), verifyTctCached, (中文(简体) ),
processRenewalRequest, (中文(简体) ), verifyDelegation 财务报告和审定财务报表 verifyDelegationMultihop(中文(简体) )
是一个 宽大 查找密钥:每个条目可能以 RFC 9562 文本形式存在,并且
匹配前已常态化, 所以 '{11111111-2222-4333-8444-555555555555}'
撤销与小写格式相同的TPT。 不是一个UUID 的条目
全部掷出( a)revoked_jtis entry is not a UUID而不是被忽视.
Python SDK的行为也一样.
伊办的身份和P-256
见
OIDC 身份标识
财务报告和审定财务报表
P-256 签名套间。 。 。 .
这个 oidcMintJwt 调用是同步的 .
在v0.2中突破变化: p-256具体工厂方法 删除后为参数
generate({ suite })编号 :fromSeed(seed, { suite })API,它符合 Python SDK 的AitpAgent.generate(suite="p256")迁移,呼叫AitpAgent.generate({ suite: 'p256' })或者说AitpAgent.fromSeed(seed, { suite: 'p256' })。 。 。 .
pinned_key 身份与Ed25519和P-256密钥配合. 关于P-256
清单 public_key 是33字节 SEC1 压缩点.
绑定的密钥( E)opts.pinnedKeys(中文(简体) )
届会接受 pinned_key 只有对等方的 AID 在
pinnedKeys 数组传递到 newSession 编号 : newResponder
(RFC-AITP-0002 第3.2节:钥匙必须放在核查员的地方信托商店,
在证据之前检查). 被允许或 [] 信任没有被钉住的密钥,所以每个
pinned_key 拒绝对等关系。 无效的 AID 投出条目 .
升级到0.14: 仅限拥有的密钥核查已不复存在. 通过对等方的AID,例如.
agent.newSession(null, { pinnedKeys: [peer.aid] }), (中文(简体) ), 握手失败IDENTITY_FAILED。 。 。 .
测试
npm install
npm run build:debug
npm test # node --test tests/*.mjs
tests/test_docs_samples.mjs 运行每个 JavaScript 块
docs/sdk-node.md
和上面的废墟.
跨语言的互通套房(Python QQ节点)住在
bindings/interop。 。 。 .
运行它 make interop 从回波根.