Octarq is configured entirely through environment variables — the canonical list
lives in .env.example.
The primary configuration options are:
Core
| Variable | Purpose |
|---|---|
OCTARQ_SECRET_KEY |
Signs session cookies and encrypts stored credentials. Required. Must be at least 16 bytes; once a domain is registered, this length floor is strictly enforced and the instance will refuse to start if shorter. |
OCTARQ_ADMIN_USER |
First admin username (default admin). |
OCTARQ_ADMIN_PASSWORD |
First admin password. Required. |
OCTARQ_ALLOW_PRIVATE_WEBHOOKS |
Allow webhook & notification delivery to private/loopback IPs. Default false. |
OCTARQ_ALLOW_PRIVATE_SMTP |
Allow outbound SMTP mail delivery to private/loopback IPs (e.g. local Postfix or Mailhog). Default false. |
OCTARQ_TRUST_PROXY |
Honour X-Forwarded-For / X-Real-IP / X-Forwarded-Proto. Enable only behind a reverse proxy you control. Default false. |
OCTARQ_LISTEN |
Address the binary binds (default :8080). |
OCTARQ_PORT |
Docker Compose only — the host port published by docker-compose.yml (default 8080), also the port knob for make dev. Not read by the binary; to change the binary’s own listen port use OCTARQ_LISTEN. |
OCTARQ_CORS_ORIGINS |
Comma-separated allowlist of exact origins (e.g. https://app.example.com) allowed to query public GET endpoints cross-origin. Empty = CORS disabled. Bootstrap fallback for runtime setting. |
Runtime Instance Settings (Dashboard)
Instance administrators can configure deployment-wide settings live via the UI (Settings → Instance / /instance/settings), without restarting the server:
| Setting Key | UI Label | Purpose |
|---|---|---|
app_name |
Product name | Brand/Product name displayed across the UI (empty = default octarq). |
base_domain |
Tenant base domain | Automatic tenant subdomain base (<slug>.<base>). |
shared_hosts |
Shared hosts | Trusted hostnames for public origin derivation. |
data_retention_days |
Keep click history for (days) | Auto-cleanup retention period for short link clicks (0 = keep forever). |
public_cors_origins |
Public CORS Origins | Comma/newline-separated allowlist of exact origins for public GET endpoints. |
mail_system_sender_id |
System SMTP Sender | SMTPSender ID used for system transactional mail (verification, password resets, invites). |
reserved_slugs |
Reserved Short Link Slugs | Slugs users are blocked from registering (built-ins like admin, api, assets, portal are always reserved). |
metrics_token |
Metrics token | Bearer token required for /metrics endpoint (empty = loopback only). |
ratelimit_auth_rpm |
Auth RPM / IP | Per-IP rate limit for authentication endpoints (default 60). |
ratelimit_api_rpm |
API RPM / IP | Per-IP rate limit for general API endpoints (default 600). |
ratelimit_redirect_rpm |
Redirect RPM / IP | Per-IP rate limit for short link redirects (default 6000). |
allow_registration |
Allow public sign-up | Controls public registration on login page (Settings → Authentication). |
require_email_verification |
Require Email Verification | Blocks login until user verifies email (Settings → Authentication). |
oauth.google.* / oauth.github.* |
Google / GitHub OAuth | Third-party social login client IDs and secrets (Settings → Authentication). |
Hostnames
There is nothing to configure. Absolute links — password reset, email
verification, workspace invites, OAuth redirect_uri — are built from the
hostname the request arrived on, and that hostname is accepted only when it
matches a domain registered under Domains. A hostname that matches none
produces relative links instead, so a forged Host header can never aim a
password-reset link at somebody else’s site.
An instance with no registered domain has nothing to check against and uses the request host as sent; register the domain you serve on to close that gap.
Hostname environment variables (optional)
Two optional bootstrap-fallback variables exist for shared / tenant-subdomain hosts. Both are read at startup only; once saved, the dashboard settings (Settings → Instance) take over:
| Variable | Purpose |
|---|---|
OCTARQ_SHARED_HOSTS |
Comma-separated hostnames the dashboard answers on. Required when tenant subdomains are in use: once any domain is registered, absolute links (password reset, invites) are only built for registered or declared hosts — without this the shared host builds no absolute URLs. |
OCTARQ_BASE_DOMAIN |
Shared tenant-subdomain base (bootstrap fallback): every new org gets <slug>.<base> automatically. Needs a wildcard DNS record and a wildcard TLS cert on the base, plus OCTARQ_SHARED_HOSTS declaring the base itself. |
Two things follow from the same request rather than from configuration:
- Where the dashboard is served. Every hostname serves
/admin, except one registered as a short-link or mail host — those exist for a workspace’s public traffic and do not show a login form. - The session cookie’s
Secureattribute. Set when the request arrived over HTTPS.X-Forwarded-Protocounts only withOCTARQ_TRUST_PROXYon.
OAuth operators: redirect_uri now varies by hostname, so every hostname
you offer social login on must be registered with the provider as
https://<host>/auth/callback/<provider>.
Database
octarq defaults to pure-Go SQLite (no cgo). Switch to PostgreSQL or MySQL 8 with two environment variables:
| Variable | Purpose |
|---|---|
OCTARQ_DB_DRIVER |
sqlite (default), postgres, or mysql. |
OCTARQ_DB_DSN |
Connection string when using Postgres (e.g. postgres://user:pass@localhost:5432/octarq?sslmode=disable) or MySQL 8 (e.g. user:pass@tcp(localhost:3306)/octarq?charset=utf8mb4&parseTime=True&loc=Local). |
OCTARQ_REDIS_URL |
Optional Redis connection (e.g. redis://localhost:6379) for rate limiting / caching. Empty = those features fall back to DB / in-memory. |
Email inbound
Inbound mail is delivered by the Cloudflare Email Worker
(deploy/cloudflare-email-worker.js).
It needs one variable — set on the Worker, not on octarq:
| Variable (Worker) | Purpose |
|---|---|
OCTARQ_ENDPOINT |
Your Inbound Webhook URL, copied from the octarq dashboard (Settings). It already embeds your org’s inbound token — no separate token variable. |
GeoIP (optional)
Geo data for click analytics. Easiest path: set a free MaxMind license key and octarq auto-downloads GeoLite2-City into its data dir, reusing the cached file on later starts.
| Variable | Purpose |
|---|---|
OCTARQ_MAXMIND_LICENSE_KEY |
Free MaxMind key — enables auto-download of GeoLite2-City. |
OCTARQ_GEOIP_DB |
Explicit path to an .mmdb file — takes precedence over the cached/downloaded one. Unset both = geo disabled. |
LLM (AI features)
The MCP server’s own tools need no LLM, but AI features (such as AI email summaries and AI assistance) can be configured via environment variables using your own provider key (BYOK):
| Variable | Purpose |
|---|---|
OCTARQ_LLM_PROVIDER |
claude, openai, gemini, mistral, cohere, or ollama. |
OCTARQ_LLM_API_KEY |
Your own provider key — octarq never marks up tokens (BYOK). |
:::tip
Defaults are claude-opus-4-8 for reasoning and claude-haiku-4-5 for cheap
classification. Switch vendor by name — no per-vendor code.
:::