Skip to main content
This chapter runs everything on your machine, with no database and no cloud account. Every command and every line of output below was run on a fresh clone of the repository on 2026-10-01.

Before you begin

  • Node.js 22 or later, and Git.
  • About ten minutes. npm ci and the first build take most of it.

1. Set up a fresh clone

What each step is for: If a later step fails with a missing file under keys/, one of the two key commands was skipped.

2. Watch a person decide

Tutorial 119 runs the real customer-refund 1.2.0 policy and the components the server runs, in one process.
It ends with:
Read it as the four rules of Chapter 1 in action:
  • The agent’s own claims (eligible, fraud check passed) never approve a refund (steps 1 and 2).
  • Saying managerApproved: true is worth nothing without a signed approval (step 3).
  • A signed approval covers one action, one resource, up to one amount, once (steps 5 to 7).
  • The policy still applies to an approved request (step 8).

3. Release an action to a system Parmana has no code for

Tutorial 123 registers an external connector through maker checker, runs an example endpoint from the SDK on your machine, and releases an approved request to it.
The parts that matter (the server’s own log lines are left out):
Chapter 6 explains each step.

4. Run the server and call it from the SDK

The tutorials run Parmana in one process. Now run the server and talk to it over HTTP, as an agent does.

Make a caller key for your agent

It prints the raw key once (Key : ...) and the entry to configure ({"callerId":"local-agent","keyHash":...}). Only the hash is ever stored. Keep the raw key for the agent; put the entry in PARMANA_API_KEYS.

Make an approver key and sign an approval

You play the approver here. On a real deployment the approver is a different person (Chapter 5).
The approval expires after 15 minutes unless you pass --ttl-seconds, and it can be used once.

Start the server

NODE_ENV=test with PARMANA_STORAGE=memory runs with no database. It also registers test:fixture-execute, a connector that needs no credential, and trusts the approver key in PARMANA_TEST_APPROVER_PUBLIC_KEY_FILE. The server refuses to start if that variable is set with any other NODE_ENV.
Paste the whole entry the key script printed, not a retyped one. In another terminal:
Every route except /health, /ready and the API description routes needs a key.

Send a request, refused, then approved

Save as first-action.ts in typescript/examples/ (so @parmana/sdk resolves to the SDK you built) and run it with PARMANA_API_KEY set to the raw key:
Output (your hash differs):
allowedPrincipalIds defaults to the caller id when the key entry names none. That is why the request acts as me.callerId.

When something goes wrong

Next

Chapter 3 does the same from a real agent, against a real server, in both SDKs.