Skip to main content

Step 0: try it live, with nothing installed

Before you install anything, call the public sandbox. It is a live Parmana server with a published demo key, and its one action, sandbox:receipt, acts on nothing. These two requests show the core of Parmana in one minute: the first is refused because it has no signed human approval, and the Playground then walks you through getting one, sending again, and verifying the signed record.
The first answers "callerId": "sandbox-visitor", allowed only sandbox:receipt. The second names the policy in effect, sandbox-receipt 1.0.0, and the facts a request must carry. Continue on the Playground, or go on below to run the same thing on your own machine, where you play the approver too.

Run it on your own machine

This walkthrough uses test:fixture-execute, a generic, credential-free capability built for local testing. It’s evaluated against a policy named vendor-payment. That policy name is unrelated to any connector; it’s simply the example policy this transaction runs against. SignalIntentBinder rejects a transaction whose declared vendorId signal doesn’t exactly match its intent.target (see Policies and the decision), so the execute step below sets both to the same value. Code samples below are shown for Python and TypeScript. Pick whichever matches your client.
No AI agent action is authorized without a signed human approval, reads included (Human approval). So this quickstart has you play the approver too: you make an approver key, the local server trusts it, and you sign an approval before the agent’s request. On a real deployment the approver is a different person, added through Manage approvers.
Running Parmana locally to evaluate it is permitted; any other use needs a written agreement, see License and evaluation.
1

Install and build

Only .env.example is in the repository; .env is gitignored and holds your local settings.
2

Generate the local signing keys

The server signs authorizations and records with the default key, and the Execution Gateway signs its own attestations with a separate gateway key. keys/ is gitignored, so a fresh clone has neither. Create both:
This writes keys/default.private.pem, keys/default.public.pem, keys/gateway.private.pem and keys/gateway.public.pem. They stay local. See Deploy patterns for how to manage keys outside local dev.
3

Make a local approver key

This writes ~/.parmana/local-test-approver__local-test-approver-key-1.private.pem (keep it) and .public.pem (the server trusts it in the next step).
4

Start the Runtime locally

The .env copied from .env.example defaults to Supabase-backed storage. To run fully locally with no external dependency, override storage to memory and set NODE_ENV=test. Both are required: PARMANA_STORAGE=memory alone only affects where Business Transactions and Trust Records are stored, two other components, the Execution Gateway’s replay-nonce store and the caller-authentication audit trail, independently default to Supabase outside NODE_ENV=test. With NODE_ENV=test, a generic, test-only connector (test-fixture) registers automatically, no credential environment variable required, and the server trusts local-test-approver with the key in PARMANA_TEST_APPROVER_PUBLIC_KEY_FILE:
PARMANA_TEST_APPROVER_PUBLIC_KEY_FILE is honored only when NODE_ENV is test. With any other NODE_ENV the server refuses to start while it is set.Confirm it’s up:
The Execution Gateway is wired into this server unconditionally. Every POST /execute is independently re-verified and routed through a real Connector. An action with no registered connector fails closed with "No connector registered for action", it does not silently skip enforcement. See The gateway.
5

Authenticate: every other route requires a bearer key

/health is the one route exempt from caller authentication (along with /ready, /openapi.yaml, /openapi.json, /api-manifest.json, /documentation, and /reference). Everything else, including /version, fails closed with a 401 before a Business Transaction is even constructed:
The PARMANA_API_KEYS entry in the previous step is a demo caller key for local development only: callerId: "demo", raw key my-secret-api-key, allowed to use test:fixture-execute and to act as demo (only its SHA-256 hash is stored, see Authentication). Its raw key is public, so never use it on a server anyone else can reach; make real keys with npm run generate:api-key. Send it as a bearer token and the same route succeeds:
This is real, fail-closed authentication, not a placeholder, see Authentication for how keys are minted and rotated outside this demo key.
6

Install the SDK

The SDK sends the bearer key from the previous step on every request:
7

Sign an approval, then execute a Business Transaction

First the approver signs an approval for this action, this target, up to this amount. Then the agent sends the transaction with the approval attached. The createBusinessTransaction helper derives every id pair the server checks for consistency, so there’s nothing to hand-assemble and get wrong:
Without humanApproved and a valid approvalArtifact, the server refuses this transaction with 403 POLICY_DENIED, whatever else the signals say.Full runnable versions: python/examples/quickstart/run.py and typescript/examples/06-create-business-transaction.ts, the same transactions run against a test server with authentication off, so they act as other principals; each takes the signed approval as an argument, or from the file PARMANA_APPROVAL_FILE names when run as a script. python/tests/test_quickstart_example.py and typescript/test/integration/examples.integration.test.ts run them against a real, freshly-spawned server on every test run, so both examples are verified to work, not just syntax-checked. The two samples above were run as shown, with the demo key, against a server started as in this page, on a fresh clone on 2026-10-01.
8

Real output

Captured from an actual run against a local server, 2026-09-14:
The full ExecutionTrustRecord includes the signature block, executions[0].decision (outcome: "APPROVED", evaluated by the vendor-payment policy), executions[0].evidence (what the connector actually did, including a connectorEvidenceHash), and an initial verifications / receipts history. See Trust Record for the complete shape, or python/examples/quickstart/README.md for the full captured JSON. For the equivalent captured TypeScript output (camelCase field names, same record shape), see TypeScript SDK Quickstart’s own “Real output” step.

Next

Playground

The full flow against the live sandbox: refusal, signed approval, approved release, offline verification.

How Parmana thinks

The concepts behind what just happened: policy, authorization, the gateway, trust records.

Verify & replay

Read back or re-run verification against the record you just created.

End-to-end: agent to Paytm

The same flow against a real connector and real infrastructure, not the local test fixture.