1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# ADR 005: Agent API Authentication Architecture
## Status
Accepted
## Context
External agents (CLI tools, automation scripts, AI assistants) need secure access to dashboard context without exposing user credentials. Traditional approaches have weaknesses:
- **API Keys**: Long-lived, often stored insecurely, difficult to revoke
- **OAuth2**: Complex setup, overkill for personal dashboard
- **SSH Keys**: Key management burden on user
Requirements:
- User awareness of agent access (no hidden API keys)
- Easy revocation (deny re-auth requests)
- Time-limited sessions to reduce exposure
- Support for both CLI and browser-based agents
## Decision
Implement **notification-based approval flow** with ephemeral sessions.
### Technical Details:
**Identity Model:**
- Agents identified by `name` + `agent_id` (UUID) pair
- Binding persisted on first approval
- Impersonation detected if name/agent_id mismatch
**Trust Levels:**
- `TRUSTED`: Previously approved, auto-approve on re-auth
- `UNKNOWN`: New agent, requires user approval
- `BLOCKED`: Denied agent, reject immediately
**Session Model:**
- 1-hour TTL tokens
- One active session per agent_id
- Session token in Authorization header
**Approval Flow:**
```
Agent Dashboard Browser
| | |
|-- POST /auth/request --> | |
| |-- WebSocket push ----> |
| | | (user sees modal)
| | |
|<-- request_token --------| |
| | |
|-- GET /auth/poll ------> | |
| (polling) | |
| | <-- POST /approve ---- |
| | |
|<-- session_token --------| |
| | |
|-- GET /context --------> | |
| (with session_token) | |
```
**Implementation:**
- `internal/handlers/agent.go` - Auth flow handlers (615 LOC)
- `internal/handlers/websocket.go` - Real-time notifications (216 LOC)
- `migrations/010_agent_tables.sql` - Storage schema
- `web/static/js/app.js` - Browser UI for approval modal
**Rate Limiting:**
- 10 requests/minute per IP on auth endpoints
- Prevents brute-force token guessing
## Consequences
**Pros:**
- User-visible agent access (approval modal shows agent name)
- Easy revocation by denying re-auth or blocking agent
- Trust level caching reduces approval fatigue for known agents
- Time-limited sessions reduce credential exposure
- Works for both CLI agents (polling) and browser agents (web endpoints)
**Cons:**
- Requires browser window open for first-time approval
- Poll loop adds latency to auth flow (~1-5 seconds)
- Session expiry interrupts long-running agent tasks (must re-auth)
## Alternatives Considered
**Option A: Traditional API Keys**
- Rejected: Long-lived credentials, no user awareness of access
**Option B: OAuth2 Device Flow**
- Rejected: Complex implementation, requires external auth server setup
**Option C: SSH-style Key Pairs**
- Rejected: Key management burden, harder to revoke
**Option D: Magic Links (email-based)**
- Rejected: Adds email dependency, slower approval flow
|