Node SDK
Start with the account-backed connection check. The download includes the compiled Node ESM SDK, type declarations and a runnable diagnostic. It requires Node.js 24+ but no registry access or dependency install.
Download and run
Download Node starter · Download SHA-256 manifest
Extract the archive, open passport-node-starter, and copy the non-secret
environment settings from Dashboard → Set up. Set the key-file path and run:
export PASSPORT_PRIVATE_KEY_FILE='/absolute/path/agent.private.pem'
npm run check
The other required variables are PASSPORT_URL, PASSPORT_ORGANIZATION_ID,
PASSPORT_AGENT_ID, and PASSPORT_PROJECT_ID. Setup fills them in. The URL
must be the configured issuer origin, not an arbitrary preview alias. Local
development must configure discovery and setup for the same local origin.
For secret-managed runtimes, the starter also accepts
PASSPORT_AGENT_PRIVATE_KEY (PEM or base64 PEM) when no file path is supplied.
Never put that secret in a prompt, committed configuration, or pasted commands.
The check signs exactly this request:
{
action: "tool",
parameters: {
server: "passport-onboarding",
tool: "connection_check",
arguments: {},
amount: 1
},
source: "local-dev"
}
The starter requires a denied / POLICY_DENIED response with a correctly
bound signed receipt. It fetches the configured issuer's discovery without
following redirects, checks its origin and decision-signing key, and verifies
the receipt against the complete request. An allowed or pending response is
an error here, not success. No execution request is sent.
Use the SDK in your application
The package is not published to npm. From your own application's directory, install the extracted local package:
npm install /absolute/path/passport-node-starter/packages/sdk
Then construct a client in the trusted runtime, not in browser or model code:
import { readFile } from "node:fs/promises";
import { PassportClient } from "@passport-ai/sdk";
function required(name) {
const value = process.env[name];
if (!value) throw new Error(`${name} is required`);
return value;
}
const passport = PassportClient.connect({
baseUrl: required("PASSPORT_URL"),
organizationId: required("PASSPORT_ORGANIZATION_ID"),
agentId: required("PASSPORT_AGENT_ID"),
projectId: required("PASSPORT_PROJECT_ID"),
privateKey: await readFile(required("PASSPORT_PRIVATE_KEY_FILE"), "utf8"),
source: "server",
});
For a KMS/HSM, use new PassportClient({ ...options, signer }) with a custom
Signer that signs canonical bytes. The runtime must validate proposed
actions before signing; possession of a key alone is not proof of safe code.
Authorization is not execution
passport.authorize({ action, parameters }) signs and submits a request.
Its result uses status and reasonCode, not a boolean:
denied: stop. A receipt is evidence of denial, never execution permission.pending: wait for a human throughwaitForDecision(result). Timeout or network failure must stop the action.allowed: the action still needs the appropriate guarded executor.
Protocol/authentication errors throw PassportError; recorded denials resolve
normally. Keep authorizationToken secret. It is a scoped bearer token for
status and execution, not a model-facing explanation.
For configured Vercel and HTTP integrations, execute(result) invokes Passport's
relay and its live checks. For custom tools or payments, implement a trusted
enforcement point with fresh permission checks and replay protection; do not
execute merely because verifyReceipt returns true.
The SDK exports receipt and credential signature helpers. They do not infer a trusted issuer or prove live revocation status. Pin the intended issuer, bind all expected request details, and consult verification. The starter implements stronger, diagnostic-specific checks on top of these helpers.
Requests default to five minutes of validity; the protocol maximum is fifteen. Approval and execution windows are separate.
When the check fails
Check the issuer URL, IDs, key file and diagnostic configuration. A lost or rotated key requires the current private key. A missing receipt, unexpected decision, issuer mismatch or invalid signature must be investigated, not ignored. Recheck the setup panel and prepare a new isolated check if the old grant or deny policy has changed. Do not convert that deny policy into an allow.