https://github.com/openleash/openleash
An open-source authorization layer where owners set policies, agents ask before acting, and counterparties can verify the agent was authorized.
https://github.com/openleash/openleash
ai-agents ai-safety authorization cryptography local-first nodejs paseto policy-engine sidecar typescript
Last synced: about 2 months ago
JSON representation
An open-source authorization layer where owners set policies, agents ask before acting, and counterparties can verify the agent was authorized.
- Host: GitHub
- URL: https://github.com/openleash/openleash
- Owner: openleash
- License: apache-2.0
- Created: 2026-02-16T07:55:43.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-04-13T16:26:37.000Z (about 2 months ago)
- Last Synced: 2026-04-13T17:45:21.067Z (about 2 months ago)
- Topics: ai-agents, ai-safety, authorization, cryptography, local-first, nodejs, paseto, policy-engine, sidecar, typescript
- Language: TypeScript
- Homepage: https://openleash.ai
- Size: 1.58 MB
- Stars: 10
- Watchers: 2
- Forks: 3
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
- Agents: AGENTS.md
Awesome Lists containing this project
README

# OpenLeash
๐ **Authorization guardrails for AI agents.** ๐ฆ
[](https://github.com/openleash/openleash/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@openleash/core)
[](LICENSE)
[](https://github.com/openleash/openleash/discussions)
[๐ Docs](docs/) โข [๐ Getting Started](#quickstart) โข [๐ฆ npm](https://www.npmjs.com/org/openleash) โข [๐ฌ Discussions](https://github.com/openleash/openleash/discussions)
---
## What is OpenLeash?
An open-source authorization layer where owners set policies, agents ask before acting, and counterparties can verify the agent was authorized.
OpenLeash runs locally next to your AI agent runtime. Before an agent takes a side-effectful action (purchases, bookings, sending messages, government submissions), it asks OpenLeash. The server evaluates the request against YAML policies and returns a decision (`ALLOW`, `DENY`, `REQUIRE_APPROVAL`, `REQUIRE_STEP_UP`, `REQUIRE_DEPOSIT`), a list of obligations, and optionally a short-lived proof token (PASETO v4.public) that counterparties can verify.
## โก Quickstart
```bash
# Clone and build
git clone https://github.com/openleash/openleash.git && cd openleash
npm install && npm run build
# Start the server (bootstraps ./data and config.yaml)
npx openleash start
# Run the interactive setup wizard
npx openleash wizard
```
## ๐ง SDK Usage
```typescript
import { authorize } from '@openleash/sdk-ts';
const result = await authorize({
openleashUrl: 'http://127.0.0.1:8787',
agentId: 'my-agent',
privateKeyB64: process.env.OPENLEASH_AGENT_PRIVATE_KEY_B64!,
action: {
action_id: crypto.randomUUID(),
action_type: 'purchase',
requested_at: new Date().toISOString(),
principal: { agent_id: 'my-agent' },
subject: { principal_id: '' },
relying_party: { domain: 'example.com', trust_profile: 'LOW' },
payload: { amount_minor: 5000, currency: 'USD', merchant_domain: 'example.com' },
},
});
console.log(result);
```
Verify a proof offline:
```typescript
import { verifyProofOffline } from '@openleash/sdk-ts';
const result = await verifyProofOffline({
token: proofToken,
publicKeys: [{ kid: 'key-id', public_key_b64: 'base64...' }],
});
console.log(result.valid, result.claims);
```
## ๐งช Playground
Run predefined scenarios to test policy behavior:
```bash
npx openleash playground list
npx openleash playground run small_purchase_allowed
npx openleash playground run large_purchase_requires_approval
```
## ๐ CLI Commands
| Command | Description |
|---|---|
| `openleash start` | Start the server |
| `openleash wizard` | Interactive setup wizard |
| `openleash policy list` | List policies |
| `openleash policy show ` | Show policy YAML |
| `openleash policy upsert --owner --file ` | Create/update policy |
| `openleash policy validate --file ` | Validate policy YAML |
| `openleash playground list` | List scenarios |
| `openleash playground run ` | Run a scenario |
| `openleash keys list` | List signing keys |
| `openleash keys rotate` | Rotate signing key |
| `openleash testvectors` | Generate test vectors |
## ๐ API Reference
When the server is running, an interactive API reference and machine-readable OpenAPI spec are available:
- **Interactive reference:** `http://localhost:8787/reference`
- **OpenAPI spec (JSON):** `http://localhost:8787/reference/openapi.json`
The `/v1/health` endpoint also includes these URLs in its response.
## ๐๏ธ Architecture
```
packages/
core/ # Authorization engine, types, crypto, state management
server/ # Fastify HTTP server, routes, middleware
gui/ # Server-rendered HTML GUI (admin + owner portal)
sdk-ts/ # TypeScript SDK for agents and counterparties
cli/ # CLI commands (start, wizard, policy, playground, keys)
```
Four actor types interact with the API:
| Actor | Auth | Endpoints |
|---|---|---|
| **Public** | None | `/v1/health`, `/v1/public-keys`, `/v1/verify-proof` |
| **Agent** | Ed25519 request signing | `/v1/authorize`, `/v1/agent/*` |
| **Owner** | PASETO session token | `/v1/owner/*` |
| **Admin** | Bearer token / localhost | `/v1/admin/*` |
All state is stored in human-readable files:
- `./data/state.md` โ authoritative index (markdown with YAML)
- `./data/owners/` โ owner profiles (markdown with YAML frontmatter)
- `./data/agents/` โ agent records (markdown with YAML frontmatter)
- `./data/policies/` โ policy YAML files
- `./data/keys/` โ signing key JSON files
- `./data/approval-requests/` โ approval request records
- `./data/policy-drafts/` โ agent-proposed policy drafts
- `./data/invites/` โ owner setup invites
- `./data/agent-invites/` โ agent registration invites
- `./data/audit.log.jsonl` โ append-only audit log
## ๐ Approval Workflow
When a policy includes a `HUMAN_APPROVAL` obligation, agents must get explicit owner approval:
```
Agent โ POST /v1/authorize โ REQUIRE_APPROVAL
Agent โ POST /v1/agent/approval-requests โ Creates pending request
Owner โ POST /v1/owner/.../approve โ Issues approval token
Agent โ POST /v1/authorize (+ token) โ ALLOW + proof token
```
Approval tokens are single-use, action-scoped, and time-limited. See [docs/protocol.md](docs/protocol.md) for details.
## ๐ Policy Drafts
Agents can propose new policies to their owner when they need access to action types not covered by existing rules:
```
Agent โ POST /v1/agent/policy-drafts โ Submits draft YAML + justification
Owner โ GET /v1/owner/policy-drafts โ Reviews pending drafts
Owner โ POST /v1/owner/.../approve โ Creates real policy + binding
Agent โ GET /v1/agent/policy-drafts/:id โ Sees APPROVED + resulting_policy_id
```
This lets agents self-serve within the owner's control โ the owner always has the final say. See [docs/protocol.md](docs/protocol.md#policy-drafts) for the full specification.
## ๐ค Owner Portal
The owner portal is a self-service web interface where owners can manage their policies, review pending approval requests, and view registered agents. Access it at `/gui/login`.
**Setup flow:**
1. An admin creates an owner via the Admin Dashboard (`/gui/dashboard`) or `npx openleash wizard`
2. The admin generates a setup invite โ the GUI produces a copyable setup link
3. The owner opens the link (`/gui/owner-setup?invite_id=...&invite_token=...`) and chooses a passphrase
4. After setup, the owner is offered to create an **agent invite** โ a single URL that an agent uses to register itself
5. The owner logs in at `/gui/login` with their Owner Principal ID and passphrase
## ๐ค Agent Registration
Agents register via **invite URLs** created by owners (or admins). The invite URL is self-contained โ the agent POSTs its public key and agent ID to it, and receives back its identity, the signing protocol, all available endpoints, and SDK install instructions.
**Using the TypeScript SDK:**
```typescript
import { redeemAgentInvite } from '@openleash/sdk-ts';
const agent = await redeemAgentInvite({
inviteUrl: process.env.OPENLEASH_AGENT_INVITE_URL!,
agentId: 'my-agent',
});
// agent.openleash_url, agent.private_key_b64, agent.agent_principal_id, ...
```
Owners can create agent invites from:
- The owner setup page (offered immediately after setting a passphrase)
- The owner agents page (`/gui/admin/agents`)
- The admin agents page (`/gui/admin/agents`)
See [AGENTS.md](AGENTS.md) for the full agent integration guide.
## ๐ Troubleshooting
### NO_POLICY errors
If an agent gets a `403` with `NO_POLICY`, it means no policy is bound to the agent or its owner. Create a policy and bind it via the owner portal or `npx openleash policy upsert`.
### Clock skew errors
If you get `TIMESTAMP_SKEW` errors, ensure the requesting system's clock is synchronized. The default allowed skew is ยฑ120 seconds. Adjust in `config.yaml`:
```yaml
security:
clock_skew_seconds: 300
```
### Nonce replay errors
Each nonce can only be used once per agent within the TTL window (default 600 seconds). Generate a unique nonce (UUID) for each request.
### Invalid signature errors
- Ensure you're using the correct private key (PKCS8 DER base64 format)
- The signing input must be exactly: `METHOD\nPATH\nTIMESTAMP\nNONCE\nBODY_SHA256`
- The body SHA256 must match the raw request body bytes
### Admin token confusion
- Default admin mode is `localhost_or_token`: localhost requests bypass token check
- If accessing remotely, you need `admin.allow_remote_admin: true` and a valid bearer token
- Token is stored in `config.yaml` under `admin.token`
### Data folder location
OpenLeash stores all state in `./data/` relative to where you run the command. Make sure you run all commands from the same directory.
## ๐ค Contributing
Contributions are welcome! Please read the [Contributing Guide](CONTRIBUTING.md) before submitting a pull request.
## ๐ License
[Apache-2.0](LICENSE)