AI got hands. This is the leash.
Policy, audit, kill switch for any AI agent with access to your accounts.
You need an AnchorBrowser API key: export ANCHOR_API_KEY=your-key
npm install leashed
Create leash.yaml:
agent: my-sales-bot rules: allow: - "read*" - "list*" - "check*" - "search*" deny: - "*send*" - "*delete*" - "*export*" - "*password*" default: deny expire_after: 60min max_actions: 50
import { createLeash } from 'leashed' const leash = createLeash('./leash.yaml') const result = await leash.task('check linkedin inbox') // → { allowed: true, output: '...' } const result2 = await leash.task('export all contacts to CSV') // → { allowed: false, reason: 'blocked by deny pattern: *export*' }
Every leash.task() call is policy-checked, audited, and budgeted.
- Credential isolation — your password stays in an isolated cloud browser. The agent gets a pre-authenticated session, never the credentials themselves.
- Scoped boundaries — tasks that don't match your policy are blocked before they start. Deny-first pattern matching with Unicode bypass protection.
- Audit + kill switch — every action logged (allowed and blocked). Budget enforced. Session destruction when you're done.
leashed is application-layer authz for AI agents — it governs what agents are authorized to do, not who they are or what credentials they hold.
| Layer | How |
|---|---|
| Task gating | Deny-first glob pattern matching on task strings |
| Time + action budgets | Configurable expiration and action limits |
| Credential isolation | Passwords stay in AnchorBrowser's isolated session |
| Session destruction | leash.yank() destroys the cloud browser session |
| Audit trail | Every task request (allowed + blocked) logged to JSONL |
| Unicode bypass protection | Strips zero-width chars, combining marks, BiDi controls |
| Layer | Why |
|---|---|
| Browser action validation | AnchorBrowser executes tasks autonomously — leashed gates the request, not the execution |
| URL/domain restrictions | Requires AnchorBrowser session-level allowlists (roadmap) |
| Semantic equivalence | "forward email" and "send email to myself" are different strings — patterns match literally |
The honest version: leashed is a seatbelt, not a cage. It stops the 95% of accidents from misconfiguration, scope creep, and unintended actions. A deliberately adversarial agent that lies about what it's doing can bypass pattern matching. For defense-in-depth, see SECURITY.md.
npx leashed status # Agent: my-sales-bot | Allowed: 23 | Blocked: 3 npx leashed audit # Full audit trail npx leashed yank # Kill switch — destroy session immediately
Full API reference, policy examples, and audit log format →
git clone https://github.com/dormstern/leashed.git cd leashed npm install npm run build npm test
Tests run against mocked AnchorBrowser sessions — no API key needed for development. CI runs on Node 18, 20, and 22.
- Post-execution validation: scan AnchorBrowser output for policy-violating content
- Domain hints in policy for audit enrichment
- Structured output schemas
- URL allowlists enforced at the browser level
- Browser action audit trail (clicks, form fills, navigation)
- Webhook callbacks for real-time policy violation alerts
Open an issue or see CONTRIBUTING.md to help shape v1.0.
leashed runs on AnchorBrowser — ephemeral, hardened cloud browser sessions for AI agents. SOC2 Type 2, ISO27001 certified. Trusted by Google, Coinbase, and Groq.
AnchorBrowser handles the browser. leashed handles the rules.
See CONTRIBUTING.md for development setup, coding standards, and how to submit changes.
MIT

