Node SDK — feature guide
Node.js SDK for the AITP reference implementation
This page is a feature-by-feature pointer into bindings/aitp-node.
Each section names the RFC, the Cargo feature flag (if any), and a
~5-line example. Full TypeScript signatures live in the auto-generated
bindings/aitp-node/index.d.ts.
The Python SDK has a symmetric surface; see sdk-python.md.
Build
npm run build:debug # default surface
npm run build:experimental:debug # adds post-v0.1 features
# Release variants:
npm run build
npm run build:experimentalDefault surface (v0.1)
Mutual handshake (RFC-AITP-0004)
import { AitpAgent } from 'aitp';
const alice = AitpAgent.generate();
const bob = AitpAgent.generate();
const bobManifest = bob.buildManifest({
displayName: 'bob',
handshakeEndpoint: 'https://bob.example/aitp/handshake/',
offeredCaps: ['demo.echo'],
});
alice.buildManifest({
displayName: 'alice',
handshakeEndpoint: 'https://alice.example/aitp/handshake/',
offeredCaps: ['demo.write'],
});
const s = alice.newSession(), r = bob.newResponder();
const hello = s.buildHello(bobManifest, ['demo.echo']);
const { ackJson, sessionId } = r.processHello(hello);
const commit = s.processHelloAck(ackJson, sessionId);
const { ackJson: cack } = r.processCommit(commit);
const aliceHeld = s.complete(cack);TCT verification (RFC-AITP-0005 §9)
// Holder-receipt model (default).
const ident = agent.verifyTct(tctJson, 'demo.echo');
// Presented-TCT model — for a resource server checking a TCT a peer
// presented in `X-AITP-TCT`. Pass the TCT's own subject AID.
const presented = agent.verifyTct(tctJson, 'demo.echo', peerAid);Delegation (RFC-AITP-0006)
import { verifyDelegation } from 'aitp';
const env = b.buildDelegation(tctBHoldsFromA, c.aid, cPubkey, ['demo.write']);
const verified = verifyDelegation(env, a.aid);
const freshTctForC = a.issueTctForDelegatee(verified);Manifest verification
import { verifyManifestJson } from 'aitp';
verifyManifestJson(manifestEnvelopeJson); // throws on failureRevocation-list signing
const envelope = issuer.signRevocationList(
[{ jti: 'uuid-here', reason: 'compromised' }],
600,
);OIDC identity (RFC-AITP-0002)
import { JwksProvider } from 'aitp';
const jwks = new JwksProvider({ 'https://idp.example/': [myJwk] });
agent.buildManifest({
...,
identityType: 'oidc',
oidcIssuer: 'https://idp.example/',
oidcSubject: 'alice',
});
const sess = agent.newSession(jwks);
const hello = sess.buildHello(peerManifest, grants, (nonce) =>
myIdp.mintJwtSync({ nonce, sub: 'alice', aud: peerAid }),
);The oidcMintJwt callback is synchronous — it runs on the libuv main
thread inside the buildHello / processHello call. Do not pass an async
function.
P-256 signing suite (RFC-AITP-0001 §5.4.3)
const agent = AitpAgent.generateP256(); // aid:pubkey:p256:<44>
const det = AitpAgent.fromP256Seed(seedBuf);P-256 produces p256.<86-char-b64url> signatures; an algorithm-agile
verifier on the other side accepts them. Caveat: the v0.1 manifest's
pinned_key identity_hint embeds an Ed25519 public key only, so P-256
agents must use identityType: 'oidc'.
Experimental surface (Cargo --features experimental)
TCT renewal (RFC-AITP-0013 / RFC-AITP-0004 §8.1, feature experimental-renewal)
const req = holder.buildRenewalRequest(currentTctEnvelopeJson);
const fresh = issuer.processRenewalRequest(req, manifestExpUnixSecs, newTtlSecs);Session Trust Bundle (RFC-AITP-0010, feature experimental-bundle)
import { SessionBundleBuilder, verifySessionBundle } from 'aitp';
const envelope = new SessionBundleBuilder(coordinator)
.participant(alice.aid, aliceTct)
.participant(bob.aid, bobTct)
.build();
const outcome = verifySessionBundle(envelope, alice.aid);
// { kind: 'clear' | 'degraded', activeAids: [...], droppedAids: [...] }SPKI cert pinning (HPKP-style, feature experimental-pinning)
import { computeSpkiHash, SpkiPinVerifier } from 'aitp';
const pin = computeSpkiHash(certDerBuffer); // 32-byte Buffer
const verifier = new SpkiPinVerifier([pin]);
verifier.isPinned(otherCertDer); // true / falseWire verifier.isPinned() into your HTTP client's checkServerIdentity
hook (e.g. undici.Agent({ connect: { ... } })). The SDK does no HTTP.
Tests + interop
npm install
npm run build:experimental:debug
npm test # 25 binding tests (node --test)
cd ../interop && pytest -v # 12 cross-language interop tests (1 deliberately skipped)