
Company News
Free Business Plan Upgrades for Open Source Maintainers
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.
@opena2a/a2a-idf
Advanced tools
Reference TypeScript SDK for A2A-IDF (Agent-to-Agent Identity Framework) — sign/verify RFC 9421, resolve keyids, validate verification levels 0/1/2, attestations, and delegation chains.
Reference TypeScript SDK for A2A-IDF — the Agent-to-Agent Identity Framework specified in a2aproject/A2A#1496.
opena2a-org/a2a-idf-conformanceVerifier-side first. Given a signed A2A request (RFC 9421 over Ed25519), this SDK answers four questions:
created, seen nonce)?Signer-side is supported via a minimal sign() for clients that need to produce request signatures or build test fixtures.
npm install @opena2a/a2a-idf
Runtime dependencies are exactly two: @noble/ed25519 and @noble/hashes. No transitive cryptography deps; nothing pulls in OpenSSL FFI or node-forge.
import {
sign,
verify,
resolveKeyid,
ReplayCache,
} from "@opena2a/a2a-idf";
// 1. Sign an outbound request.
const signed = sign({
method: "POST",
path: "/api/task",
body: new TextEncoder().encode(JSON.stringify({ task: "summarize" })),
params: {
keyid: "https://acme.example/keys/agent-1",
created: Math.floor(Date.now() / 1000),
nonce: crypto.randomUUID().replace(/-/g, ""),
},
privateKey, // 32-byte Ed25519 seed
});
// 2. Verify an inbound request.
const { publicKey } = await resolveKeyid(
"https://acme.example/keys/agent-1",
);
const replay = new ReplayCache();
const result = verify({
method: "POST",
path: "/api/task",
body: requestBody,
headers: {
"content-digest": headers["content-digest"],
"signature-input": headers["signature-input"],
signature: headers["signature"],
},
publicKey,
checkNonce: replay.check.bind(replay),
});
if (!result.ok) {
// result.reason is one of:
// missing-headers, malformed-signature-input, malformed-signature,
// unsupported-component, content-digest-mismatch, content-digest-missing,
// content-digest-unsupported-algorithm,
// timestamp-too-old, timestamp-future-skew,
// replay-detected, signature-invalid
}
This SDK byte-matches the Envoys §13 test vectors (spec v1.4.0, sha256 5dcc855e…c21b2e9):
| Vector | Method | Path | Body | Status |
|---|---|---|---|---|
| 1 | GET | /api/health | empty | ✓ matches XUpjUHt36NbHgAZrQkFY2fSNUR19tgmRlGO1dBhaZDgBv4wb55qgJf2buv3wgnTYwtT+1sH2jzSbcgG6FLGKCA== |
| 2 | POST | /api/task | summarize JSON | ✓ matches i5tKcOHKhRTCztR2cazuzNAg9rPiRf47MKTOGve92Rs43gNmltuN5LVScedR6C08MGsQykMc7txJ21KCG8SEBQ== |
| 3 | POST | /api/echo | {} | ✓ matches m2besJKk6Q0MIwFoTENobvvHxFan1fUTv7bzY4EB6OjfIlktqwKa7r/Ab0tDDWFGjQ0CbALgvWGcQfzDr/GeBQ== |
See test/rfc9421.test.ts. The keypair is RFC 8032 §7.1 Test 1, fixed for reproducibility across implementations.
import { level1, level2 } from "@opena2a/a2a-idf";
// Level 1 — domain-verified
const l1 = await level1({
signatureVerified: result.ok,
domain: "acme.example",
expectedToken: "https://acme.example/keys/agent-1",
dns: yourDnsResolver, // implements resolveTxt(name) → { records, ttlSeconds }
});
// l1.warnings includes "dns-ttl-above-cap:<n>s > 300s" when the
// `_a2a-identity` record TTL exceeds the cap.
// Level 2 — organization-verified (Level 1 + trusted attestations)
const l2 = await level2({
...l1Inputs,
attestationArray: agentCard.attestations,
attestationOpts: {
resolveIssuerKey: async (issuerKeyid) =>
(await resolveKeyid(issuerKeyid)).publicKey,
},
trustedIssuers: new Set(["https://attestor.example/keys/issuer-1"]),
});
import { verifyDelegationChain } from "@opena2a/a2a-idf";
const r = await verifyDelegationChain(agentCard.delegationChain, {
resolveKey: async (keyid) => (await resolveKeyid(keyid)).publicKey,
nowSeconds: Math.floor(Date.now() / 1000),
maxDepth: 4,
});
if (r.ok) {
console.log("effective scope:", r.effectiveScope);
}
Chain rules enforced: first link is a root (signed by the originating delegator); each subsequent link carries the previous link's previousSignature; scope narrows monotonically; expiry never widens; depth ≤ maxDepth; signing keys resolve through the same resolveKey callback.
resolveKeyid() dispatches on Content-Type:
application/did+json → W3C DID Document with an Ed25519 verification method (publicKeyMultibase or publicKeyJwk with crv: "Ed25519").{ address, public_key: <PEM SPKI> }.Both shapes return the same 32-byte raw Ed25519 key, so callers can pass it directly to verify({ publicKey }).
@opena2a/secretless).These are scoped for v0.2 and onward — see A2A_IDF_CAMPAIGN.md for the trajectory.
v0.1 — MVP. Not yet published to npm. All acceptance criteria from the A2A-IDF SDK pickup doc are met locally; npm publication follows the canonical-suite composition fixture (fixtures/composition/aim-did-rfc9421/signature-alone.json) landing in opena2a-org/a2a-idf-conformance and an opena2a.org/identity page going live.
The conformance suite (opena2a-org/a2a-idf-conformance) is the canonical home for cross-implementation byte-match fixtures. SDK PRs that don't pair with a fixture update are still welcome, but cross-impl behavior changes belong in the suite first.
FAQs
Reference TypeScript SDK for A2A-IDF (Agent-to-Agent Identity Framework) — sign/verify RFC 9421, resolve keyids, validate verification levels 0/1/2, attestations, and delegation chains.
We found that @opena2a/a2a-idf demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Open source maintainers are under more pressure than ever. We're raising our open source program from the Team plan to the Business plan, free.

Security News
The supply chain control that delays freshly published gems now covers lockfile generation and gem vendoring in Ruby projects.

Security News
During a UK cyber test, a Mythos 5 agent used sockpuppets, social engineering, and prompt injection to try to get a maintainer to merge malware.