Skip to content

Configuration Reference

Huntable CTI Studio configuration uses three files: environment variables (.env), Docker Compose (docker-compose.yml), and source feeds (config/sources.yaml).

Configuration Files

Environment Variables (.env)

Primary configuration file for sensitive values and service settings. Provision it with setup:

Bash
./setup.sh --no-backups

Docker Compose (docker-compose.yml)

Defines service topology, port mappings, and volume mounts.

Source Configuration (config/sources.yaml)

Defines CTI feeds and sources. See Source Configuration Precedence for details on YAML vs database sync.

Port Mappings

Default Ports

Service Host Port Container Port Purpose
Web/API 8001 8001 Main FastAPI application
PostgreSQL 5432 5432 Database
Redis 6379 6379 Cache and message broker
LM Studio 1234 — External (host machine)

Customizing Ports

To change the host port for the web application, edit docker-compose.yml:

YAML
services:
  web:
    ports:
      - "8002:8001"  # Map host port 8002 to container port 8001

After changing ports:

Bash
docker compose down
docker compose up -d

For tests, set the matching base URL:

Bash
export CTI_SCRAPER_URL=http://localhost:8002

Troubleshooting Port Conflicts

Check if a port is in use:

Bash
lsof -i :8001

To resolve conflicts, either stop the conflicting service or change the host port in docker-compose.yml as shown above.

Environment Variables Reference

Core Infrastructure

Variable Purpose Default Required
DATABASE_URL PostgreSQL connection string Built by Docker Compose from POSTGRES_PASSWORD (see .env.example); not a literal default in repo Yes
POSTGRES_PASSWORD PostgreSQL password — Yes
MAINTENANCE_API_TOKEN Shared secret for internal web-to-maintenance backup/restore requests — Yes when using web backup/restore
REDIS_URL Redis connection redis://redis:6379/0 Yes
SOURCES_CONFIG Path to sources YAML config/sources.yaml No
ENVIRONMENT Environment name development No
DISABLE_SOURCE_AUTO_SYNC Skip YAML→DB sync on startup false No
SECRET_KEY Signs CSRF tokens Generated by ./setup.sh In production when CSRF is active

Authentication and Access Control

Auth, RBAC, and CSRF are configured entirely via environment variables (AUTH_MODE, TRUSTED_HOSTS, CORS_ALLOWED_ORIGINS, CSRF_ENABLED, the AUTH_* trusted-header and group-mapping variables). The canonical reference is Authentication; for the Entra ID / oauth2-proxy front door see Enterprise SSO Setup. Parsing and fail-closed production validation live in src/web/security/config.py.

Celery Configuration

Variable Purpose Default
CELERY_BROKER_URL Celery broker URL redis://redis:6379/0
CELERY_MAX_TASKS_PER_CHILD Worker task limit before restart 50

LLM Provider Keys

Variable Purpose Required
OPENAI_API_KEY OpenAI API key No
ANTHROPIC_API_KEY Anthropic Claude API key No

Keys set during ./setup.sh: Keys entered when setup.sh prompts you are written to .env only. The application uses these values at runtime; you do not need to enter them again in the Settings page. Values saved in Settings are stored in the database and take precedence over .env for the workflow UI.

Credential fields never show a stored value. The settings API does not return secrets to the browser, so every credential input loads empty regardless of whether one is configured. The line under the field is what tells you: Configured (with a short hint and a Clear stored control) or Not set. Type a new value to replace what is stored; leaving the field empty leaves it untouched. Removing a credential is a deliberate act via Clear stored, never a side effect of an empty field.

Workflow-Specific LLM Configuration

Variable Purpose Default
WORKFLOW_OPENAI_API_KEY OpenAI key for workflows Falls back to OPENAI_API_KEY
WORKFLOW_ANTHROPIC_API_KEY Anthropic key for workflows Falls back to ANTHROPIC_API_KEY
WORKFLOW_OPENAI_ENABLED Enable OpenAI in workflows DB setting
WORKFLOW_ANTHROPIC_ENABLED Enable Anthropic in workflows DB setting
WORKFLOW_LMSTUDIO_ENABLED Enable LM Studio in workflows DB setting
WORKFLOW_CODEX_ENABLED Enable the deployment-managed Codex subscription in workflows false
WORKFLOW_OPENAI_MODEL OpenAI model for workflows gpt-4o-mini
WORKFLOW_ANTHROPIC_MODEL Anthropic model for workflows claude-sonnet-4-5
WORKFLOW_CODEX_MODEL Fallback Codex workflow model when the subscription cannot list models gpt-5.6-luna

Optional Codex Subscription Provider

Codex uses its own managed ChatGPT authentication; do not configure a subscription credential as an API key. Set WORKFLOW_CODEX_ENABLED=true, then authenticate the shared workflow-worker state volume once:

Bash
docker compose exec workflow_worker codex login --device-auth

--device-auth is required here. Plain codex login starts a browser-callback listener on port 1455 inside the container, which a host browser cannot reach; the device-code flow prints a URL and code to open in your own browser instead. The credential is written to the shared codex_auth volume, so web and both workers pick it up without a restart.

The workflow configuration and SIGMA enrichment modals list the models available to that login. Use the Test subscription control in Settings (or POST /api/settings/codex/test) to verify connectivity without running a workflow.

Optional LM Studio LLM Provider

LM Studio is not an application dependency. Configure this section only if you choose LM Studio for LLM inference. Embeddings are generated inside the application with sentence-transformers and do not call LM Studio.

Variable Purpose Default
LMSTUDIO_API_URL LM Studio API base URL http://host.docker.internal:1234/v1
LMSTUDIO_MODEL Default LM Studio model deepseek/deepseek-r1-0528-qwen3-8b (hardcoded in docker-compose.yml; .env value is not passed through)
LMSTUDIO_MODEL_RANK Model for ranking agent qwen/qwen3-4b-2507 (hardcoded in docker-compose.yml; .env value is not passed through)
LMSTUDIO_MODEL_EXTRACT Model for extraction agent qwen/qwen3-4b-2507
LMSTUDIO_MODEL_SIGMA Model for Sigma generation qwen/qwen3-4b-2507
LMSTUDIO_TEMPERATURE LLM temperature —
LMSTUDIO_TOP_P Top-p sampling —
LMSTUDIO_SEED Random seed for reproducibility —
LMSTUDIO_MAX_CONTEXT Max context window size —

Note: When the optional LM Studio LLM provider is enabled, it runs on your host machine. The host.docker.internal hostname allows Docker containers to reach that host service. Set LMSTUDIO_API_URL in Settings -> Agentic Workflow Configuration. Context length is configured per model via LMSTUDIO_CONTEXT_LENGTH_<model_slug> in docker-compose.yml and can differ between web and worker services. Old .env entries named LMSTUDIO_EMBEDDING_URL or LMSTUDIO_EMBEDDING_MODEL are obsolete and can be deleted. See LM Studio Integration for details.

Workflow Presets

Pre-built workflow config presets let you run the pipeline without configuring prompts by hand. Each preset sets one LLM provider and model for every workflow agent, plus default prompt configs (role, task, instructions, schema) for each agent. Seed prompt files live in src/prompts/ but are only read on first bootstrap or explicit reset; the authoritative prompts at runtime live in the database. See Prompt Architecture for details.

Quickstart presets (v2 format, always committed to the repo) are in config/presets/AgentConfigs/quickstart/:

Preset file Provider Model Use when
Quickstart-anthropic-sonnet-4-6.json Anthropic Claude Sonnet 4.6 You have ANTHROPIC_API_KEY and want Claude for all agents.
Quickstart-anthropic-haiku-4-5.json Anthropic Claude Haiku 4.5 You have ANTHROPIC_API_KEY and want a faster, lower-cost Claude model.
Quickstart-openai-gpt-4.1-mini.json OpenAI gpt-4.1-mini You have OPENAI_API_KEY and want a fast, low-cost OpenAI model.
Quickstart-openai-gpt-4.1.json OpenAI gpt-4.1 You have OPENAI_API_KEY and want the full gpt-4.1 model.
Quickstart-openai-gpt-4o.json OpenAI gpt-4o You have OPENAI_API_KEY and want gpt-4o.
Quickstart-openai-gpt-4o-mini.json OpenAI gpt-4o-mini You have OPENAI_API_KEY and want the gpt-4o-mini variant.
Quickstart-openai-gpt-5.json OpenAI gpt-5 You have OPENAI_API_KEY and want gpt-5.
Quickstart-codex-gpt-5.6-sol.json Codex gpt-5.6-sol You have a connected Codex subscription and want gpt-5.6-sol for all agents.
Quickstart-codex-gpt-5.6-terra.json Codex gpt-5.6-terra You have a connected Codex subscription and want gpt-5.6-terra for all agents.
Quickstart-codex-gpt-5.6-luna.json Codex gpt-5.6-luna You have a connected Codex subscription and want gpt-5.6-luna for all agents.
Quickstart-LMStudio-Qwen3.json LM Studio Qwen 3 (local) You run LM Studio with a Qwen3-compatible model.
Quickstart-LMStudio-Gemma4B.json LM Studio Gemma 4B (local) You run LM Studio with a Gemma 4B-compatible model.

All paths are relative to config/presets/AgentConfigs/quickstart/.

How to load a preset

  1. Open the Workflow page in the web UI.
  2. In the workflow config panel, use Import Preset from file and choose a JSON file from config/presets/AgentConfigs/quickstart/.
  3. Confirm the import; the active workflow config (thresholds, agent models, and agent prompts) is replaced by the preset. Tweak individual prompt fields (role, task, instructions, schema) in the workflow config editor as needed.

Private presets: To keep presets out of version control, put JSON files in config/presets/private/. That directory is gitignored (only *.json there); use Import Preset from file to load from it.

To normalize key order in quickstart presets after a schema update, run from the repo root:

Bash
python3 scripts/build_baseline_presets.py

src/prompts/ files are seed defaults, not live prompts. Editing them only affects new installs or explicit bootstrap resets; it does not change prompts for a running instance. To change prompts on a running instance, use the workflow config editor or the prompt API endpoints.

Content Filtering

Variable Purpose Default
CONTENT_FILTERING_ENABLED Enable ML content filtering true
CONTENT_FILTERING_CONFIDENCE Minimum confidence threshold 0.7
CHATGPT_CONTENT_LIMIT Max content chars for ChatGPT 1000000
ANTHROPIC_CONTENT_LIMIT Max content chars for Anthropic 1000000

Note: CHATGPT_CONTENT_LIMIT and ANTHROPIC_CONTENT_LIMIT are hardcoded to 1000000 in docker-compose.yml for the web service; .env values are not passed through to web (other services without this override still read .env).

Langfuse Observability

Variable Purpose Notes
LANGFUSE_PUBLIC_KEY Langfuse public key Required to enable tracing
LANGFUSE_SECRET_KEY Langfuse secret key Required to enable tracing
LANGFUSE_HOST Langfuse Cloud host URL Optional; runtime default is https://us.cloud.langfuse.com
LANGFUSE_PROJECT_ID Langfuse project ID Optional; improves workflow trace deep links in the UI

Configure Langfuse through environment variables or the Settings UI. Settings stored in the web UI take precedence over the same values in the environment.

Huntable CTI Studio supports Langfuse Cloud only. Local or self-hosted Langfuse deployments are outside this project's supported and tested configurations.

Set LANGFUSE_HOST to the correct Langfuse Cloud region for your account. If unset, the runtime defaults to https://us.cloud.langfuse.com (US). Common cloud hosts: https://cloud.langfuse.com (EU), https://us.cloud.langfuse.com (US), https://hipaa.cloud.langfuse.com. EU and US are separate Langfuse deployments -- keys from one region will not authenticate against the other.

Security note: Langfuse receives workflow and LLM telemetry. Depending on the workflow path, traces may contain prompts, article content, extracted observables, outputs, and metadata. Enable Langfuse only where external cloud tracing is acceptable for your data.

See Langfuse Setup for the full setup and verification workflow.

SIGMA / GitHub Integration

The app submits approved SIGMA rules via GitHub PRs. Setup is automated during ./setup.sh.

During setup.sh (interactive):

  1. Create a repo at github.com/new (e.g. Huntable-SIGMA-Rules)
  2. When prompted, enter owner/repo (e.g. myuser/Huntable-SIGMA-Rules)
  3. The script clones to ../Huntable-SIGMA-Rules and creates the rules/ structure

After setup (required):

Non-interactive: Set SIGMA_GITHUB_REPO=owner/repo before running ./setup.sh --non-interactive to clone automatically.

Variable Purpose Default
HUNTABLE_SIGMA_REPO_HOST_PATH Host checkout mounted into Docker at /app/sigma-repo; override only when the customer rules repo is not the app's sibling directory ../Huntable-SIGMA-Rules
SIGMA_REPO_PATH Path to the customer rules repo containing Huntable-created and approved rules; used for PR submission and customer-repo indexing sigma-repo
GITHUB_TOKEN GitHub PAT for PR submission —
GITHUB_REPO Target repo for SIGMA rule PRs owner/repo (from setup)

The upstream SigmaHQ reference repository is separate: data/sigma-repo. It is maintained by sigma sync for reference-rule indexing and must not be configured as SIGMA_REPO_PATH.

Source Configuration

  • YAML file: config/sources.yaml (version-controlled template)
  • Runtime source of truth: PostgreSQL sources table
  • Auto-sync: YAML -> DB sync runs on startup when fewer than 5 sources exist in the database
  • Manual sync: ./run_cli.sh sync-sources --config config/sources.yaml --no-remove
  • Disable auto-sync: Set DISABLE_SOURCE_AUTO_SYNC=true

See Source Configuration Precedence for details.

Celery and Scheduled Jobs

Task queues, Celery Beat periodic tasks (source checks, cleanup, reports, embeddings, Sigma sync, provider model catalog refresh, customer-repo index), and host backup cron are documented in Scheduled Jobs. The provider model catalog is also refreshed at setup (./setup.sh) and start (./start.sh) so workflow model dropdowns show the current list immediately.

Health Checks and Diagnostics

Application Health

Bash
curl http://localhost:8001/health

API Documentation

http://localhost:8001/docs

Database Connection

Bash
PGPASSWORD=$POSTGRES_PASSWORD psql -h localhost -U cti_user -d cti_scraper -c "SELECT 1"

Redis Connection

Bash
redis-cli -h localhost -p 6379 ping

Workflow Status

Bash
curl http://localhost:8001/api/workflow/executions

Ingestion Analytics

Bash
curl http://localhost:8001/api/health/ingestion

Applying Configuration Changes

After modifying configuration:

  1. Environment variables only: Restart affected services

    Bash
    docker compose restart web worker
    

  2. Port changes or docker-compose.yml: Rebuild and restart

    Bash
    docker compose down
    docker compose up -d --build
    

  3. Source configuration: Sync sources

    Bash
    ./run_cli.sh sync-sources --config config/sources.yaml
    


Last updated: 2026-07-04 Last reviewed: 2026-07-04