What You Will Build

By the end of this tutorial, you will have a running OpenLeash instance with an owner account, a registered agent, a YAML authorization policy, and a verified proof token. The entire setup runs locally — no cloud services, no databases, no external dependencies beyond Node.js.

Here is the flow: install OpenLeash, run the interactive wizard to create an owner and agent, write a policy that controls spending, send an authorization request, and verify the proof token that comes back. Each step builds on the previous one.

Prerequisites

You need Node.js 20 or later and npm. That is it. OpenLeash is a single npm package with no native dependencies. Check your version:

Check Node.js version
$ node --version
v22.4.0

Step 1: Install and Initialize

Install OpenLeash globally or use npx to run it directly. The wizard command walks you through initial setup: it creates a data directory, generates signing keys, and sets up your first owner account.

Install and run the wizard
$ npx openleash wizard
OpenLeash Setup Wizard
======================
? Enter a display name for the owner:
> Alice
? Enter a passphrase (min 8 chars):
> ********
Created owner: usr_01HQ3...
Generated Ed25519 signing keypair
Created data directory: ./data
Setup complete. Run `npx openleash start` to begin.

The wizard creates a ./data directory containing your owner file, signing keys, and a state index. All state is file-based — you can inspect, version control, or back up the data directory at any time.

Step 2: Start the Server

Start the OpenLeash sidecar. It runs as a local HTTP server on port 8787 by default and includes a web GUI for managing agents, policies, and approval requests.

Start the server
$ npx openleash start
OpenLeash v0.14.0
Listening on http://127.0.0.1:8787
GUI available at http://127.0.0.1:8787/gui

Open http://127.0.0.1:8787/gui in your browser to access the owner portal. Log in with the passphrase you set during the wizard. From here you can create agent invites, manage policies, and review approval requests.

Step 3: Register an Agent

Agents register by accepting an invite and providing an Ed25519 public key. The invite flow ensures only agents you authorize can connect. You can create an invite through the GUI or the API. Here we will use the TypeScript SDK from the agent's perspective:

agent-setup.ts — Register with OpenLeash
import {
generateEd25519Keypair,
registerAgent,
} from "@openleash/sdk";
// Generate a keypair for the agent
const keypair = await generateEd25519Keypair();
// Register using the invite code from the owner
const agent = await registerAgent({
baseUrl: "http://127.0.0.1:8787",
inviteCode: "inv_01HQ3...", // from GUI or API
publicKey: keypair.publicKey,
privateKey: keypair.privateKey,
name: "Shopping Agent",
});
console.log("Agent ID:", agent.agentId);
// Agent ID: agt_01HQ3...

The agent is now registered and bound to the owner. It can send authorization requests, but all requests will be denied until you create a policy that allows specific actions.

Step 4: Write a Policy

Policies define what actions an agent can perform and under what conditions. They are YAML files stored in ./data/policies/. Here is a policy that allows the agent to make purchases under $100, requires human approval for $100-$500, and denies anything above $500:

data/policies/spending-policy.yaml
id: pol_spending_limit
name: Spending Limit Policy
description: Controls agent purchasing behavior
rules:
- action: "purchase.*"
effect: ALLOW
conditions:
- field: context.amount
operator: lt
value: 100
- action: "purchase.*"
effect: REQUIRE_APPROVAL
conditions:
- field: context.amount
operator: gte
value: 100
- field: context.amount
operator: lte
value: 500
- action: "purchase.*"
effect: DENY
conditions:
- field: context.amount
operator: gt
value: 500

You can also create and manage policies through the CLI (npx openleash policy upsert) or the owner API. Policies take effect immediately — no server restart required.

Step 5: Authorize an Action

Now the agent can request authorization before performing actions. The SDK handles Ed25519 request signing automatically. Here is an authorization request for a $45 purchase:

agent-action.ts — Request authorization
import { authorize } from "@openleash/sdk";
const result = await authorize({
baseUrl: "http://127.0.0.1:8787",
privateKey: keypair.privateKey,
agentId: "agt_01HQ3...",
action: "purchase.order",
context: {
amount: 45,
currency: "USD",
vendor: "example-store",
description: "Office supplies",
},
});
console.log(result.decision);
// "ALLOW"
console.log(result.proof_token);
// "v4.public.eyJ..."

The request is evaluated against the spending policy. Since $45 is under the $100 threshold, the decision is ALLOW and OpenLeash returns a signed PASETO proof token. The agent can now proceed with the purchase and present the proof token to the vendor.

If the agent had requested a $250 purchase, the decision would be REQUIRE_APPROVAL, and the agent would need to wait for the owner to approve through the GUI or API. A $600 purchase would be denied outright.

Step 6: Verify the Proof Token

The counterparty (the service receiving the agent's request) verifies the proof token to confirm the action was authorized. Verification can be done offline using the owner's public key or online by calling the OpenLeash verification endpoint:

verify.ts — Verify proof token (offline)
import { verifyProofOffline } from "@openleash/sdk";
// Public key from GET /v1/public-keys
const publicKey = "...owner-ed25519-public-key...";
const verified = await verifyProofOffline({
token: result.proof_token,
publicKey,
});
console.log(verified.action);
// "purchase.order"
console.log(verified.decision);
// "ALLOW"
console.log(verified.constraints);
// { max_amount: 100, currency: "USD" }

Offline verification uses only the public key and the token itself — no network call to OpenLeash. This means proof tokens work even when the authorization server is offline, across different networks, and with zero additional latency.

For online verification (useful when you do not have the public key cached), use the POST /v1/verify-proof endpoint or verifyProofOnline() in the SDK.

What Happens in the Audit Log

Every authorization decision is recorded in the append-only audit log at ./data/audit.log.jsonl. Each line is a JSON object with the full request, decision, policy matches, and timestamp. The log is useful for debugging policy behavior, compliance reporting, and understanding how your agent is operating over time.

Audit log entry
{
"timestamp": "2026-04-10T12:00:00.000Z",
"agent_id": "agt_01HQ3...",
"action": "purchase.order",
"decision": "ALLOW",
"matched_policies": ["pol_spending_limit"],
"context": { "amount": 45, "currency": "USD" }
}

Next Steps

You now have a working authorization setup. From here you can:

  • Write more policies for different action types (email, file access, API calls)
  • Set up approval workflows for high-value actions
  • Integrate the SDK into your agent framework (works with LangChain, CrewAI, AutoGen, or any custom agent)
  • Deploy OpenLeash as a Docker container for production use
  • Use the interactive playground to test policy evaluation

For more depth, explore the AI agent authorization concepts, learn why we chose PASETO over JWT for proof tokens, or read about why AI agents need authorization in production systems. The full API reference and policy language documentation are available in the documentation.