Configuration
Optio is configured through environment variables, Helm chart values, and per-repository settings in the dashboard. This page covers all three layers.
Environment Variables
These are set on the API server. In Kubernetes, they are configured via the Helm chart's api.env section or directly as environment variables on the deployment.
Core
| Variable | Default | Description |
|---|---|---|
| DATABASE_URL | (required) | PostgreSQL connection string |
| REDIS_URL | (required) | Redis connection string for BullMQ and pub/sub |
| OPTIO_ENCRYPTION_KEY | (required) | AES-256-GCM key for secret encryption (32-byte hex) |
| PUBLIC_URL | http://localhost:30400 | Public URL of the API server (used for OAuth callbacks) |
| PORT | 4000 | API server port |
Concurrency & Tuning
| Variable | Default | Description |
|---|---|---|
| OPTIO_MAX_CONCURRENT | 5 | Global maximum running tasks across all repos |
| OPTIO_REPO_POD_IDLE_MS | 600000 | Idle timeout for repo pods in milliseconds (10 min default) |
| OPTIO_PR_WATCH_INTERVAL | 30000 | PR polling interval in milliseconds |
| OPTIO_HEALTH_CHECK_INTERVAL | 60000 | Health check and cleanup interval in milliseconds |
| OPTIO_IMAGE_PULL_POLICY | IfNotPresent | Kubernetes image pull policy for agent pods (Never for local dev) |
Authentication
| Variable | Default | Description |
|---|---|---|
| OPTIO_AUTH_DISABLED | false | Disable all auth checks (local dev only) |
| GITHUB_OAUTH_CLIENT_ID | — | GitHub OAuth app client ID |
| GITHUB_OAUTH_CLIENT_SECRET | — | GitHub OAuth app client secret |
| GOOGLE_OAUTH_CLIENT_ID | — | Google OAuth client ID |
| GOOGLE_OAUTH_CLIENT_SECRET | — | Google OAuth client secret |
| GITLAB_OAUTH_CLIENT_ID | — | GitLab OAuth client ID |
| GITLAB_OAUTH_CLIENT_SECRET | — | GitLab OAuth client secret |
| GITLAB_OAUTH_BASE_URL | https://gitlab.com | Base URL for self-hosted GitLab |
Info
CLIENT_ID and CLIENT_SECRET. At least one provider is required for production deployments. Register the callback URL as {PUBLIC_URL}/api/auth/{provider}/callback.Helm Chart Values
The Helm chart at helm/optio/ deploys the full stack. Here are the key configuration sections.
Database & Redis
# Use built-in instances (dev only)
postgresql:
enabled: true
auth:
password: "optio_dev"
redis:
enabled: true
# Use external managed services (production)
postgresql:
enabled: false
externalDatabase:
url: "postgresql://user:pass@your-db:5432/optio"
redis:
enabled: false
externalRedis:
url: "redis://your-redis:6379"Encryption
# Generate a 32-byte hex key
openssl rand -hex 32encryption:
key: "your-64-character-hex-string-here"Warning
Agent Images
agent:
# For local dev (images loaded directly into K8s containerd)
imagePullPolicy: Never
# For production (images in a container registry)
imagePullPolicy: IfNotPresent
# or: AlwaysIngress
ingress:
enabled: true
hosts:
- host: optio.example.com
tls: trueServices
# Local dev (NodePort for direct access)
api:
service:
type: NodePort
nodePort: 30400
web:
service:
type: NodePort
nodePort: 30310
# Production (ClusterIP behind ingress)
api:
service:
type: ClusterIP
web:
service:
type: ClusterIPAuth
auth:
# Disable for local development
disabled: true
# Production: configure OAuth providers
github:
clientId: "your-client-id"
clientSecret: "your-client-secret"
google:
clientId: "your-client-id"
clientSecret: "your-client-secret"What the Chart Creates
- Namespace, ServiceAccount, and RBAC (pod/exec/secret management)
- API deployment + service with health probes
- Web deployment + service
- Conditional PostgreSQL and Redis deployments
- Configurable Ingress resource
Per-Repository Settings
Each connected repository has its own settings, configured in the dashboard under Repos → Settings.
General
| Setting | Default | Description |
|---|---|---|
| imagePreset | auto-detect | Agent image: node, python, go, rust, full |
| defaultBranch | main | Branch to create worktrees from |
| autoMerge | false | Auto-merge PRs when CI passes and review is approved |
| autoResume | true | Auto-resume agent when reviewer requests changes |
| maxConcurrentTasks | 2 | Max concurrent tasks in this repo |
| maxPodInstances | 1 | Max pod replicas for this repo (1-20) |
| maxAgentsPerPod | 2 | Max concurrent agents per pod (1-50) |
Claude Settings
| Setting | Default | Description |
|---|---|---|
| claudeModel | sonnet | Model for coding tasks (sonnet, opus, haiku) |
| claudeContextWindow | null | Context window override (null = model default) |
| claudeThinking | false | Enable extended thinking mode |
| claudeEffort | null | Effort level override |
| maxTurnsCoding | null | Max agent turns for coding tasks |
| maxTurnsReview | null | Max agent turns for review tasks |
| promptTemplateOverride | null | Custom prompt template for this repo |
Review Settings
| Setting | Default | Description |
|---|---|---|
| reviewEnabled | false | Enable automatic code review agent |
| reviewTrigger | on_ci_pass | When to trigger: on_ci_pass or on_pr |
| reviewModel | sonnet | Model to use for review (often a cheaper model) |
| reviewPromptTemplate | null | Custom review prompt template |
Prompt Templates
System prompts use a simple template language with variable substitution and conditionals.
Available Variables
| Variable | Description |
|---|---|
| {{TASK_FILE}} | Path to the task description markdown file |
| {{BRANCH_NAME}} | Git branch name for this task |
| {{TASK_ID}} | Unique task identifier |
| {{TASK_TITLE}} | Task title |
| {{REPO_NAME}} | Repository name (owner/repo) |
| {{AUTO_MERGE}} | Whether auto-merge is enabled |
| {{PR_NUMBER}} | PR number (review tasks only) |
| {{TEST_COMMAND}} | Detected test command (review tasks only) |
Conditionals
{{#if AUTO_MERGE}}
After CI passes, the PR will be auto-merged.
{{else}}
Wait for manual review before merging.
{{/if}}Priority Chain
Templates are resolved in order of specificity:
- Per-repo override (
repos.promptTemplateOverride) - Global default (
prompt_templatestable) - Hardcoded fallback in
@optio/shared
Review prompts follow the same chain: repos.reviewPromptTemplate → default review template.
Secrets
Secrets are managed in the dashboard under Secrets and are encrypted at rest with AES-256-GCM. Key secrets to configure:
CLAUDE_AUTH_MODE—api-keyoroauth-tokenANTHROPIC_API_KEY— Your API key (if using api-key mode)CLAUDE_CODE_OAUTH_TOKEN— OAuth token (if using oauth-token mode)GITHUB_TOKEN— GitHub personal access token for PR watching, issue sync, and repo detection
Tip