# Leave this as is if connecting from a remote machine SERVER_IP=0.0.0.0 # SECURITY: JWT secret for token signing. # REQUIRED — the application will refuse to start if this is unset or set to the # known-compromised default disclosed in GHSA-4gxj-hw3c-3x2x. # Generate a unique secret with: openssl rand -base64 32 JWT_SECRET=REPLACE_ME # SECURITY: Dedicated secret for signing OAuth2 state tokens (SSO flows). # If not set, falls back to JWT_SECRET — set this to isolate SSO state signing. # Generate with: openssl rand -base64 32 SSO_STATE_SECRET=REPLACE_ME # SECURITY: Fernet encryption key for TOTP secrets stored in the database. # If not set, falls back to a key derived from JWT_SECRET. # ⚠️ Once set and users have enrolled 2FA, do NOT change this key — existing # TOTP secrets in the database will become unreadable. # Generate with: python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())" TOTP_ENCRYPTION_KEY=REPLACE_ME # WebAuthn / Passkey sign-in (optional — leave WEBAUTHN_ORIGINS empty to disable). # RP ID must match the host users reach in the browser (no scheme/port). # ORIGINS is a comma-separated list of allowed frontend origins (scheme + host + port). # Example local dev: use localhost (not 127.0.0.1 — browsers reject passkeys on the IP). # WEBAUTHN_ORIGINS=http://localhost:5173 WEBAUTHN_RP_ID=localhost WEBAUTHN_RP_NAME=SOCFortress CoPilot WEBAUTHN_ORIGINS=https://localhost:5173 # Shared secrets required on the webhook routes that are gated by a header instead of a # JWT: GRAYLOG_API_HEADER_VALUE protects /api/graylog/invoke (active-response) and the # /api/incidents/alerts/create/threshold|velo-sigma alert-injection routes; # VELOCIRAPTOR_API_HEADER_VALUE and GRAFANA_API_HEADER_VALUE protect their respective # routes. All three FAIL CLOSED: if left blank the route is denied for everyone, so there # is no guessable default to exploit (GHSA-x8gc-f8p4-frc2, GHSA-xh98-w6qh-cr44 — same class # as the JWT_SECRET default in GHSA-4gxj-hw3c-3x2x). Generate a unique random value per # deployment (e.g. `openssl rand -hex 32`) and send it as the matching request header # (`Graylog`, `Velociraptor`, `grafana`). Do NOT commit a real value or reuse one secret. GRAYLOG_API_HEADER_VALUE= VELOCIRAPTOR_API_HEADER_VALUE= GRAFANA_API_HEADER_VALUE= MYSQL_URL=copilot-mysql # ! Avoid using special characters in the password ! # MYSQL_ROOT_PASSWORD=REPLACE_WITH_PASSWORD MYSQL_USER=copilot # ! Avoid using special characters in the password ! # MYSQL_PASSWORD=REPLACE_WITH_PASSWORD MINIO_URL=copilot-minio MINIO_ROOT_USER=admin # ! Make the password at least 8 characters long ! # MINIO_ROOT_PASSWORD=REPLACE_ME MINIO_SECURE=False # ! ALERT FORWARDING IP # Set this to the IP of the host running CoPilot. This is used by Graylog to forward alerts to CoPilot # ! Not needed anymore since we are reading from the index now # ! Ensure Graylog is able to reach this IP and port 5000 ALERT_FORWARDING_IP=0.0.0.0 # Connector Credentials # ! SETTING UP YOUR CONNECTORS DEMOs https://www.youtube.com/@taylorwalton_socfortress/videos! # WAZUH_INDEXER_URL=https://127.1.1.1:9200 WAZUH_INDEXER_USERNAME=admin WAZUH_INDEXER_PASSWORD=admin WAZUH_MANAGER_URL=https://127.1.1.1 WAZUH_MANAGER_USERNAME=dummy WAZUH_MANAGER_PASSWORD=dummy GRAYLOG_URL=http://127.1.1.1 GRAYLOG_USERNAME=dummy GRAYLOG_PASSWORD=dummy GRAYLOG_NETWORK_URL=http://127.1.1.1 GRAYLOG_NETWORK_USERNAME=dummy GRAYLOG_NETWORK_PASSWORD=dummy SHUFFLE_URL=https://127.1.1.1 SHUFFLER_API_KEY=dummy SHUFFLE_WORKFLOW_ID=dummy VELOCIRAPTOR_URL=https://127.1.1.1 VELOCIRAPTOR_API_KEY_PATH=dummy SUBLIME_URL=http://127.1.1.1 SUBLIME_API_KEY=dummy INFLUXDB_URL=http://127.1.1.1 INFLUXDB_API_KEY=dummy INFLUXDB_ORG_AND_BUCKET=dummy,dummy GRAFANA_URL=http://127.1.1.1 GRAFANA_USERNAME=dummy GRAFANA_PASSWORD=dummy WAZUH_WORKER_PROVISIONING_URL=http://127.1.1.1 EVENT_SHIPPER_URL=graylog_host GELF_INPUT_PORT=gelf_port ALERT_CREATION_PROVISIONING_URL=http://127.1.1.1 HAPROXY_PROVISIONING_URL=http://127.1.1.1 # VirusTotal VIRUSTOTAL_URL=https://www.virustotal.com/api/v3 VIRUSTOTAL_API_KEY=REPLACE_ME # Portainer PORTAINER_URL=http://127.1.1.1:9000 PORTAINER_USERNAME=admin PORTAINER_PASSWORD=admin PORTAINER_ENDPOINT_ID=2 # SOCFORTRESS TALON : https://github.com/taylorwalton/talon/tree/main TALON_URL=http://127.1.1.1:3100 TALON_API_KEY=REPLACE_ME # ! CoPilot MCP # OpenAI Configuration OPENAI_API_KEY=REPLACE_ME OPENAI_MODEL=gpt-4o # Application Configuration LOG_LEVEL=INFO # JWT token expiry in minutes (default: 1440 = 24h) ACCESS_TOKEN_EXPIRE_MINUTES=1440 # Audit log retention, in days (issue #943). A daily scheduled job deletes audit_log rows # older than this so the append-only audit trail can't grow without bound. Default 90. # Raise it if your compliance framework mandates a longer minimum retention; set 0 to disable # pruning entirely (keep all audit entries forever). AUDIT_LOG_RETENTION_DAYS=90 # MCP Server Process Management MCP_SERVER_ENABLED=true # External OpenSearch Configuration OPENSEARCH_URL=https://your-wazuh-indexer-url:9200 # Likely your wazuh-indexer OPENSEARCH_USERNAME=YOUR_WAZUH_INDEXER_USERNAME OPENSEARCH_PASSWORD=YOUR_WAZUH_INDEXER_PASSWORD OPENSEARCH_SSL_VERIFY=false OPENSEARCH_SSL_SHOW_WARN=false # OpenSearch MCP Server Configuration MCP_OPENSEARCH_AUTH_TOKEN=secret-token # External MySQL Configuration MYSQL_ENABLED=true MYSQL_HOST=copilot-mysql MYSQL_PORT=3306 MYSQL_DATABASE=copilot # MySQL MCP Server Configuration MCP_MYSQL_AUTH_TOKEN=mysql-token MCP_MYSQL_SERVER_ENABLED=true # External Wazuh Configuration WAZUH_PROD_URL=https://your-wazuh-manager:55000 WAZUH_PROD_USERNAME=wazuh-wui WAZUH_PROD_PASSWORD=wazuh-wui WAZUH_PROD_SSL_VERIFY=false WAZUH_PROD_TIMEOUT=30 # Wazuh MCP Server Configuration MCP_WAZUH_AUTH_TOKEN=wazuh-token MCP_WAZUH_SERVER_ENABLED=true # External Velociraptor Configuration VELOCIRAPTOR_API_KEY=/app/velociraptor-config.yaml # Dont change this VELOCIRAPTOR_SSL_VERIFY=false VELOCIRAPTOR_TIMEOUT=30 # Quarantine artifact overrides. Leave unset to use Velociraptor's built-in # artifacts. On Velociraptor 0.76.x+ the built-in Linux.Remediation.Quarantine # runs a "forbidden connection test" that can roll back a working quarantine; # point this at a custom artifact (which Velociraptor won't let you override in # place) to avoid it. See issue #913. # VELOCIRAPTOR_LINUX_QUARANTINE_ARTIFACT=Custom.Linux.Remediation.Quarantine # VELOCIRAPTOR_WINDOWS_QUARANTINE_ARTIFACT=Custom.Windows.Remediation.Quarantine # Velociraptor MCP Server Configuration MCP_VELOCIRAPTOR_AUTH_TOKEN=velociraptor-token MCP_VELOCIRAPTOR_SERVER_ENABLED=true MCP_VELOCIRAPTOR_HOST=0.0.0.0 MCP_VELOCIRAPTOR_PORT=8001 # SOCFortress MDR Forwarding # When enabled, alerts for customers that have the "SOCFortress MDR" integration # deployed are forwarded to the MDR server (POST /api/v1/alerts/copilot). The # per-customer collector UUID is entered in the integration UI; MDR_COLLECTOR_UUID # below is only a single-tenant fallback. MDR_ENABLED=false MDR_SERVER_URL=https://mdr-server.socfortress.co MDR_COLLECTOR_UUID= # Graylog Threshold Alert -> OpenSearch index mapping # A Graylog threshold/aggregation event does not carry the source index pattern, so # CoPilot must be told which index to search per SOURCE value to resolve the underlying # events (alert asset/title + timeline). Built-in defaults cover wazuh and office365. # # THRESHOLD_SOURCE_INDEX_MAPPING: JSON object mapping a custom SOURCE to an index # pattern string, or a [index_pattern, time_field] pair (time field defaults to # "timestamp"). Merges over and overrides the built-in defaults. Example: # THRESHOLD_SOURCE_INDEX_MAPPING={"bitwarden": "bitwarden-*", "dellswitch": ["dellswitch-*", "timestamp"]} # # THRESHOLD_SOURCE_INDEX_FALLBACK_ENABLED: when true (default), an unmapped SOURCE # falls back to "-*" with a "timestamp" time field, so most custom sources # work with no config. Set false to raise on unknown sources instead of guessing. THRESHOLD_SOURCE_INDEX_MAPPING= THRESHOLD_SOURCE_INDEX_FALLBACK_ENABLED=true # SMTP (optional) — used by the customer Security panel to email a temporary # password to a user. When SMTP_HOST is unset, the email action is disabled in # the UI and the backend refuses to send (all other Security actions still work). SMTP_HOST= SMTP_PORT=587 SMTP_USERNAME= SMTP_PASSWORD= SMTP_FROM= SMTP_USE_TLS=true