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.
"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
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.Install and build
.env.example is in the repository; .env is gitignored and holds your local settings.Generate the local signing keys
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: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.Make a local approver key
~/.parmana/local-test-approver__local-test-approver-key-1.private.pem (keep it)
and .public.pem (the server trusts it in the next step).Start the Runtime locally
.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: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.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: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:Install the SDK
Sign an approval, then execute a Business Transaction
createBusinessTransaction
helper derives every id pair the server checks for consistency, so there’s nothing to
hand-assemble and get wrong: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.Real output
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.