Skip to content

Commit 3218f3d

Browse files
committed
docs: add sample app guides and broker setup for demo scenarios
8 sample app guides (01-08) covering real-world AgentAuth patterns: order worker, data pipeline, patient guard, moderation delegation, deploy chain, trading agent, incident response, audit scanner. Plus broker setup guide and mini-max reference doc.
1 parent 1d868a0 commit 3218f3d

11 files changed

Lines changed: 4130 additions & 0 deletions

docs/sample-app-mini-max.md

Lines changed: 941 additions & 0 deletions
Large diffs are not rendered by default.

docs/sample-apps-broker-setup.md

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
# Broker Setup Guide
2+
3+
> **Purpose:** Set up the broker so the [sample apps](sample-app-mini-max.md) can run.
4+
> The apps need specific scope ceilings configured per app.
5+
> **Audience:** Operators registering apps, or developers verifying their app's ceiling.
6+
> **Prerequisites:** Broker running. See [Getting Started: Operator](../broker/docs/getting-started-operator.md) for broker deployment.
7+
8+
---
9+
10+
## Overview
11+
12+
Every app needs a registered scope ceiling. The ceiling is the **maximum** scope any agent created by that app can request. If an app requests a scope outside its ceiling, the broker returns `403` and no token is issued.
13+
14+
The app **cannot** discover its own ceiling — the operator sets it when registering the app, and the broker enforces it silently at agent creation time. You must track ceilings outside the broker.
15+
16+
---
17+
18+
## Step 1: Register the App
19+
20+
Register the app once. Replace the scopes with what your operator approved.
21+
22+
### Option A: Using aactl (recommended)
23+
24+
```bash
25+
export AACTL_BROKER_URL="http://localhost:8080"
26+
export AACTL_ADMIN_SECRET="your-admin-secret"
27+
28+
aactl app register \
29+
--name sample-apps \
30+
--scopes "read:data:*,write:data:*,read:customers:*,write:orders:*,read:files:*,write:files:*,read:monitoring:*,send:webhooks:*,read:billing:*,write:notes:*,read:audit:all,delete:customers:*,read:logs:*"
31+
```
32+
33+
### Option B: Using raw HTTP (admin API)
34+
35+
Admin auth is not part of the SDK. Use `aactl` or raw HTTP:
36+
37+
```bash
38+
# 1. Get admin token
39+
ADMIN_TOKEN=$(curl -s -X POST "http://localhost:8080/v1/admin/auth" \
40+
-H "Content-Type: application/json" \
41+
-d '{"secret": "your-admin-secret"}' | python3 -c "import sys,json; print(json.load(sys.stdin)['access_token'])")
42+
43+
# 2. Register app with the full ceiling
44+
curl -X POST "http://localhost:8080/v1/admin/apps" \
45+
-H "Content-Type: application/json" \
46+
-H "Authorization: Bearer $ADMIN_TOKEN" \
47+
-d '{
48+
"name": "sample-apps",
49+
"scopes": ["read:data:*","write:data:*","read:customers:*","write:orders:*","read:files:*","write:files:*","read:monitoring:*","send:webhooks:*","read:billing:*","write:notes:*","read:audit:all","delete:customers:*","read:logs:*"]
50+
}'
51+
```
52+
53+
Save the `client_id` and `client_secret` from the response. The `client_secret` is shown only once.
54+
55+
---
56+
57+
## Step 2: Set Environment Variables
58+
59+
```bash
60+
export AGENTAUTH_BROKER_URL="http://localhost:8080"
61+
export AGENTAUTH_CLIENT_ID="sample-apps"
62+
export AGENTAUTH_CLIENT_SECRET="your-client-secret"
63+
```
64+
65+
---
66+
67+
## Scope Ceiling Reference Per App
68+
69+
Each app requests specific scopes. The **app's ceiling** must cover them, or the broker rejects the agent creation.
70+
71+
### App 1: File Access Gate
72+
73+
```
74+
Ceiling needed: read:files:*, write:files:*
75+
Scopes requested by app: read:files:report-q3
76+
```
77+
78+
The app reads files `report-q3` and `audit-log`. The ceiling must include `read:files:*`.
79+
80+
### App 2: Customer API Gateway
81+
82+
```
83+
Ceiling needed: read:customers:*
84+
Scopes requested by app: read:customers:customer-42, read:customers:customer-99
85+
```
86+
87+
The app fetches customer records by ID. The ceiling must include `read:customers:*`.
88+
89+
### App 3: LLM Tool Executor
90+
91+
```
92+
Ceiling needed: read:customers:*, write:orders:*, delete:customers:*, read:audit:all
93+
Scopes requested by app: read:customers:customer-42, write:orders:customer-42
94+
(delete:customers:* and read:audit:all are intentionally not requested —
95+
this is what the app tests as denied)
96+
```
97+
98+
The app exercises scope enforcement. It needs `delete:customers:*` and `read:audit:all` in the ceiling **only to demonstrate denials** — the app intentionally does not request them, so the broker blocks them.
99+
100+
### App 4: Data Pipeline Runner
101+
102+
```
103+
Ceiling needed: read:data:*, write:data:*
104+
Scopes requested by app: read:data:source-batch-101, read:data:source-batch-102,
105+
write:data:dest-batch-101, write:data:dest-batch-102
106+
```
107+
108+
The pipeline reads from source partitions and writes to destination partitions. The ceiling must include `read:data:*` and `write:data:*`.
109+
110+
### App 5: Audit Log Reader
111+
112+
```
113+
Scope ceiling: N/A — no agent scopes needed
114+
What it uses: Admin auth only (aactl or raw HTTP admin API)
115+
POST /v1/admin/auth with AACTL_ADMIN_SECRET
116+
GET /v1/audit/events with admin Bearer token
117+
```
118+
119+
The SDK is not used. The app uses raw HTTP to authenticate as admin and read events. The SDK (`AgentAuthApp`) only handles app-level operations — it has no admin auth path.
120+
121+
### App 6: Token Lifecycle Manager
122+
123+
```
124+
Ceiling needed: read:data:*
125+
Scopes requested by app: read:data:sync-source
126+
```
127+
128+
The worker reads from a sync source. The ceiling must include `read:data:*`.
129+
130+
### App 7: Multi-Tenant Agent Factory
131+
132+
```
133+
Ceiling needed: read:data:*
134+
Scopes requested by app: read:data:invoices:{tenant_id}, read:data:reports:{tenant_id}
135+
(tenant IDs are substituted at runtime: acme-corp, globex)
136+
```
137+
138+
The factory substitutes tenant IDs at runtime. The ceiling must include `read:data:*` — the specific `{tenant_id}` identifiers are not in the ceiling.
139+
140+
### App 8: Webhook Dispatcher
141+
142+
```
143+
Ceiling needed: send:webhooks:*
144+
Scopes requested by app: send:webhooks:order-confirmation
145+
```
146+
147+
The app sends outbound webhooks. The ceiling must include `send:webhooks:*`.
148+
149+
### App 9: Scope Ceiling Guard
150+
151+
```
152+
Ceiling needed: read:data:test, read:data:*, write:data:*, admin:revoke:*, read:logs:*
153+
(intentionally includes out-of-bounds scopes for testing)
154+
Scopes requested by app: read:data:test — inside ceiling → should succeed
155+
admin:revoke:asterisk — outside ceiling → BLOCKED (403)
156+
read:logs:system — outside ceiling → BLOCKED (403)
157+
```
158+
159+
The purpose of this app is to demonstrate the broker blocking requests that exceed the ceiling. Without `admin:revoke:*` and `read:logs:*` in the ceiling, the app cannot show the blocking behavior.
160+
161+
### App 10: Renewal with Revocation Detection
162+
163+
```
164+
Ceiling needed: read:monitoring:*
165+
Scopes requested by app: read:monitoring:alerts
166+
```
167+
168+
The continuous agent reads monitoring alerts. The ceiling must include `read:monitoring:*`.
169+
170+
---
171+
172+
## Complete Ceiling for All Apps
173+
174+
To run every app without modification, register the app with this ceiling:
175+
176+
### aactl
177+
178+
```bash
179+
aactl app update sample-apps \
180+
--scopes "read:data:*,write:data:*,read:customers:*,write:orders:*,read:files:*,write:files:*,read:monitoring:*,send:webhooks:*,read:billing:*,write:notes:*,read:audit:all,delete:customers:*,read:logs:*"
181+
```
182+
183+
### HTTP
184+
185+
```bash
186+
curl -X POST "http://localhost:8080/v1/admin/apps/sample-apps" \
187+
-H "Authorization: Bearer $ADMIN_TOKEN" \
188+
-H "Content-Type: application/json" \
189+
-d '{
190+
"name": "sample-apps",
191+
"scopes": ["read:data:*","write:data:*","read:customers:*","write:orders:*","read:files:*","write:files:*","read:monitoring:*","send:webhooks:*","read:billing:*","write:notes:*","read:audit:all","delete:customers:*","read:logs:*"]
192+
}'
193+
```
194+
195+
---
196+
197+
## Broker Start Command
198+
199+
```bash
200+
AA_ADMIN_SECRET="your-admin-secret" \
201+
AA_DB_PATH="/tmp/agentauth.db" \
202+
AA_DEFAULT_TTL="300" \
203+
AA_MAX_TTL="600" \
204+
./broker
205+
```
206+
207+
| Flag | Purpose |
208+
|------|---------|
209+
| `AA_ADMIN_SECRET` | Admin password for operator tasks (app registration, revocation, audit) |
210+
| `AA_DB_PATH` | SQLite database path — audit log and revocation data |
211+
| `AA_DEFAULT_TTL` | Default agent token TTL in seconds (300 = 5 minutes) |
212+
| `AA_MAX_TTL` | Maximum TTL any token can be issued with (clamping ceiling) |
213+
214+
---
215+
216+
## Quick Verification
217+
218+
```bash
219+
# Broker is up
220+
curl http://localhost:8080/v1/health
221+
222+
# App auth works
223+
curl -X POST "http://localhost:8080/v1/app/auth" \
224+
-H "Content-Type: application/json" \
225+
-d '{"client_id": "sample-apps", "client_secret": "your-client-secret"}'
226+
# Returns: {"access_token": "...", "expires_in": 1800}
227+
228+
# List apps (admin)
229+
aactl app list
230+
```
231+
232+
---
233+
234+
## Troubleshooting
235+
236+
| Symptom | Cause | Fix |
237+
|--------|-------|-----|
238+
| `401` on app auth | Wrong `client_id` or `client_secret` | Re-register the app and save the credentials |
239+
| `403` on agent creation | Requested scope outside app ceiling | Extend the app ceiling with `aactl app update`, or narrow the requested scope |
240+
| `403` on admin auth | Wrong `AACTL_ADMIN_SECRET` | Restart the broker with the correct secret |
241+
| `Connection refused` | Broker not running | `./broker` or `docker compose up` |
242+
| App 5 returns empty events | Admin token expired | Re-run the aactl command or re-authenticate |
243+
| App 9 shows all `PASS` | Ceiling is too wide — all test scopes are allowed | Narrow the ceiling so `admin:revoke:*` and `read:logs:*` are outside it |

0 commit comments

Comments
 (0)