Skip to content

TypeScript SDK

If your Node.js application calls a TrustPlane-protected API, the TypeScript caller SDK for TrustPlane Auth builds and signs the proof-bound request material for you before the call goes out, and can enroll the workload with Control. It is a Node.js-only package, available at version 0.2.2:

Terminal window
npm install @trustplane/auth-sdk@0.2.2

Releases are published to npm with provenance, and the latest tag resolves to 0.2.2.

At 0.2.2, the TypeScript SDK supports:

  • generating, importing, and exporting CLI-compatible Ed25519 software keys;
  • issuing the short-lived passport-v0.1 shape used by the current CLI;
  • exact transcript-v1 request signing, including the body SHA-256 value used in TrustPlane request headers;
  • strict parsing and enforcement of active Control key-grant signing profiles;
  • signed requests for every HTTP method, including custom methods;
  • TA-G1 public auto-enrollment (challenge, server-bound proof, key proof-of-possession, submission, retry, secret-capability polling, and runtime activation);
  • compact JWT, AWS IID, and Azure IMDS enrollment proof values; and
  • broker IPC v1 request building, Unix-socket calls, and adapter-ready headers.

The package is Node.js-only because it uses node:crypto and Unix sockets. Browser and edge runtimes are not currently supported.

The package does not include a verifier, adapter, policy engine, broker runtime, SPIFFE issuer, deployment logic, Control administrative API, or CLI-only bundle/local-demo commands. Keep verification, policy, and deployment decisions in the TrustPlane Auth runtime path that owns them.

Raw local signing is software-only. Stronger signer classes must be fulfilled by an appropriate broker or signer; they are never simulated with an exportable key.

Control returns a safe signing profile for a specific active key grant. Parse that JSON with parseSigningProfile, load the corresponding local key, and let ProtectedClient issue a fresh passport and sign each request:

import {
ProtectedClient,
ed25519PrivateKeyFromBase64URL,
parseSigningProfile
} from "@trustplane/auth-sdk";
const profile = parseSigningProfile(controlSigningProfileJSON);
const privateKey = ed25519PrivateKeyFromBase64URL(privateKeyFileContents.trim());
const client = new ProtectedClient({ profile, privateKey });
const response = await client.request(
profile.method,
"/orders/123?expand=items",
undefined,
{ Accept: "application/json" }
);

Each request receives a fresh short-lived passport/JTI, nonce, canonical body/query/header digest, and proof. The client rejects a method or path outside the active profile, including sibling-prefix mistakes. Parameterized profiles require a concrete path (/orders/123, not /orders/{id}); encoded or ambiguous paths fail closed, query-only targets retain a literal profile path, and redirects are not followed with TrustPlane credentials.

Use buildRequest when you want the canonical transcript material and body hash before signing or before comparing against conformance vectors. Passport-bound fields such as passportJTI, issuedAtUnix, and keyBinding must come from the real passport you are preparing to use.

import {
SoftwareKeyBinding,
bodySHA256,
buildRequest,
type RequestInput
} from "@trustplane/auth-sdk";
const body = `{"order_id":"ord_123","amount":"42.00"}`;
const request: RequestInput = {
method: "POST",
scheme: "https",
authority: "orders.example",
path: "/v1/orders",
rawQuery: "region=us&priority=standard",
audience: "orders-api",
routeId: "orders.create",
contentEncoding: "identity",
body,
headers: [
{ name: "Content-Type", value: "application/json" },
{ name: "X-TrustPlane-Nonce", value: "nonce-v1-001" }
],
headerAllowList: ["content-type", "x-trustplane-nonce"],
nonce: "nonce-v1-001",
passportJTI: "passport-jti-from-real-passport",
issuedAtUnix: 1740000000,
keyBinding: SoftwareKeyBinding
};
const material = buildRequest(request);
console.log({
bodySHA256: bodySHA256(body),
transcriptSHA256: material.transcriptSHA256
});

signRequest is Node.js-only API for raw local software signing. First obtain a real TrustPlane passport from the TrustPlane CLI or broker. The Ed25519 private key you pass must match the passport cnf.public_key_b64url value, and the passport cnf.key_binding must be software. Raw signing does not support the remote_kms, hardware_local, or attested_workload key bindings — those require a broker or signer path.

import { createPrivateKey } from "node:crypto";
import { readFile } from "node:fs/promises";
import { HeaderNonce, signRequest } from "@trustplane/auth-sdk";
const passport = process.env.TRUSTPLANE_PASSPORT;
if (!passport) {
throw new Error("TRUSTPLANE_PASSPORT must contain a real TrustPlane passport");
}
const privateKey = createPrivateKey(
await readFile(new URL("./software-ed25519-private-key.pem", import.meta.url))
);
const url = new URL("https://orders.example/v1/orders?region=us&priority=standard");
const body = `{"order_id":"ord_123","amount":"42.00"}`;
const nonce = "nonce-v1-001";
const signed = signRequest({
passportToken: passport,
privateKey,
request: {
method: "POST",
scheme: url.protocol.slice(0, -1),
authority: url.host,
path: url.pathname,
rawQuery: url.search.slice(1),
routeId: "orders.create",
contentEncoding: "identity",
body,
headers: [
{ name: "Content-Type", value: "application/json" },
{ name: HeaderNonce, value: nonce }
],
headerAllowList: ["content-type", "x-trustplane-nonce"],
nonce
}
});
const response = await fetch(url, {
method: "POST",
body,
headers: {
"Content-Type": "application/json",
...signed.headers
}
});
if (!response.ok) {
throw new Error(`request failed: ${response.status}`);
}

TA-G1 public auto-enrollment is supported through EnrollmentClient. The Enrollment Policy reference is opaque: Control — not the SDK caller — selects the exact source, revision, proof mode, client, Auth Site, and runtime target.

import { EnrollmentClient, jwtEnrollmentProof } from "@trustplane/auth-sdk";
const result = await new EnrollmentClient().enroll({
controlURL: "https://control.example",
enrollmentPolicyRef: "enrpol_...",
provider: "kubernetes_service_account_oidc",
privateKey,
proofProvider: async (challenge) =>
jwtEnrollmentProof(await obtainAudienceBoundToken(challenge.expected_audience ?? ""))
});

The SDK validates Control’s immutable source revision, Azure proof mode when applicable, and required encoding before invoking the proof callback. Helpers also build AWS IID and Azure IMDS attested-document proof values. The safe result never contains proof, key, nonce, signature, or poll capability material. Enrollment requires HTTPS.

Provider credential acquisition stays in the application callback so it can use the host’s projected token, CI, SPIFFE, or cloud metadata client. The SDK owns the complete Control protocol. Once a submission is accepted, a polling deadline returns a safe pending result with the request ID instead of resubmitting the proof.

buildBrokerRequest, BrokerClient.issue, and brokerHeaders provide the caller side of broker IPC v1 over a Unix socket when key custody and signer selection belong to a local TrustPlane broker. The package does not include a broker runtime.

Pin the exact package version 0.2.2 and use the shared conformance vectors to check transcript and signing behavior. The Python SDK is also released.