Security Guide
Toban is designed with security as a core principle. This guide explains the security model, isolation mechanisms, and best practices for running AI agents safely on your codebase.
Security Model Overview
Toban enforces security at multiple layers:
- Authentication -- GitHub OAuth for users, workspace-scoped API keys for CLI
- CSRF protection -- Token-based CSRF defense on all dashboard API calls
- Agent isolation -- Each agent runs in its own git worktree
- Role boundaries -- Agents can only perform role-appropriate actions
- Input validation -- All data validated and sanitized via Zod schemas
- Workspace-scoped access -- API keys and data are isolated per workspace
Authentication
GitHub OAuth Flow
- User clicks "Sign in with GitHub" on the dashboard
- Browser redirects to GitHub's authorization page
- User approves, GitHub redirects back with an authorization code
- The API exchanges the code for an access token
- The API creates a session and sets a secure HTTP-only cookie
- Subsequent dashboard requests include the session cookie
The session cookie is HTTP-only and secure (HTTPS-only in production). The dashboard never has direct access to the GitHub token.
CSRF Protection
All state-changing requests from the dashboard include a CSRF token:
- The dashboard fetches a CSRF token from the API on page load
- The token is included in a custom header on every POST/PUT/PATCH/DELETE request
- The API validates the token against the session before processing the request
The API proxy route (/api/proxy/[...path]) handles CSRF token injection automatically.
API Key Authentication
CLI and programmatic access uses Bearer tokens in the format tb_ws{workspace_id}_sk_{secret}:
- Each key is scoped to a single Project (workspace)
- Keys cannot access data from other Projects
- User session keys are auto-generated on login and expire after 7 days of inactivity (sliding window)
- Agent keys (used by the CLI) expire after 24 hours of inactivity (sliding window extends on use)
Agent Sandboxing
Git Worktree Isolation
Every agent task runs in an isolated git worktree:
your-repo/
├── src/ <-- Your working directory (untouched)
└── .worktrees/
└── builder-task-123/ <-- Agent's isolated copy
├── src/
└── ...
This means:
- Agents cannot modify your working directory directly
- Each agent has its own branch and working copy
- Failed or rejected work is discarded without affecting your code
- Multiple agents can work simultaneously without conflicts
Branch Isolation
Each agent creates a dedicated branch:
agent/builder-task-123
agent/cloud-eng-task-456
Completed work is merged back to the base branch with --no-ff (no fast-forward), preserving a clear merge history.
Automatic Cleanup
When an agent finishes (or fails), its worktree is automatically cleaned up. No stale branches or orphaned directories are left behind.
Manager Permission Mode
The Manager agent (which coordinates sprints and responds to chat) runs with restricted permissions. When using the Claude Code CLI engine, the Manager is launched with --permission-mode plan, which limits its ability to execute arbitrary tools. The Manager can analyze and plan but relies on ACTION blocks to request changes, which require user approval. Other engines may have different permission models.
Task Auto-Start
When the CLI is connected, tasks assigned to agent roles (builder, cloud-engineer, etc.) are automatically picked up and executed. Tasks assigned to user are never auto-started. To prevent agents from working on a task, set its owner to user before connecting the CLI.
Note: Auto-start is the recommended workflow for fast iteration. A manual approval mode (approve/reject before each agent starts) will be available as an opt-in setting in a future release.
Credential Management
GitHub App Installation Tokens
Toban uses a git credential helper that fetches fresh GitHub App installation tokens on demand:
- At CLI startup, a shell script is written to
~/.toban/git-credential-helper.sh(mode0700, owner-only executable) - The script calls
GET /api/v1/workspace/git-tokenwith the workspace API key - The API returns a short-lived GitHub App installation token (1 hour expiry)
- Git invokes this helper automatically on push/pull operations
This avoids:
- Storing long-lived tokens on disk
- Embedding tokens in git remote URLs (which are visible in
.git/config) - Token expiry issues during long-running agent tasks
After initial clone, any embedded tokens in remote URLs are cleaned and replaced with plain https://github.com/... URLs.
Role Boundaries
Each agent role has strictly defined capabilities enforced in the system prompt:
| Role | Can Do | Cannot Do |
|---|---|---|
| Manager | Coordinate sprints, propose tasks, review backlog | Write code directly |
| Builder | Write code, run tests, commit changes | Modify infrastructure |
If an agent is asked to perform work outside its role, the prompt instructs it to refuse and suggest the appropriate agent.
Input Validation
All data entering the system is validated with Zod schemas:
| Context | Max Length | Validation |
|---|---|---|
| Project spec | 10 KB | HTML sanitized |
| Task description | 2 KB | HTML sanitized |
| Message content | 2 KB | HTML sanitized |
| Agent name | 64 chars | Alphanumeric + hyphens only |
HTML Sanitization
All user input is sanitized to remove:
<script>tags<iframe>and<embed>tags- Event handlers (
onclick,onerror, etc.) javascript:URLs- Other XSS vectors
API Key Security
Best Practices
- Rotate keys regularly -- Create new keys and revoke old ones
- Use environment variables -- Never hardcode keys in source code
- Limit distribution -- Only share keys with team members who need CLI access
- Store keys in your shell profile or a secrets manager, not in version control
Rate Limiting
The API enforces rate limits to prevent abuse:
| Endpoint Type | Limit |
|---|---|
| Auth endpoints | 60 requests/minute |
| API endpoints | 600 requests/minute |
| Write operations (per workspace + IP) | 60/minute |
Audit Logging
Security-relevant events are logged:
- API key creation and revocation
- Agent spawning and termination
- Task status changes
- Authentication events
Access audit logs from the dashboard or via GET /api/v1/audit-logs.
Reporting Security Issues
If you discover a security vulnerability in Toban, please report it responsibly:
- Do not open a public GitHub issue
- Use GitHub Security Advisories to submit a private report
- Or contact us via X DM (@recuupfeg)
- Include steps to reproduce and potential impact
We aim to acknowledge reports within 48 hours and provide fixes within 7 days for critical issues.
Data Storage and Privacy
What Toban Stores
- Project metadata: Project name, description, spec, language, workflow settings
- Task data: Titles, descriptions, status, review comments, story points
- Agent activity: Status, last seen timestamps, progress logs
- Messages: Chat messages between users and the Manager agent
- Knowledge and ADRs: Shared knowledge and architecture decisions
- GitHub metadata: GitHub username, avatar URL, org name, installation ID
What Toban Does NOT Store
- Your source code: Agents run on your local machine via the CLI. Code is cloned locally, not uploaded to Toban servers.
- Git diffs or file contents: Review comments contain summaries, not raw code.
- Anthropic API keys: Your Claude Code authentication stays on your machine.
Where Data Is Stored
All data is stored in Cloudflare D1 (SQLite at the edge) and Cloudflare R2 (for workspace exports). Data is replicated across Cloudflare's global network.
Data Deletion
When you delete a Project, all associated data (tasks, sprints, agents, messages, knowledge, ADRs, audit logs) is permanently deleted. This is a hard delete with no recovery — use the workspace export feature to back up data before deletion.