Frona is configured through a YAML config file at data/config.yaml. You can change the path by setting the FRONA_CONFIG environment variable.
Environment variables with the FRONA_ prefix override values from the config file. For example, FRONA_SERVER_PORT=9999 overrides server.port in the YAML. See Configuration for the environment variable reference.
Server
General server settings.
server:
port: 3001
base_url: https://frona.example.com
backend_url: http://localhost:3001
frontend_url: http://localhost:3000
static_dir: /app/static
issuer_url: https://frona.example.com
max_concurrent_tasks: 10
sandbox_disabled: false
sandbox_max_agent_cpu_pct: 95.0
sandbox_max_agent_memory_pct: 80.0
sandbox_max_total_cpu_pct: 98.0
sandbox_max_total_memory_pct: 90.0
sandbox_timeout_secs: 0
sse_pending_events_secs: 60
cors_origins: https://app.example.com
max_body_size_bytes: 104857600
shutdown_timeout_secs: 60| Field | Type | Default | Description |
|---|---|---|---|
port | integer | 3001 | HTTP server port |
base_url | string | -- | Public-facing base URL, used for callbacks and links |
backend_url | string | -- | Override backend API URL |
frontend_url | string | -- | Override frontend URL |
static_dir | string | /app/static | Directory serving the frontend static files |
issuer_url | string | -- | JWT token issuer URL |
max_concurrent_tasks | integer | 10 | Maximum concurrent background tasks across all agents |
sandbox_disabled | boolean | false | Disable CLI/Python/Node.js sandboxing. Not recommended for production |
sandbox_max_agent_cpu_pct | float | 95.0 | Maximum CPU percentage a single agent can use |
sandbox_max_agent_memory_pct | float | 80.0 | Maximum memory percentage a single agent can use |
sandbox_max_total_cpu_pct | float | 98.0 | Maximum total CPU percentage all agents can use |
sandbox_max_total_memory_pct | float | 90.0 | Maximum total memory percentage all agents can use |
sandbox_timeout_secs | integer | 0 | Global sandbox execution timeout. 0 means no timeout |
sse_pending_events_secs | integer | 60 | How long to buffer SSE events after client disconnects |
cors_origins | string | -- | Allowed CORS origins |
max_body_size_bytes | integer | 104857600 (100 MB) | Maximum HTTP request body size |
shutdown_timeout_secs | integer | 60 | Graceful shutdown timeout |
Auth
Authentication and token settings.
auth:
encryption_secret: change-this-in-production
access_token_expiry_secs: 900
refresh_token_expiry_secs: 604800
presign_expiry_secs: 86400| Field | Type | Default | Description |
|---|---|---|---|
encryption_secret | string | dev-secret-change-in-production | Secret used to derive the AES-256 key that encrypts JWT signing keypairs at rest. Must be changed in production |
access_token_expiry_secs | integer | 900 (15 min) | How long access tokens are valid |
refresh_token_expiry_secs | integer | 604800 (7 days) | How long refresh tokens are valid |
presign_expiry_secs | integer | 86400 (24 hours) | How long pre-signed URLs are valid |
:::caution[Change the encryption secret in production] encryption_secret is used to derive an AES-256 encryption key (via SHA-256) that protects the JWT signing keypairs stored in the database. It is not used directly for JWT signing — instead it encrypts the private keys that do the signing.
A built-in default is provided for local development, but you must set your own value in production. If the default is left in place and database files are ever exposed (backup leak, file traversal, shared host), an attacker could decrypt the signing keypairs and forge authentication tokens for any user.
Generate a strong random secret:
openssl rand -base64 32:::
SSO
OpenID Connect single sign-on. Disabled by default.
sso:
enabled: true
authority: https://auth.example.com
client_id: your-client-id
client_secret: your-client-secret
scopes: openid email
disable_local_auth: false
signups_match_email: true
allow_unknown_email_verification: true
client_cache_expiration: 0| Field | Type | Default | Description |
|---|---|---|---|
enabled | boolean | false | Enable OIDC authentication |
authority | string | -- | OpenID Connect authority URL |
client_id | string | -- | OAuth client ID |
client_secret | string | -- | OAuth client secret |
scopes | string | openid email | OpenID scopes to request |
disable_local_auth | boolean | false | Force SSO-only authentication. Disables local login |
signups_match_email | boolean | true | Match SSO signups to existing accounts by email |
allow_unknown_email_verification | boolean | true | Accept emails not verified by the identity provider |
client_cache_expiration | integer | 0 | Client metadata cache expiration in seconds |
Database
database:
path: data/db| Field | Type | Default | Description |
|---|---|---|---|
path | string | data/db | Path to the SurrealDB data directory |
Browser
Headless Chrome configuration for browser automation. Optional. If not configured, browser tools are unavailable.
browser:
ws_url: ws://browserless:3333
profiles_path: /profiles
connection_timeout_ms: 30000
api_token: your-browserless-token| Field | Type | Default | Description |
|---|---|---|---|
ws_url | string | -- | WebSocket URL of the Browserless instance |
profiles_path | string | /profiles | Directory for storing browser profiles |
connection_timeout_ms | integer | 30000 (30s) | Timeout for connecting to the browser service |
api_token | string | -- | Authentication token for the Browserless HTTP API |
Search
Web search provider configuration. Optional. If not configured, search tools are unavailable.
search:
provider: searxng
searxng_base_url: http://searxng:8080| Field | Type | Default | Description |
|---|---|---|---|
provider | string | -- | Search provider: searxng, tavily, or brave |
searxng_base_url | string | -- | Base URL of the SearXNG instance |
Vault
External vault provider configuration. Credentials set here create system-managed vault connections that sync automatically on startup. See Vault Providers for details.
vault:
onepassword_service_account_token: ops_...
onepassword_vault_id: abc123
bitwarden_client_id: user.xxx
bitwarden_client_secret: xxx
bitwarden_master_password: xxx
bitwarden_server_url: https://vault.example.com
hashicorp_address: http://localhost:8200
hashicorp_token: hvs.xxx
hashicorp_mount: secret
keepass_path: /path/to/vault.kdbx
keepass_password: xxx
keeper_app_key: xxx| Field | Type | Default | Description |
|---|---|---|---|
onepassword_service_account_token | string | -- | 1Password service account token |
onepassword_vault_id | string | -- | 1Password default vault ID |
bitwarden_client_id | string | -- | Bitwarden personal API key client ID |
bitwarden_client_secret | string | -- | Bitwarden personal API key client secret |
bitwarden_master_password | string | -- | Bitwarden master password |
bitwarden_server_url | string | -- | Bitwarden server URL (for self-hosted) |
hashicorp_address | string | -- | HashiCorp Vault server address |
hashicorp_token | string | -- | HashiCorp Vault auth token |
hashicorp_mount | string | secret | HashiCorp Vault KV2 mount path |
keepass_path | string | -- | Path to KeePass .kdbx file |
keepass_password | string | -- | KeePass master password |
keeper_app_key | string | -- | Keeper Secrets Manager app key |
Storage
File storage paths.
storage:
workspaces_path: data/workspaces
files_path: data/files
shared_config_dir: resources
skills_dir: data/skills
cache_dir: data/system/cache| Field | Type | Default | Description |
|---|---|---|---|
workspaces_path | string | data/workspaces | Directory for agent workspace files |
files_path | string | data/files | Directory for file uploads and attachments |
shared_config_dir | string | resources | Directory containing shared prompts and agent configurations |
skills_dir | string | data/skills | Directory for installed shared skills |
cache_dir | string | data/system/cache | Directory for system caches (skill registry, etc.) |
Scheduler
Background job intervals.
scheduler:
poll_secs: 60
space_compaction_secs: 3600
memory_compaction_secs: 7200| Field | Type | Default | Description |
|---|---|---|---|
poll_secs | integer | 60 (1 min) | How often the scheduler checks for due tasks |
space_compaction_secs | integer | 3600 (1 hour) | Interval for space context compaction |
memory_compaction_secs | integer | 7200 (2 hours) | Interval for memory compaction |
Inference
LLM inference settings.
inference:
max_tool_turns: 200
default_max_tokens: 8192
compaction_trigger_pct: 80
history_truncation_pct: 90| Field | Type | Default | Description |
|---|---|---|---|
max_tool_turns | integer | 200 | Maximum tool call iterations per agent response |
default_max_tokens | integer | 8192 | Default max tokens for LLM responses |
compaction_trigger_pct | integer | 80 | Context usage percentage that triggers message compaction |
history_truncation_pct | integer | 90 | Context usage percentage that triggers history truncation |
Voice
Twilio voice call configuration. Optional. If not configured, voice tools are unavailable.
voice:
provider: twilio
twilio_account_sid: your-account-sid
twilio_auth_token: your-auth-token
twilio_from_number: "+15551234567"
twilio_voice_id: Polly.Matthew
twilio_speech_model: enhanced
callback_base_url: https://frona.example.com| Field | Type | Default | Description |
|---|---|---|---|
provider | string | -- | Voice provider. Currently only twilio is supported |
twilio_account_sid | string | -- | Twilio account SID |
twilio_auth_token | string | -- | Twilio auth token |
twilio_from_number | string | -- | Twilio phone number for outbound calls (E.164 format) |
twilio_voice_id | string | -- | Twilio voice ID for text-to-speech |
twilio_speech_model | string | -- | Twilio speech recognition model |
callback_base_url | string | -- | Public URL for Twilio callbacks. Overrides server.base_url for voice |
Providers
LLM provider API keys and endpoints. Providers can also be auto-discovered from environment variables (e.g., ANTHROPIC_API_KEY, OPENAI_API_KEY).
providers:
anthropic:
api_key: sk-ant-...
enabled: true
openai:
api_key: sk-...
enabled: true
ollama:
base_url: http://localhost:11434/v1
enabled: true| Field | Type | Default | Description |
|---|---|---|---|
api_key | string | -- | API key for the provider |
base_url | string | -- | Custom base URL (for self-hosted models like Ollama) |
enabled | boolean | true | Whether this provider is active |
Supported providers: anthropic, openai, groq, openrouter, deepseek, gemini, cohere, mistral, perplexity, together, xai, hyperbolic, moonshot, mira, galadriel, huggingface, ollama.
Models
Model groups define which LLM an agent uses. Each group is tagged with a provider and has a primary model, optional fallbacks, and provider-specific parameters.
Model groups cannot be set via environment variables. They must be configured in the config file.
Common fields
These fields are available for all providers:
| Field | Type | Default | Description |
|---|---|---|---|
provider | string | required | Provider name (see below) |
model | string | required | Model ID (without provider prefix) |
fallbacks | list | [] | Fallback model groups tried in order if the primary fails |
max_tokens | integer | -- | Maximum tokens to generate per response |
temperature | float | -- | Sampling temperature (0.0-2.0) |
context_window | integer | -- | Override context window size |
retry.max_retries | integer | 10 | Maximum retry attempts on failure |
retry.initial_backoff_ms | integer | 1000 (1s) | Initial backoff between retries |
retry.backoff_multiplier | float | 2.0 | Exponential backoff multiplier |
retry.max_backoff_ms | integer | 60000 (60s) | Maximum backoff duration |
Anthropic
models:
primary:
provider: anthropic
model: claude-sonnet-4-5-20250514
max_tokens: 8192
thinking:
type: enabled
budget_tokens: 10000
top_p: 0.9
top_k: 40Additional fields: thinking (with type and budget_tokens), top_p, top_k, stop_sequences.
OpenAI, Groq, OpenRouter, DeepSeek, xAI, Together, Hyperbolic
These providers share the same parameter set:
models:
coding:
provider: openai
model: gpt-4o
max_tokens: 8192
top_p: 0.9
reasoning_effort: highAdditional fields: top_p, min_p, frequency_penalty, presence_penalty, seed, max_completion_tokens, reasoning_effort, logprobs, top_logprobs, stop.
Gemini
models:
reasoning:
provider: gemini
model: gemini-2.5-pro
thinking_config:
thinking_budget: 10000
include_thoughts: trueAdditional fields: thinking_config (with thinking_budget and include_thoughts), top_p, top_k, stop_sequences, candidate_count.
Ollama
models:
local:
provider: ollama
model: llama3.1
num_ctx: 8192
num_predict: 4096Additional fields: think, num_ctx, num_predict, num_batch, num_keep, num_thread, num_gpu, top_k, top_p, min_p, repeat_penalty, repeat_last_n, frequency_penalty, presence_penalty, mirostat, mirostat_eta, mirostat_tau, tfs_z, seed, stop, use_mmap, use_mlock.
Generic
For any other provider. Only common fields are available.
models:
custom:
provider: generic
model: my-modelApps
Settings for agent-deployed applications.
app:
port_range_start: 4000
port_range_end: 4100
health_check_timeout_secs: 30
max_restart_attempts: 2
hibernate_after_secs: 259200| Field | Type | Default | Description |
|---|---|---|---|
port_range_start | integer | 4000 | Start of the port range for app allocation |
port_range_end | integer | 4100 | End of the port range for app allocation |
health_check_timeout_secs | integer | 30 | Maximum time to wait for an app to become healthy during deployment |
max_restart_attempts | integer | 2 | How many times to restart a crashed app before marking it as failed |
hibernate_after_secs | integer | 259200 (3 days) | Inactivity duration before auto-hibernating an app |
Cache
Entity caching settings.
cache:
entity_ttl_secs: 300
entity_max_capacity: 1000| Field | Type | Default | Description |
|---|---|---|---|
entity_ttl_secs | integer | 300 (5 min) | Time-to-live for cached entities |
entity_max_capacity | integer | 1000 | Maximum number of cached entities |
Sensitive values
These fields are automatically redacted in logs: auth.encryption_secret, sso.client_secret, voice.twilio_account_sid, voice.twilio_auth_token, all vault.* credential fields, and all providers[*].api_key values.