Environment variables
Every Fenrir setting lives in .env (loaded at startup). Defaults are in p3guardian/config.py. Restart p3guardian.service after changing.
Defaults are dev-friendly, not production-grade
Several of the defaults below are deliberately permissive for the 15-minute install path — IP_WHITELIST, the LLM choice, the dashboard binding. Before exposing the server to the internet, work through the Hardening checklist . It calls out which values must change and to what.
Database
Variable
Default
Purpose
DATABASE_URL
(empty → SQLite)
PostgreSQL DSN, e.g. postgresql://p3guardian:pwd@localhost/p3guardian. Empty falls back to SQLite at data/guardian.db
DB_PATH
data/guardian.db
SQLite location (used only if DATABASE_URL is empty)
Log paths to monitor
Variable
Default
Purpose
AUTH_LOG
/var/log/auth.log
sshd + sudo events
HONEYPOT_LOG
/var/log/nginx/honeypot.log
Custom honeypot channel populated by your nginx config
FAIL2BAN_LOG
/var/log/fail2ban.log
fail2ban actions
The other monitors (nginx, ufw, kernel, package) use hardcoded paths in app.py — change there if your distro is non-standard.
Auto-ban + whitelist
Variable
Default
Purpose
AUTO_BAN_ENABLED
true
Master switch for the responder pipeline
AUTO_BAN_MIN_SEVERITY
3
Min severity for auto-ban (HIGH=3, CRITICAL=4)
IP_WHITELIST
192.168.1.0/24,127.0.0.1
Comma-separated list. Whitelisted IPs get severity demoted to INFO/LOW. CHANGE BEFORE FIRST START if your reverse-proxy doesn't strip RFC1918 source IPs — see Hardening checklist #1
Autonomous response (Sprint 2)
See the dedicated Autonomous response page for the full operational checklist.
Variable
Default
Purpose
AUTO_ACTION_ENABLED
false
Master switch for kill / quarantine / stop / isolate / rollback. Off by default
AUTO_ACTION_DRY_RUN
true
When true, log + persist what would happen but don't execute. Keep on for ≥ 1 week before flipping off
AUTO_ACTION_MIN_CONFIDENCE
85
LLM confidence threshold (0-100) below which actions are skipped
AUTO_ACTION_TYPES
["kill_process","file_quarantine","service_stop"]
Allowlist. Add isolate_network and package_rollback only after auditing those code paths
AUTO_ACTION_PROCESS_WHITELIST
sshd, systemd, postgres, p3guardian, cloudflared, nginx, fail2ban-server, dbus, NetworkManager, ...
Names that are never killable / stoppable / removable, even with confidence 100
AUTO_ACTION_QUARANTINE_DIR
/var/quarantine
Where quarantined files are moved (created mode 0700 on first use)
Web dashboard
Variable
Default
Purpose
WEB_ENABLED
true
Master switch for the aiohttp dashboard
WEB_HOST
0.0.0.0
Bind address
WEB_PORT
8443
Bind port (HTTP, not HTTPS — terminate TLS upstream)
WEB_PUBLIC_URL
(empty)
Public URL shown in Telegram messages. Empty falls back to detected LAN IP. Set to https://app.fenrirsoc.com (or your domain) in production
GEOIP_DB_PATH
data/GeoLite2-City.mmdb
MaxMind DB path. Download separately
SERVER_LAT / SERVER_LON
Frankfurt
Coordinates of your server for the live attack map
Multi-server (optional)
Variable
Default
Purpose
SERVER_ID
main
Unique ID for this server in a federated setup
SERVER_NAME
Main Server
Display name on the multi-tenant dashboard
API_SECRET
(empty)
Shared secret for /api/ingest from remote agents. Required when running multi-server
AI / LLM
OpenRouter (cloud)
Variable
Default
Purpose
OPENROUTER_API_KEY
(empty)
Set this to use cloud LLMs. Empty disables OpenRouter
OPENROUTER_MODEL
qwen/qwen3.5-flash-02-23
Model ID. Try anthropic/claude-haiku-4.7 or claude-opus-4-7 for better reasoning
Ollama (local)
Variable
Default
Purpose
OLLAMA_URL
http://127.0.0.1:11434
Ollama service endpoint
OLLAMA_MODEL
qwen3:0.6b
Model name (must be pre-pulled with ollama pull). The 0.6B default is for local dev — for any internet-facing host use a ≥7B local model or an OpenRouter cloud model. Small models are more vulnerable to prompt-injection embedded in attacker-controlled log lines. See Hardening checklist #12
AI_ANALYSIS_ENABLED
true
Master switch for AI features
If both OpenRouter and Ollama are configured, OpenRouter wins. Set OPENROUTER_API_KEY empty to force Ollama.
Telegram bot
Variable
Default
Purpose
TELEGRAM_BOT_TOKEN
(empty)
From @BotFather. Empty disables the bot
TELEGRAM_CHAT_ID
(empty)
Where alerts go. Find with @userinfobot (your DM) or by adding the bot to a group
GDPR breach notification
Variable
Default
Purpose
BREACH_NOTIFICATION_ENABLED
true
Auto-create breach records for relevant events
BREACH_NOTIFICATION_EMAIL
(empty)
DPO email for notifications. Required for GDPR-33 audit pass
BREACH_ESCALATION_MINUTES
30,120,360,1440
Escalation reminders before the 72h deadline
Reporting & retention
Variable
Default
Purpose
DAILY_DIGEST_HOUR
7
UTC hour for the daily Telegram digest. 0-23
RETENTION_DAYS
90
Max age of events rows before purge. Aligns with GDPR Art. 5(1)(e)
Compliance scheduler
Variable
Default
Purpose
COMPLIANCE_ENABLED
true
Run daily compliance audits
COMPLIANCE_FRAMEWORKS
GDPR,ISO27001
Which frameworks to audit
COMPLIANCE_SCHEDULE_HOUR
6
UTC hour
COMPLIANCE_ALERT_ON_FAILURE
true
Send Telegram alert if a control fails
Client branding
Variable
Default
Purpose
CLIENT_NAME
(empty)
Shown on dashboards & PDF reports
CLIENT_LOGO_PATH
(empty)
Path to PNG/JPG (embedded in PDF reports)
GUARDIAN_VERSION
0.5.0
Version string for compatibility checks
Example minimal .env
# Database
DATABASE_URL = postgresql://p3guardian:supersecret@localhost/p3guardian
# Telegram (required for alerts)
TELEGRAM_BOT_TOKEN = 1234567890 :abcdefghijklmnop
TELEGRAM_CHAT_ID = -1001234567890
# AI (one of the two)
OPENROUTER_API_KEY = sk-or-v1-...
OPENROUTER_MODEL = qwen/qwen3.5-flash-02-23
# Public URL (for Telegram links)
WEB_PUBLIC_URL = https://app.fenrirsoc.com
# Compliance
BREACH_NOTIFICATION_EMAIL = [email protected]
CLIENT_NAME = ACME Corp
Security tips
.env should be 0640 root:p3guardian — readable only by the service user.
Don't commit .env to git. The repo's .gitignore covers it.
Rotate TELEGRAM_BOT_TOKEN and OPENROUTER_API_KEY periodically. Both can be re-issued without downtime if you script the swap.
For multi-tenant deployments (Fenrir-as-SOCaaS for multiple clients), use a different SERVER_ID per client and a strong API_SECRET.