Skip to main content
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:
This runs 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:
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.

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:
The committed .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:
This is real, fail-closed authentication, not a placeholder, see Authentication for how keys are minted and rotated outside this demo key.

5. Install the Python SDK

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

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:
Full runnable version: 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:
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.

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.