For agents

Node SDK

@graypass/node requests canonical decisions, manages supported subject and action operations, verifies proofs, and supplies Express and webhook helpers. It runs on your backend with a secret credential. The documented version is 1.0.0. Download the Node SDK archive, verify it with the installation instructions, and install the prebuilt package:

Shell
npm install --ignore-scripts ./graypass-node-1.0.0.tgz

The runnable example targets Node.js 22.17 or later in the Node 22 line.

Client configuration

TypeScript
import { GrayPassClient } from '@graypass/node';

const graypass = new GrayPassClient({
  apiKey: process.env.GRAYPASS_SECRET_KEY!,
  endpoint: 'https://app.graypass.org',
  keysUrl: 'https://app.graypass.org',
  issuer: 'https://app.graypass.org',
  timeoutMs: 5000,
});

Set the required apiKey to your secret server or admin credential. The default API endpoint is https://api.graypass.org; the hosted app origin also serves the canonical API. keysUrl is the configured trusted base origin used to retrieve published proof keys. issuer defaults to the hosted issuer shown above.

You may independently configure tenantId, environmentId, and a replayStore. When either identity binding is absent, verification obtains it through credential(). That response is cached for the client lifetime. Public key retrieval is cached separately, with a refresh on an unknown key ID. Keep endpoint, key origin, and issuer consistent with the service configuration supplied for your environment.

Supported methods

Method Purpose
credential() Inspect tenant, environment, scope, key mode, and reported proof issuer
createSubject(input) Create or retrieve a scoped subject from a stable external reference
createClientToken(subject, { origin, ttlSeconds }) Mint a short-lived browser token for a registered origin
completeEnrollment(subject, session) Complete enrollment after the server reports readiness
createPasskeyRegistrationGrant(subject) Issue a one-time grant after your authenticated account checks
revokePasskey(subject, passkeyId) Remove a registered subject passkey
revokeSubject(subject) Revoke the subject's existing operational reliance
deleteSubject(subject) Delete supported subject operational records
exportSubject(subject) Return the bounded export described in the subject guide
registerAction(input) Register an action using admin scope; starts in shadow mode
updateAction(id, input) Update display fields or request a mode change; handle a refused transition without changing the execution path
authorize(input) Request a decision and verify the returned request hash against local input
getAuthorization(id) Retrieve an authorization trace and nested proof information
reportOutcome(id, outcome, note?) Record one immutable customer-reported outcome
jwks() Obtain the published proof key set
verify(proof, expectations) Check signature and expected claims locally using available or fetched keys
verifyOnline(proof, expectations) Check server state and optionally consume; consumption defaults to true
actionHash(input) Recompute the canonical action binding

Use direct HTTP for operations without a convenience method, including policy activation, assessment retrieval, review, recovery, and evaluation management. See API reference.

Configure modes using Actions and policies. If the service refuses a mode transition, the action retains its previous mode. After an ambiguous timeout, retrieve the action's current state before retrying.

Authorization inputs and results

authorize() accepts subject, action, resource, audience, optional context, session, human actor, nonce, idempotencyKey, and requestedAt. The backend supplies authenticated identity and validated resource ownership. Context must obey the registered schema and canonical integer-safe request rules.

Supply a stable idempotency key for one logical request. If you supply that key but omit a nonce, the SDK derives a stable nonce for retries. Without a key, it generates a new request identity. Persist the original business material, nonce, and idempotency key. A transport retry may refresh requestedAt within the API freshness window while retaining that saved binding; it remains the same logical operation. See request conventions.

The result contains decision, mode, assurance, reason codes, challenge, compact proof when applicable, trace information, and verification.nonce and verification.actionHash. The latter is computed locally from the submitted request. getAuthorization() returns a different trace shape: access its compact proof as trace.proof?.compact.

Express integration

protect() and clientTokenRoute() are exported by the package and the Express entry point. clientTokenRoute() must be mounted behind your application's authentication and use a server-resolved subject and registered origin. Your application authenticates the customer before calling the handler.

protect() takes the client, action key, audience, and callbacks for subject, resource, optional context, and optional idempotency key. For an enforce-mode allow, it verifies the locally bound proof and consumes it online before calling the next handler. Test and shadow modes return a non-executing response. Challenge, hold, denial, missing proof, failed verification, and unavailable dependencies do not call the protected handler.

Default responses are challenge 401, hold 202, deny 403, and unavailability 503. onUnavailable: 'hold' returns 202 while preserving non-execution. Use custom response callbacks to present the result; execute the protected mutation only through the verified handler. For asynchronous resumption, connect the middleware to your durable pending-request and challenge-resume ledger using the integration guide.

Verification and webhooks

@graypass/node/verify exports verifyProof, fetchJwks, actionHash, and MemoryReplayStore, plus the relevant types. Supply explicit expected issuer, tenant, environment, audience, action, and action hash when calling the standalone verifier. Use a shared replay strategy across a fleet and complete online consumption before execution.

parseWebhook(rawBody, signatureHeader, secret, v2Headers) verifies the exact raw bytes and parses the event. Require the V2 signature, timestamp, and delivery ID before calling it. See the complete webhook handler, including canonical event deduplication and rotation.

Errors and retries

HTTP failures raise GrayPassApiError with status and code; malformed or non-JSON error responses are also surfaced as errors. The client applies its configured timeout. Your application owns retry and business transaction policy. Catch failures, preserve non-execution, and retry only according to the operation's idempotency semantics.

Report an executed outcome after your application confirms execution. Retry a failed outcome report through your own outbox rather than repeating the consequential operation.

For direct actionHash calls, explicitly supply actorType: 'human'. The direct helper requires this value at runtime. GrayPassClient.authorize() supplies it automatically for human actions.