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 step 6 below sets both to
the same value.1. Install dependencies
2. Generate a local Gateway keypair
The Execution Gateway signs its own attestations with a keypair separate from the authorization-verification key (keys/default.*.pem, already committed for local dev). No
key is generated automatically, you have to create one:
scripts/generate-keypair.ts --algorithm ed25519 --key-id gateway, writing
keys/gateway.private.pem / keys/gateway.public.pem. keys/ is gitignored, this stays
local. See Deploy patterns for how to manage keys outside local dev.
3. Start the Runtime locally
The committed.env 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:
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.4. Every other route requires a bearer key
/health is the one route exempt from caller authentication (along with /ready,
/openapi.yaml, and /documentation). Everything else, including /version, fails closed
with a 401 before a Business Transaction is even constructed:
.env ships one demo caller key for local development, callerId: "demo",
raw key my-secret-api-key (only its SHA-256 hash is ever stored, see
Authentication). Send it as a bearer token and the same
route succeeds:
5. Install the Python SDK
6. Execute a Business Transaction
create_business_transaction() derives every id pair the server checks for consistency, so
there’s nothing to hand-assemble and get wrong:
python/examples/quickstart/run.py, this is exactly the transaction
it sends. python/tests/test_quickstart_example.py runs this script against a real,
freshly-spawned server on every test run, so this example is verified to work, not just
syntax-checked.
7. Real output
Captured from an actual run against a local server, 2026-09-14: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.
Next
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.