Skip to main content
The patterns on this page — the audit-log schema, the metric names, the rate limiter — are illustrative starting points for your own integration, not claims about what this repository’s own infrastructure runs or has test coverage for. The SDK behavior itself (the Configuration/RetryPolicy shape, the error classes, the retry semantics) is real and verified — see TypeScript SDK for what’s actually tested.

Deployment architecture

The SDK never talks to a downstream system directly — it talks only to your Parmana Runtime deployment. See Deploy patterns for running that Runtime itself in production (Fly.io/Docker, or any Node-compatible platform).

Environment variables

A production-safe client wrapper

Prefer to omit transport. From 1.1.6 the client builds its own HttpTransport from the configuration you pass, so timeout, retryPolicy, apiKey and userAgent all apply. If you supply your own transport (1.1.5 and earlier require one), build it from the same configuration object. HttpTransport reads timeout and retryPolicy from the configuration it is constructed with. If you write transport: new HttpTransport({ endpoint, apiKey }) next to a retryPolicy on the client, the transport never sees the retry policy and nothing is retried, with no error. Tested against a server that returns 503 twice: with the transport built from a partial configuration there is 1 request and an InternalServerError, and with the transport built from the full configuration there are 3 requests and success. Retries are off unless retryPolicy.enabled is true and maxAttempts is above zero. maxAttempts counts retries after the first attempt, so maxAttempts: 3 makes up to 4 requests. Only GET requests are ever retried, on a network failure, a timeout, a 429 or a 5xx. A POST, including execute(), is never retried, and a policy rejection is a final answer that must never be retried. See TypeScript SDK configuration and behavior for every option and default.

Error handling: fail closed

Every non-2xx response the Runtime returns maps to a specific, typed error — there is no “unknown error, assume success” path:
Two kinds of InternalServerError need different handling (1.1.3). Check error.serverCode. On SIGNING_UNAVAILABLE or EXECUTION_INTENT_UNAVAILABLE (503) nothing was executed, so retry later with a new businessTransactionId. On EXECUTION_RECORD_INCOMPLETE (500) the action was released and only its signed record failed, so never resubmit it under a new id: tell the operator, who can rebuild the record without repeating the action (see Execution Intents). The Execution Intent methods (executionIntent, unfinalizedExecutionIntents, finalizeExecutionIntent, resolveExecutionIntent) are in the SDK source and are not in the published 1.1.6, so until the next release the operator uses the HTTP API. POST /execute is not itself retried by the SDK’s retry policy — see TypeScript SDK for exactly which operations are retry-eligible. If you need your own retry around execute() (for a NetworkError/TimeoutError only, never for ExecutionRejectedError), reuse businessTransactionId on the retry — it’s the server’s idempotency key, so a retried execute() against a transaction that actually succeeded returns the original result instead of executing twice.

Audit logging pattern

Every ExecutionTrustRecord is already Parmana’s own durable, signed audit record — but most teams also want a local, queryable copy alongside their own application logs:
An illustrative schema for the table above:
This is a convenience index into your own systems, not a replacement for the signed record itself — for anything compliance-sensitive, verify against the ExecutionTrustRecord’s signature (see Verify independently), which doesn’t depend on this table being correct.

Monitoring pattern

Track, at minimum, the shape of decisions your service is producing — a spike in denials or a rising Parmana-call latency is usually the first signal something is wrong upstream of Parmana (a bad policy deploy, a misconfigured signal), not inside the SDK itself:
Reasonable alert thresholds to start from: denial rate crossing an unusual baseline for a given policy, error outcomes (network/timeout/internal, as opposed to denied) above zero for more than a few minutes, and p99 latency on execute() growing past your PARMANA_TIMEOUT_MS.

Rate limiting pattern

The Runtime itself does not currently return a 429/rate-limit response the SDK maps to a dedicated error (see TypeScript SDK for error classes that are defined but not yet thrown by any real condition) — if your own call volume needs shaping, do it client-side:

Testing in production

A smoke test to run right after every deploy, against the real endpoint you just deployed:
For a full execution smoke test (not just health), run it against a staging Runtime with a dedicated, obviously-named test policy and principal — never against a production policy your own smoke test could pollute with real audit entries.

Deployment checklist

  • PARMANA_ENDPOINT and PARMANA_API_KEY set from your secrets manager, not committed to source (see Deploy patterns).
  • retryPolicy configured deliberately — confirm what’s idempotent-safe to retry versus what isn’t (see the table above).
  • Every client.execute() / client.createTransaction() call site fails closed: a caught, unrecognized error is treated as not-approved, never as approved.
  • ExecutionRejectedError is never silently swallowed — it’s a real policy decision your caller needs to see.
  • businessTransactionId reuse on retry is intentional (idempotency), not accidental.
  • A signature-verification path exists independent of this SDK (see Verify independently) for anything you’ll need to prove later without trusting your own logs.
  • Smoke test wired into your deploy pipeline, hitting health()/version() at minimum.
  • Monitoring on denial rate and error rate, not just uptime.

Next

TypeScript SDK reference

The full, verified error taxonomy, model types, and test suite this page builds on.

Deploy patterns

Running the Parmana Runtime itself in production, not just the SDK client.

Verify independently

Re-verify a trust record’s signature without trusting this SDK or your own logs.

Limitations

What Parmana does and does not guarantee — read before writing an incident runbook.