Skip to content

Commit 1ba1119

Browse files
committed
tighten README for developer audience
- Remove marketing sections (use cases, crane metaphor, mermaid diagrams, company backstory) - Keep: Quick Start, Security Model, CLI, Roadmap - Add Development section with clone/build/test - Add CONTRIBUTING.md - Rename shield.test.ts → leash.test.ts (pre-rebrand artifact) - Rename examples/shield.yaml → examples/leash.yaml - Fix npm badge color (orange → blue) - Add CI badge Signed-off-by: dormstern <dormstern@gmail.com>
1 parent fbe0528 commit 1ba1119

4 files changed

Lines changed: 109 additions & 189 deletions

File tree

CONTRIBUTING.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Contributing to leashed
2+
3+
Thanks for your interest in contributing.
4+
5+
## Getting Started
6+
7+
```bash
8+
git clone https://github.com/dormstern/leashed.git
9+
cd leashed
10+
npm install
11+
npm run build
12+
npm test
13+
```
14+
15+
No AnchorBrowser API key is needed for development — all tests run against mocked sessions.
16+
17+
## Making Changes
18+
19+
1. Fork the repo and create a branch from `main`
20+
2. Write or update tests for your changes
21+
3. Run `npm test` to make sure everything passes
22+
4. Run `npm run build` to verify TypeScript compilation
23+
5. Open a pull request
24+
25+
## Project Structure
26+
27+
```
28+
src/
29+
index.ts # createLeash() — main entry point
30+
policy.ts # Pattern matching + deny-first evaluation
31+
session.ts # AnchorBrowser session lifecycle
32+
audit.ts # JSONL audit log
33+
output-scanner.ts # Post-execution output scanning
34+
cli.ts # npx leashed commands
35+
types.ts # TypeScript types
36+
constants.ts # Shared constants
37+
tests/
38+
leash.test.ts # Integration tests (mocked AnchorBrowser)
39+
policy.test.ts # Policy evaluation unit tests
40+
audit.test.ts # Audit log unit tests
41+
cli.test.ts # CLI unit tests
42+
output-scanner.test.ts # Output scanner tests
43+
examples/
44+
leash.yaml # Example policy file
45+
basic.ts # Minimal usage example
46+
openclaw-inbox.ts # OpenClaw inbox agent example
47+
```
48+
49+
## Coding Standards
50+
51+
- TypeScript strict mode
52+
- Tests via Vitest
53+
- No runtime dependencies beyond `anchorbrowser`, `js-yaml`, `picomatch`
54+
- Fail closed — errors are reported as blocked, never silently swallowed
55+
56+
## Reporting Bugs
57+
58+
Use the [bug report template](https://github.com/dormstern/leashed/issues/new?template=bug_report.md). Include your policy config and Node version.
59+
60+
## Security Vulnerabilities
61+
62+
Do **not** file a public issue for security vulnerabilities. See [SECURITY.md](./SECURITY.md).

README.md

Lines changed: 47 additions & 189 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44
55
Policy, audit, kill switch for any AI agent with access to your accounts.
66

7-
[![npm version](https://img.shields.io/npm/v/leashed)](https://www.npmjs.com/package/leashed)
7+
[![npm version](https://img.shields.io/npm/v/leashed?color=blue)](https://www.npmjs.com/package/leashed)
88
[![license](https://img.shields.io/npm/l/leashed)](./LICENSE)
99
[![tests](https://img.shields.io/badge/tests-67%20passing-brightgreen)](#)
10-
11-
**[See the full showcase →](https://behalf.work/harness/)**
10+
[![CI](https://github.com/dormstern/leashed/actions/workflows/ci.yml/badge.svg)](https://github.com/dormstern/leashed/actions/workflows/ci.yml)
1211

1312
### OpenClaw sales bot — leashed
1413

@@ -18,10 +17,6 @@ Policy, audit, kill switch for any AI agent with access to your accounts.
1817

1918
![Work assistant demo](docs/demos/work-assistant-demo.gif)
2019

21-
## The Problem
22-
23-
[42,000 live credentials leaked](https://www.wired.com/story/ai-agent-credential-leaks/) from AI agent workflows. The community's response? Buy a separate Mac Mini. **leashed replaces the Mac Mini** — software governance instead of hardware isolation.
24-
2520
## Quick Start
2621

2722
You need an [AnchorBrowser](https://anchorbrowser.io) API key: `export ANCHOR_API_KEY=your-key`
@@ -37,7 +32,7 @@ npm install leashed
3732
Create `leash.yaml`:
3833

3934
```yaml
40-
agent: my-openclaw-sales-bot
35+
agent: my-sales-bot
4136
rules:
4237
allow:
4338
- "read*"
@@ -68,223 +63,86 @@ const result2 = await leash.task('export all contacts to CSV')
6863
// → { allowed: false, reason: 'blocked by deny pattern: *export*' }
6964
```
7065
71-
That's it. Every `leash.task()` call is policy-checked, audited, and budgeted.
72-
73-
## Common Use Cases
74-
75-
People give agents their passwords every day. Here's what they're afraid of — and how `leashed` fixes it.
76-
77-
### 1. LinkedIn Sales Agent (OpenClaw)
78-
79-
**The fear:** Your bot has your LinkedIn password. It's supposed to read your inbox and check messages. But what if it starts mass-connecting, exporting contacts, or changing your profile?
80-
81-
**With leashed:**
82-
83-
```yaml
84-
agent: linkedin-sales-bot
85-
rules:
86-
allow:
87-
- "read*"
88-
- "list*"
89-
- "check*"
90-
- "search*"
91-
deny:
92-
- "*send*"
93-
- "*connect*"
94-
- "*export*"
95-
- "*settings*"
96-
- "*password*"
97-
default: deny
98-
expire_after: 60min
99-
max_actions: 50
100-
```
101-
102-
Read inbox, check messages — allowed. Mass-connect, export contacts — blocked before it starts.
103-
104-
### 2. Email & Calendar Assistant
105-
106-
**The fear:** Your assistant has your Gmail. It reads your calendar and summarizes emails. But what if it deletes messages, forwards sensitive emails externally, or changes your billing settings?
107-
108-
**With leashed:**
109-
110-
```yaml
111-
agent: daily-briefing
112-
rules:
113-
allow:
114-
- "read*"
115-
- "list*"
116-
- "check*"
117-
- "summarize*"
118-
deny:
119-
- "*delete*"
120-
- "*forward*"
121-
- "*billing*"
122-
- "*settings*"
123-
- "*password*"
124-
default: deny
125-
expire_after: 30min
126-
max_actions: 100
127-
```
128-
129-
Read calendar, list emails, summarize threads — allowed. Delete, forward, change settings — blocked.
130-
131-
### 3. CRM Data Entry Bot
66+
Every `leash.task()` call is policy-checked, audited, and budgeted.
13267

133-
**The fear:** Your bot updates Salesforce records from your email threads. But what if it bulk-deletes contacts, exports your pipeline, or modifies deal values?
134-
135-
**With leashed:**
136-
137-
```yaml
138-
agent: crm-updater
139-
rules:
140-
allow:
141-
- "read*"
142-
- "update*"
143-
- "list*"
144-
- "search*"
145-
deny:
146-
- "*delete*"
147-
- "*export*"
148-
- "*bulk*"
149-
- "*admin*"
150-
- "*billing*"
151-
default: deny
152-
expire_after: 45min
153-
max_actions: 200
154-
```
155-
156-
Read records, update fields, search contacts — allowed. Bulk-delete, export pipeline, admin changes — blocked.
157-
158-
---
159-
160-
## AI got hands. We control the grip.
161-
162-
Think of a crane operator. The brain decides what to move — but the joystick decides how far the arm can reach. **leashed is the joystick between the AI agent and your accounts.**
163-
164-
### Without leashed
165-
166-
```mermaid
167-
flowchart LR
168-
A["🤖 AI Agent<br/><i>the brain</i>"]
169-
B["📧 Your Accounts<br/><i>LinkedIn, Gmail, CRM</i>"]
170-
171-
A -- "🔴 your password<br/>full access" --> B
172-
173-
style A fill:#fef2f2,stroke:#fca5a5,color:#991b1b
174-
style B fill:#fef2f2,stroke:#fca5a5,color:#991b1b
175-
```
176-
177-
> **The agent IS you.** Full access. No limits. No off switch.
178-
179-
### With leashed
180-
181-
```mermaid
182-
flowchart LR
183-
A["🤖 AI Agent<br/><i>the brain</i>"]
184-
S["🛡️ leashed<br/><i>the joystick</i>"]
185-
B["📧 Your Accounts<br/><i>LinkedIn, Gmail, CRM</i>"]
186-
187-
A -- "requests action" --> S
188-
S -- "🟢 scoped access" --> B
189-
190-
style A fill:#f0fdf4,stroke:#86efac,color:#166534
191-
style S fill:#ede9fc,stroke:#6d5bd0,color:#6d5bd0
192-
style B fill:#f0fdf4,stroke:#86efac,color:#166534
193-
```
194-
195-
> **The agent works through controlled arms.** You decide what moves.
196-
197-
| | |
198-
|---|---|
199-
| ✅ read inbox | ✅ list messages |
200-
| ❌ delete data | ❌ export contacts |
201-
| ⏱️ 60 min limit | 🔢 50 actions max |
202-
203-
> *A crane operator doesn't carry the steel himself. He moves joysticks that control arms — limited to a work zone, every movement tracked, with an emergency stop within reach. That's what leashed does for AI agents.*
204-
205-
### Three layers of protection
68+
## How It Works
20669

20770
1. **Credential isolation** — your password stays in an isolated cloud browser. The agent gets a pre-authenticated session, never the credentials themselves.
20871
2. **Scoped boundaries** — tasks that don't match your policy are blocked before they start. Deny-first pattern matching with Unicode bypass protection.
20972
3. **Audit + kill switch** — every action logged (allowed and blocked). Budget enforced. Session destruction when you're done.
21073

21174
## Security Model
21275

213-
In security terms, 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. Think of it like an AWS IAM policy that checks what you *request*, not what the underlying service *executes*.
76+
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.
21477

215-
### What leashed enforces today (v0.1)
78+
### What leashed enforces
21679

217-
| Layer | Enforced | How |
218-
|-------|----------|-----|
219-
| Task gating | Yes | Deny-first glob pattern matching on task strings |
220-
| Time + action budgets | Yes | Configurable expiration and action limits |
221-
| Credential isolation | Yes | Passwords stay in AnchorBrowser's isolated session, never exposed to the agent |
222-
| Session destruction | Yes | `leash.yank()` destroys the cloud browser session |
223-
| Audit trail | Yes | Every task request (allowed + blocked) logged to JSONL |
224-
| Unicode bypass protection | Yes | Strips zero-width chars, combining marks, BiDi controls |
80+
| Layer | How |
81+
|-------|-----|
82+
| Task gating | Deny-first glob pattern matching on task strings |
83+
| Time + action budgets | Configurable expiration and action limits |
84+
| Credential isolation | Passwords stay in AnchorBrowser's isolated session |
85+
| Session destruction | `leash.yank()` destroys the cloud browser session |
86+
| Audit trail | Every task request (allowed + blocked) logged to JSONL |
87+
| Unicode bypass protection | Strips zero-width chars, combining marks, BiDi controls |
22588

226-
### What leashed does NOT enforce (yet)
89+
### What leashed does NOT enforce
22790

228-
| Layer | Status | Why |
229-
|-------|--------|-----|
230-
| Browser action validation | Roadmap (v1.0) | AnchorBrowser executes tasks autonomously — leashed has no visibility into actual browser clicks/navigation |
231-
| URL/domain restrictions | Roadmap (v1.0) | Requires AnchorBrowser session-level allowlists (not yet available in their SDK) |
232-
| Semantic equivalence | By design | `"forward email"` and `"send email to myself"` are different strings — glob patterns match literally, not semantically |
91+
| Layer | Why |
92+
|-------|-----|
93+
| Browser action validation | AnchorBrowser executes tasks autonomously — leashed gates the request, not the execution |
94+
| URL/domain restrictions | Requires AnchorBrowser session-level allowlists (roadmap) |
95+
| Semantic equivalence | `"forward email"` and `"send email to myself"` are different strings — patterns match literally |
23396

234-
### The honest version
97+
**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](./SECURITY.md).
23598

236-
The policy engine checks the **task description string** — the human-readable instruction you pass to `leash.task()`. If the string matches a deny pattern, it never reaches the browser. If it's allowed, AnchorBrowser's AI executes it autonomously.
99+
## CLI
237100

238-
This means: a well-intentioned agent that uses descriptive task names gets real governance. A deliberately adversarial agent that lies about what it's doing can bypass pattern matching — just like a developer with an IAM read-only key could name their Lambda "ReadOnlyFunction" while it actually writes to S3.
101+
```bash
102+
npx leashed status # Agent: my-sales-bot | Allowed: 23 | Blocked: 3
103+
npx leashed audit # Full audit trail
104+
npx leashed yank # Kill switch — destroy session immediately
105+
```
239106

240-
**leashed is a seatbelt, not a cage.** It stops the 95% of accidents that come from misconfiguration, scope creep, and unintended actions. It does not stop a determined attacker with direct API access.
107+
## API
241108

242-
For defense-in-depth, see [SECURITY.md](./SECURITY.md).
109+
[Full API reference, policy examples, and audit log format →](./docs/API.md)
243110

244-
## CLI
111+
## Development
245112

246113
```bash
247-
npx leashed status # Agent: my-openclaw-sales-bot | Allowed: 23 | Blocked: 3
248-
npx leashed audit # Full audit trail
249-
npx leashed yank # Kill switch — destroy session immediately
114+
git clone https://github.com/dormstern/leashed.git
115+
cd leashed
116+
npm install
117+
npm run build
118+
npm test
250119
```
251120

252-
[Full API reference & policy examples →](./docs/API.md)
121+
Tests run against mocked AnchorBrowser sessions — no API key needed for development. CI runs on Node 18, 20, and 22.
253122

254123
## Roadmap
255124

256-
leashed is v0.1 — the governance primitives. Here's what's coming:
257-
258-
### v0.2 — Output Scanning
125+
### v0.3 — Output Scanning (current)
259126
- Post-execution validation: scan AnchorBrowser output for policy-violating content
260-
- Domain hints in policy: `domains: [linkedin.com]` for documentation and audit enrichment
261-
- Structured output schemas for safer result parsing
127+
- Domain hints in policy for audit enrichment
128+
- Structured output schemas
262129

263-
### v1.0 — Session-Level Enforcement (with AnchorBrowser)
264-
- URL allowlists at the session level — the browser itself refuses to navigate outside your policy
265-
- Browser action audit trail — not just task requests, but actual clicks, form fills, and navigation
130+
### v1.0 — Session-Level Enforcement
131+
- URL allowlists enforced at the browser level
132+
- Browser action audit trail (clicks, form fills, navigation)
266133
- Webhook callbacks for real-time policy violation alerts
267-
- This is the "IAM enforcement" layer — restrictions enforced by the infrastructure, not just the intent
268134

269-
Want to help shape v1.0? [Open an issue](https://github.com/dormstern/leashed/issues) or reach out.
135+
[Open an issue](https://github.com/dormstern/leashed/issues) or see [CONTRIBUTING.md](./CONTRIBUTING.md) to help shape v1.0.
270136

271137
## Empowered by AnchorBrowser
272138

273-
leashed runs on [AnchorBrowser](https://anchorbrowser.io) — ephemeral, hardened cloud browser sessions purpose-built for AI agents. Each session is isolated, auto-expires, and leaves no trace. [Cloudflare](https://cloudflare.com) verified bot partner. SOC2 Type 2 and ISO27001 certified. Trusted by [Google](https://google.com), [Coinbase](https://coinbase.com), and [Composio](https://composio.dev). Stealth proxies, CAPTCHA solving, anti-fingerprinting, and full session isolation out of the box.
139+
leashed runs on [AnchorBrowser](https://anchorbrowser.io) — ephemeral, hardened cloud browser sessions for AI agents. SOC2 Type 2, ISO27001 certified. Trusted by Google, Coinbase, and Groq.
274140

275141
AnchorBrowser handles the browser. leashed handles the rules.
276142

277-
[Get an API key →](https://anchorbrowser.io)
278-
279-
## Why This Exists
280-
281-
[Behalf](https://behalf.work) already powers safe delegation for humans — scoped sessions, audit trails, and instant revocation for people who delegate work through their accounts. We built the trust infrastructure, battle-tested it, and realized: **agents need the exact same thing.**
282-
283-
42,000 live credentials leaked from AI agent workflows. The community's best workaround is buying a separate Mac Mini. That's not security — that's surrender.
284-
285-
So we open-sourced the engine. `leashed` gives agents what they should have had from the start: **a policy file, an audit log, and a kill switch.** The same trust model that protects human delegation — now available for every agent operator.
143+
## Contributing
286144

287-
Half the access. All the work done.
145+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, coding standards, and how to submit changes.
288146

289147
## License
290148

0 commit comments

Comments
 (0)