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:
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:
After changing ports:
For tests, set the matching base URL:
Troubleshooting Port Conflicts¶
Check if a port is in use:
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:
--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
- Open the Workflow page in the web UI.
- In the workflow config panel, use Import Preset from file and choose a JSON file from
config/presets/AgentConfigs/quickstart/. - 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:
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):
- Create a repo at github.com/new (e.g.
Huntable-SIGMA-Rules) - When prompted, enter
owner/repo(e.g.myuser/Huntable-SIGMA-Rules) - The script clones to
../Huntable-SIGMA-Rulesand creates therules/structure
After setup (required):
- Add your GitHub Personal Access Token in Settings -> GitHub (repo scope)
- Create token at github.com/settings/tokens
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
sourcestable - 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¶
API Documentation¶
http://localhost:8001/docs
Database Connection¶
Redis Connection¶
Workflow Status¶
Ingestion Analytics¶
Applying Configuration Changes¶
After modifying configuration:
-
Environment variables only: Restart affected services
-
Port changes or docker-compose.yml: Rebuild and restart
-
Source configuration: Sync sources
Last updated: 2026-07-04 Last reviewed: 2026-07-04