Skip to content

Configuration

Alga is configured via environment variables. The canonical reference is apps/backend/.env.example — copy it to apps/backend/.env and fill in the values. A YAML config file (CONFIG_PATH) is also supported for non-route settings; environment variables always override the YAML file, and the YAML file overrides built-in defaults.

setup.sh generates .env files with random secrets for local Docker Compose. Use it for a fast start:

sh
./setup.sh && docker compose up -d

The default values below come from Defaults() in apps/backend/config/config.go. Duration values use Go duration syntax (30s, 10m, 12h, 168h). Boolean values accept true/false (and other strconv.ParseBool forms).

Precedence: .env Overrides the Inherited Environment

The backend loads .env files with godotenv.Overload semantics: for every key present in apps/backend/.env (or the repo-root .env), the file value replaces any same-named variable inherited from your shell, container environment, or secret provider. This is the reverse of common dotenv conventions — exporting a variable has no effect while the same key exists in a loaded .env. To let an environment-provided value win (container environment: blocks, systemd units, secret managers), delete or comment out that key in .env.

Full resolution order (lowest to highest): built-in defaults → YAML config file (CONFIG_PATH) → environment variables (with .env overriding inherited environment per above) → System Configuration API for its supported keys.

General

VariableDefaultRequiredDescription
PORT8080NoBackend HTTP listen port
LOG_LEVELinfoNoLog level: debug, info, warn, error
LOG_FILENoPath to log file output. Empty logs to stdout
LOG_FORMATtextNoLog output format: text (human-readable) or json (structured)
ENVIRONMENTNoSet to production (or prod) to enforce production checks (secure cookies). Crypto config is required in all environments, not only production
CONFIG_PATH./config/config.yamlNoOptional YAML config file path for non-route settings
ALGA_BASE_URLNoBase URL used for incident channel links and outbound references

Admin Bootstrap

On first boot with no users in the database, the frontend redirects to /setup where the operator creates the initial admin account (email, password, and full name) via the setup wizard. The setup wizard is only available when no users exist — once an admin exists, it is disabled.

To reset a user's password later, use the CLI: alga user reset-password <email> (see CLI reference).

Session & Cookies

VariableDefaultRequiredDescription
SESSION_EXPIRY_HOURS24NoSliding (idle) session expiry, in hours
SESSION_MAX_LIFETIME12hNoAbsolute max session lifetime, enforced in addition to idle expiry (ASVS V3.2/V3.3)
SECURE_COOKIESfalseNoSet the Secure flag on cookies. Auto-enabled when ENVIRONMENT=production and HSTS is emitted on HTTPS regardless

HTTP Server Hardening

All have safe defaults; override only to tune for your deployment.

VariableDefaultDescription
SERVER_READ_HEADER_TIMEOUT10sMax duration reading request headers (neutralizes slowloris)
SERVER_READ_TIMEOUT30sMax duration reading the full request (headers + body)
SERVER_WRITE_TIMEOUT30sMax duration writing the response. SSE handlers clear their own write deadline
SERVER_IDLE_TIMEOUT120sMax idle time for keep-alive connections
SERVER_MAX_HEADER_BYTES1048576Max request header size in bytes (1 MiB)

PostgreSQL

VariableDefaultRequiredDescription
POSTGRES_DSNYesPostgreSQL connection string (e.g. postgres://user:pass@localhost:5432/alga?sslmode=disable). Production must use sslmode=require or verify-full
POSTGRES_AUTO_MIGRATEfalseNoRun goose migrations on startup (enabled in Docker Compose)

Cryptography

Fail-closed — required in every environment

ENCRYPTION_KEYS and SECRET_PEPPER are required at startup in all environments, not only production. If either is missing or invalid, the server refuses to start (ASVS V2.1/V6.2).

VariableDefaultRequiredDescription
ENCRYPTION_KEYSYesComma-separated kid:base64(32B) pairs for AES-256-GCM envelope encryption. The highest kid seals new ciphertexts; lower kids decrypt historical data. Generate keys with openssl rand -base64 32 (e.g. 1:<base64>,2:<base64>)
SECRET_PEPPERYesBase64-encoded HMAC pepper (must decode to >= 32 bytes) for password pre-hashing and token hashing. Generate with openssl rand -base64 32

setup.sh generates keys

setup.sh appends a generated ENCRYPTION_KEYS value in the 1:<base64> form above, plus SECRET_PEPPER, to apps/backend/.env.

Envelope format

Ciphertext is stored as enc:v<kid>:base64(12B nonce || AES-256-GCM ciphertext+tag) — e.g. enc:v1:…. The kid picks the HMAC pepper for SECRET_PEPPER-derived token hashes (hex(64) with a 12-hex lookup_prefix for indexed prefix scans) and the Argon2id peppered pre-hash: password bytes are HMAC-SHA-256 with SECRET_PEPPER before Argon2id. cfg.Validate() rejects the process unless both values are present and well-formed — fail-closed in every environment, not only production (see Security & Authentication).

Argon2id Tuning

Defaults follow OWASP 2026 (m=64 MiB, t=3, p=2). Tune so a single hash takes ~250–500ms on production hardware. Memory is the dominant cost; combined with MAX_CONCURRENT_PASSWORD_HASHES it bounds API memory at roughly ARGON2_MEMORY_KIB * MAX_CONCURRENT_PASSWORD_HASHES KiB.

VariableDefaultDescription
ARGON2_MEMORY_KIB65536Memory cost in KiB (64 MiB). Minimum accepted: 8192
ARGON2_TIME3Iterations. Minimum accepted: 1
ARGON2_PARALLELISM2Parallelism factor. Minimum accepted: 1
ARGON2_SALT_LEN16Salt length in bytes. Minimum accepted: 8
ARGON2_KEY_LEN32Derived key length in bytes. Minimum accepted: 16
MAX_CONCURRENT_PASSWORD_HASHES2 * NumCPUMax concurrent hash/verify operations (bounds API memory)

Trusted Proxies

VariableDefaultRequiredDescription
TRUSTED_PROXIESNoComma-separated list of trusted proxy IPs/CIDRs for rate limiting and client-IP extraction

Slack

VariableDefaultRequiredDescription
SLACK_BOT_TOKENNoSlack bot token (UI-configurable, stored encrypted). When set via env, the UI fields are locked
SLACK_DEFAULT_CHANNELNoDefault Slack channel for unmatched alerts
SLACK_DISABLEDfalseNoDisable Slack delivery
SLACK_SIGNING_SECRETNoVerifies Slack Events API signatures on /webhooks/slack
SLACK_CLIENT_IDNoSlack app Client ID (enables OAuth install flow)
SLACK_CLIENT_SECRETNoSlack app Client Secret (enables OAuth install flow)
SLACK_OAUTH_REDIRECT_URLNoOverride OAuth callback URL (for reverse-proxy setups)

Mattermost

VariableDefaultRequiredDescription
MATTERMOST_SERVER_URLNoMattermost server base URL (Alga appends /plugins/com.alga.mattermost-plugin for the plugin API). When set via env, the UI field is locked
MATTERMOST_WEBHOOK_SECRETNoShared secret with the Mattermost plugin
MATTERMOST_TEAMNoMattermost team slug for channel resolution (e.g. engineering)
MATTERMOST_DEFAULT_CHANNELNoDefault Mattermost channel for unmatched alerts
MATTERMOST_DISABLEDfalseNoDisable Mattermost delivery

RabbitMQ

VariableDefaultRequiredDescription
RABBITMQ_URINoAMQP URI (enables the async pipeline: alert processing, investigations, email, escalation, triage, SLA)

Valkey / Redis

VariableDefaultRequiredDescription
VALKEY_ADDRNoValkey/Redis address (enables sessions, caching, rate limiting, leader election, presence, SLA, escalation state, on-call cache, idempotency replay)
VALKEY_PASSWORDNoValkey/Redis password
VALKEY_DB0NoDatabase number

Idempotency & Outbox

VariableDefaultRequiredDescription
IDEMPOTENCY_ENABLEDtrueNoEnable Idempotency-Key replay for opted-in retry-safe writes (create incident, ingest alert webhook, notification send, agent state-changing actions). Requires Valkey; no-op when Valkey is not configured
IDEMPOTENCY_TTL24hNoHow long a cached response is replayed for a repeated Idempotency-Key before the key expires
ALGA_OUTBOX_RETENTION168h (7 days)NoRetention window for published transactional-outbox rows before pruning. Set to 0 to disable pruning

Hermes / SRE Agent

VariableDefaultRequiredDescription
HERMES_PLATFORM_URLNoHermes platform base URL (stored in the integrations table, encrypted token)
HERMES_PLATFORM_TOKENNoHermes platform bearer token (encrypted at rest)

Agent connections use per-agent tokens

Agent dispatch and SSE connections use bearer tokens created per-agent in the Alga UI (alga_agent_...), not HERMES_PLATFORM_TOKEN. The platform URL/token fields are stored encrypted in the integrations table and surfaced via the integration config API.

Agent SSE

VariableDefaultRequiredDescription
AGENT_SSE_ALLOWED_ORIGINSNoComma-separated Origin allowlist for the agent SSE endpoint. Empty allows all origins

Alert Correlation

VariableDefaultRequiredDescription
CORRELATION_WINDOW15sNoTime window during which alerts sharing a correlation key are buffered and merged into one investigation. 0 flushes each alert immediately (no grouping delay)
CORRELATION_COOLDOWN_TTL30mNoCooldown after investigation publish (prevents duplicates)

Investigation

VariableDefaultRequiredDescription
INVESTIGATION_TIMEOUT10mNoInvestigation timeout
MAX_CONCURRENT_INVESTIGATIONS3NoMax parallel investigations per agent
MAX_CONCURRENT_COMMAND3NoMax concurrent command dispatches
STATUS_UPDATE_INTERVAL15mNoDefault cadence for incident status updates
INVESTIGATION_CHANNELNoSlack or Mattermost channel for investigation threads
CRITICAL_SEVERITY_LABELSNoComma-separated labels that trigger critical escalation

Scheduler HA & Presence

VariableDefaultRequiredDescription
SCHEDULER_LEADER_TTL15sNoLeader lease TTL for scheduler HA. Set to 0 for single-replica
AGENT_PRESENCE_TTL90sNoAgent SSE presence TTL (renewed via heartbeat/keepalive)
AGENT_DISCONNECT_GRACE45sNoGrace period before resetting work on agent disconnect
CANCEL_SET_TTL168h (7 days)NoHow long a deleted entity's cancel marker lives in Valkey so workers skip it without hitting Postgres. Must exceed the max RabbitMQ retry/DLQ horizon

Stale Alert Sweep

VariableDefaultRequiredDescription
STALE_ALERT_THRESHOLD15mNoMinimum age before a firing alert with no investigation is considered stale. 0 disables
STALE_ALERT_SWEEP_INTERVAL5mNoHow often the scheduler scans for stale alerts

SLA Sweep

VariableDefaultRequiredDescription
SLA_SWEEP_INTERVAL60sNoHow often the scheduler leader publishes an SLA breach-detection sweep tick. Values ≤ 0 disable publication entirely

Stuck-Investigation Escalation

VariableDefaultRequiredDescription
STUCK_INVESTIGATION_ESCALATION_MULTIPLIER2NoMultiple of INVESTIGATION_TIMEOUT after which an in-progress investigation is "stuck" and pages the ops team. Set to 0 to disable
STUCK_INVESTIGATION_ESCALATION_TICK_INTERVAL30sNoHow often the stuck-investigation escalation worker runs
OPS_TEAM_NAMEops-teamNoTeam whose schedule is the human-on-call target for stuck-investigation and forced-channel escalations

Voice Escalation

Alga supports two voice providers for phone-call escalation: Twilio (default) and Telnyx. They are mutually exclusive — only the selected provider is active. Set VOICE_PROVIDER to choose; switching requires a restart. When unset, the provider can be chosen from the Integrations UI (persisted in the DB).

VariableDefaultRequiredDescription
VOICE_PROVIDERtwilioNotwilio or telnyx. Unrecognized values normalize to twilio. Setting this locks the UI selector

Twilio

VariableDefaultRequiredDescription
TWILIO_ACCOUNT_SIDNoTwilio account SID. When set via env, the UI fields are locked and env takes precedence
TWILIO_AUTH_TOKENNoTwilio auth token (required for callback validation)
TWILIO_FROM_NUMBERNoTwilio outbound phone number
TWILIO_DISABLEDfalseNoDisable Twilio entirely

Telnyx

VariableDefaultRequiredDescription
TELNYX_API_KEYNoTelnyx API key. When set via env, the UI fields are locked
TELNYX_CONNECTION_IDNoTelnyx Call Control Application ID
TELNYX_FROM_NUMBERNoTelnyx outbound phone number
TELNYX_PUBLIC_KEYNoEd25519 public key (base64) from the Telnyx portal, used to verify inbound call-control webhooks at /api/v1/telnyx/callback. Required when VOICE_PROVIDER=telnyx
TELNYX_DISABLEDfalseNoDisable Telnyx entirely
TELNYX_TTS_VOICENoTTS voice for spoken prompts (e.g. Polly.Brian, Azure.en-CA-ClaraNeural, ElevenLabs.eleven_flash_v2_5.<voice_id>). Defaults to a free Telnyx voice
TELNYX_TTS_LANGUAGENoTTS language
TELNYX_TTS_API_KEY_REFNoIdentifier of a Telnyx integration secret holding the ElevenLabs API key. Required only when TELNYX_TTS_VOICE starts with ElevenLabs.

SMTP / Email

Required for password reset emails and email notifications. If SMTP_HOST is empty, password reset emails are logged but not delivered.

VariableDefaultRequiredDescription
SMTP_HOSTNoSMTP relay hostname (enables email notifications + password reset)
SMTP_PORT587NoSMTP port
SMTP_USERNoSMTP auth username
SMTP_PASSWORDNoSMTP auth password
SMTP_FROMNoFrom address for email notifications
SMTP_SKIP_TLS_VERIFYfalseNoSkip TLS certificate verification for SMTP. Security risk — logs a loud warning on startup when enabled (ASVS V9.2)

Agent Memory

pgvector-backed shared agent memory for extracting and searching investigation memories.

VariableDefaultRequiredDescription
MEMORY_ENABLEDfalseNoEnable agent memory
MEMORY_EMBEDDING_URLNoOpenAI-compatible embedding API URL
MEMORY_EMBEDDING_API_KEYNoAPI key for the embedding service
MEMORY_EMBEDDING_MODELNoEmbedding model name — must be 1536-dimension (boot-time check rejects others)
MEMORY_LLM_URLNoOpenAI-compatible LLM API URL for memory extraction
MEMORY_LLM_API_KEYNoAPI key for the extraction LLM
MEMORY_LLM_MODELNoLLM model for memory extraction
MEMORY_AUTO_EXTRACTfalseNoAuto-extract memories on investigation completion
MEMORY_MAX_PER_INVESTIGATIONNoHard cap on memories extracted per investigation; LLM results are truncated to this before embedding (default 10)
MEMORY_SIMILARITY_THRESHOLDNoMin search score (0–1) for results to be returned; applied as a post-filter on the vector and text search paths. 0 returns the raw top-K

Triage

VariableDefaultRequiredDescription
TRIAGE_ENABLEDfalseNoEnable the triage system
TRIAGE_LLM_URLNoLLM API URL for triage decisions
TRIAGE_LLM_API_KEYNoAPI key for the triage LLM
TRIAGE_LLM_MODELNoLLM model for triage
TRIAGE_MAX_CONCURRENT3NoMax concurrent triage operations
TRIAGE_TIMEOUT2mNoTriage operation timeout
MAX_CONCURRENT_TRIAGE5NoMax concurrent triage workers
TRIAGE_CONFIDENCE_THRESHOLD0.7NoMin confidence for auto-decisions; below this, decisions downgrade to enrich_only
TRIAGE_AUTO_RESOLVE_ENABLEDfalseNoAllow auto_resolve decisions (otherwise downgrades to enrich_only)
TRIAGE_SUPPRESS_ENABLEDfalseNoAllow suppress decisions (otherwise downgrades to enrich_only)
TRIAGE_CONTEXT_EPISODIC_LIMIT3NoMax episodic context entries
TRIAGE_CONTEXT_NOTES_LIMIT3NoMax knowledge notes for context
TRIAGE_CONTEXT_MEMORIES_LIMIT5NoMax agent memories for context
TRIAGE_AUTO_PROMOTE_CONFIRMED_COUNT3NoConfirmed results of the same correlation key + decision before new triages for that key skip the LLM (0 disables)

Google OAuth

Enables "Sign in with Google" on the login page.

VariableDefaultRequiredDescription
GOOGLE_CLIENT_IDNoGoogle OAuth client ID
GOOGLE_CLIENT_SECRETNoGoogle OAuth client secret
GOOGLE_OAUTH_REDIRECT_URLNoOverride callback URL (auto-detected from request headers if not set)
GOOGLE_OAUTH_ENABLEDtrueNoToggle Google Sign-In

Google Meet (War Rooms)

Auto-creates a Google Meet space per incident for war-room coordination. Requires a service-account JSON with the Meet API enabled and domain-wide delegation for scope https://www.googleapis.com/auth/meet.space.admin.

VariableDefaultRequiredDescription
GOOGLE_MEET_ENABLEDfalseNoEnable Google Meet integration
GOOGLE_MEET_CREDENTIALS_PATHNoPath to the service-account JSON
GOOGLE_MEET_AUTO_CREATEtrueNoAuto-create a Meet space when an incident goes active

Data Retention

VariableDefaultRequiredDescription
DATA_RETENTION_DAYS90NoDays to retain resolved alerts. Set to 0 to keep forever
AUDIT_RETENTION_DAYS365NoDays to retain audit logs; pruned by the hourly retention sweeper alongside DATA_RETENTION_DAYS. Set to 0 to keep forever

Observability (OpenTelemetry)

Tracing is env-gated and off by default. When disabled, a noop tracer provider is installed and tracing has zero runtime cost. Tracing turns on when ALGA_OTEL_ENABLED=true or an OTLP endpoint is configured.

VariableDefaultRequiredDescription
ALGA_OTEL_ENABLEDfalseNoMaster switch for OpenTelemetry tracing
OTEL_EXPORTER_OTLP_ENDPOINTNoOTLP/HTTP collector endpoint. The standard OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is also honored
ALGA_OTEL_SAMPLE_RATIO1.0 (when tracing enabled)NoFraction (0.0–1.0) of new traces sampled via a ParentBased(TraceIDRatioBased) sampler

Frontend

The frontend is a Vite app; its variables are prefixed with VITE_ and read at build time.

VariableDefaultRequiredDescription
VITE_API_BASE_URLNoAPI base URL override for the frontend. Leave empty to use the Vite dev proxy

Features With No Environment Variables

These features are configured entirely through the API/UI, not environment variables:

  • Playbooks — managed via /api/v1/playbooks
  • Heartbeats — managed via /api/v1/heartbeats
  • Status Pages — managed via /api/v1/status-pages
  • Credential Providers & Shared Secrets — managed via /api/v1/credential-providers and /api/v1/shared-secrets
  • Incident Summariesincident_summary_enabled, incident_summary_interval, and per-severity incident_summary_intervals are managed via the System Configuration API
  • On-Call Reminders — on-call shift handoff detection runs on the scheduler; reminder behavior is not controlled by environment variables

System Configuration API

Runtime settings can also be managed via the API at PUT /api/v1/system/config. For supported settings this overrides environment variables. See System Configuration API.

Released under the MIT License.