The problem: AI does actions
Traditional AI = chatbot. Answers questions. Does no actions.
Adam is different. Adam = agent. It can:
- read files
- run shell commands
- browse websites
- modify databases
- send emails
The action surface = the largest attack surface.
The Permission Manager
Every action, before it executes, passes through the Permission Manager:
action.requested → permission.check → {allow, deny, ask}
19 categories, 3 modes per category:
The 19 categories
- file.read — read files
- file.write — write files
- file.delete — delete files
- shell.safe — safe commands (ls, cat, pwd)
- shell.network — network commands (curl, wget)
- shell.dangerous — dangerous commands (rm, dd, mkfs)
- browser.read — read pages
- browser.write — write in pages (forms, comments)
- browser.submit — submit forms
- email.read — read emails
- email.send — send emails
- email.draft — create draft without sending
- database.read — read from database
- database.write — write in database
- database.delete — delete from database
- api.call.external — calling external APIs
- api.call.internal — calling internal APIs
- mcp.execute — execute MCP server
- subagent.spawn — spawn subagent
The 3 modes
Each category can be set by the client to one of:
- auto-allow: execute without asking
- once: ask once per session
- always-ask: ask every time
The default configuration
On install, the default:
| Category | Default mode |
|----------|--------------|
| file.read | auto-allow |
| file.write | once |
| file.delete | always-ask |
| shell.safe | auto-allow |
| shell.network | always-ask |
| shell.dangerous | always-ask |
| email.send | always-ask |
| database.delete | always-ask |
| subagent.spawn | once |
Client can adjust. But default is conservative.
A real example
User: 'delete all the old logs'
Permission check:
action: file.delete (in /var/log/)
category: file.delete
mode: always-ask
→ ASK USER
Adam: 'Do you really want to delete /var/log/?'
options: ['Yes, delete', 'No, stop', 'Show me the contents first']
Audit log
Every action, allowed or denied, is logged to:
/audit/2026-07-05.jsonl
{
"timestamp": "2026-07-05T14:23:18Z",
"user": "[email protected]",
"action": "file.delete",
"path": "/var/log/old.log",
"result": "allowed",
"session_id": "abc123"
}
The audit log:
- Append-only (cannot be modified)
- Cryptographically signed
- Queryable via API
- Exportable for compliance
Engineering decisions
Why 19, not 50?
Every category = code + test + documentation. 50 = burden on the user. 19 = enough granularity for 95% of use cases.
Why 3 modes, not 5?
- auto-allow / always-deny = binary
- once / always-ask = session-level granularity
- 5 modes = feature creep
Why default conservative?
Default insecure = bad UX (on first bug, company loses data). Default conservative = slow but safe. Client can open up. Cannot close down if the key is lost.
The Permission Manager as an engineering choice
19 × 3 = 57 configuration options. May seem like a lot. But it's:
- Single source of truth
- Version controlled
- Auditable
- Default safe
The Permission Manager is not a feature — it's the contract between humans and AI.



