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

VariableDefaultDescription
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_URLhttp://localhost:30400Public URL of the API server (used for OAuth callbacks)
PORT4000API server port

Concurrency & Tuning

VariableDefaultDescription
OPTIO_MAX_CONCURRENT5Global maximum running tasks across all repos
OPTIO_REPO_POD_IDLE_MS600000Idle timeout for repo pods in milliseconds (10 min default)
OPTIO_PR_WATCH_INTERVAL30000PR polling interval in milliseconds
OPTIO_HEALTH_CHECK_INTERVAL60000Health check and cleanup interval in milliseconds
OPTIO_IMAGE_PULL_POLICYIfNotPresentKubernetes image pull policy for agent pods (Never for local dev)

Authentication

VariableDefaultDescription
OPTIO_AUTH_DISABLEDfalseDisable all auth checks (local dev only)
GITHUB_OAUTH_CLIENT_IDGitHub OAuth app client ID
GITHUB_OAUTH_CLIENT_SECRETGitHub OAuth app client secret
GOOGLE_OAUTH_CLIENT_IDGoogle OAuth client ID
GOOGLE_OAUTH_CLIENT_SECRETGoogle OAuth client secret
GITLAB_OAUTH_CLIENT_IDGitLab OAuth client ID
GITLAB_OAUTH_CLIENT_SECRETGitLab OAuth client secret
GITLAB_OAUTH_BASE_URLhttps://gitlab.comBase URL for self-hosted GitLab

Info

Enable an OAuth provider by setting both its 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

values.yaml
# 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

terminal
# Generate a 32-byte hex key
openssl rand -hex 32
values.yaml
encryption:
  key: "your-64-character-hex-string-here"

Warning

The encryption key is required and is used for AES-256-GCM encryption of all secrets stored in the database. Losing this key means losing access to all stored secrets.

Agent Images

values.yaml
agent:
  # For local dev (images loaded directly into K8s containerd)
  imagePullPolicy: Never

  # For production (images in a container registry)
  imagePullPolicy: IfNotPresent
  # or: Always

Ingress

values.yaml
ingress:
  enabled: true
  hosts:
    - host: optio.example.com
  tls: true

Services

values.yaml
# 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: ClusterIP

Auth

values.yaml
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

SettingDefaultDescription
imagePresetauto-detectAgent image: node, python, go, rust, full
defaultBranchmainBranch to create worktrees from
autoMergefalseAuto-merge PRs when CI passes and review is approved
autoResumetrueAuto-resume agent when reviewer requests changes
maxConcurrentTasks2Max concurrent tasks in this repo
maxPodInstances1Max pod replicas for this repo (1-20)
maxAgentsPerPod2Max concurrent agents per pod (1-50)

Claude Settings

SettingDefaultDescription
claudeModelsonnetModel for coding tasks (sonnet, opus, haiku)
claudeContextWindownullContext window override (null = model default)
claudeThinkingfalseEnable extended thinking mode
claudeEffortnullEffort level override
maxTurnsCodingnullMax agent turns for coding tasks
maxTurnsReviewnullMax agent turns for review tasks
promptTemplateOverridenullCustom prompt template for this repo

Review Settings

SettingDefaultDescription
reviewEnabledfalseEnable automatic code review agent
reviewTriggeron_ci_passWhen to trigger: on_ci_pass or on_pr
reviewModelsonnetModel to use for review (often a cheaper model)
reviewPromptTemplatenullCustom review prompt template

Prompt Templates

System prompts use a simple template language with variable substitution and conditionals.

Available Variables

VariableDescription
{{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

prompt template
{{#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:

  1. Per-repo override (repos.promptTemplateOverride)
  2. Global default (prompt_templates table)
  3. 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-key or oauth-token
  • ANTHROPIC_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

Secret values are never logged or returned via the API. Only secret names and scopes are visible in the dashboard.

Next Steps