PORT=3001 # HEALTH_TOKEN is read at runtime only (process.env at startup). # On Coolify: MUST be is_runtime=true, is_buildtime=false. # Buildtime ARG leaks the secret in clear in application_deployment_queues.logs. HEALTH_TOKEN=change-me-to-a-strong-secret LOGTO_HEALTH_URL=https://auth.lacompagniemaximus.com/oidc/.well-known/openid-configuration # Directory read by GET /reports/scans and GET /defenseurs/findings. On Coolify # it is its own read-only mount (/home/defenseur/defenseurs/reports -> # /data/defenseurs/reports:ro), nested inside the read-only /data/defenseurs # mount that holds status.json. REPORTS_DIR=/data/defenseurs/reports # --- Workstation snapshots (POST /hosts/, GET /hosts) -------------------- # Directory the API WRITES workstation snapshots into, one .json per host. # Unlike the two /data/defenseurs mounts (read-only `:ro`; content owned by # defenseur:defenseur, uid/gid 1001, group-writable but not by gid 1000), this # one must be writable by uid 1000 (the `node` user the container runs as) or # every ingest answers 500. HOSTS_DIR=/data/hosts # Comma-separated allowlist of host ids. Each entry must match # ^[a-z0-9][a-z0-9-]{0,31}$ — anything else is logged and dropped at startup. HOSTS_ALLOWED_IDS=thinkpad # Bearer token for POST /hosts/. Separate from HEALTH_TOKEN on purpose: a # workstation agent should be able to write its own snapshot without gaining # read access to the Defenseurs reports. Same Coolify rule as HEALTH_TOKEN — # is_runtime=true, is_buildtime=false. Unset -> POST /hosts/ answers 503. HOSTS_INGEST_TOKEN=change-me-to-a-strong-secret # Age (seconds) past which GET /hosts reports a host as offline. Default 900. HOSTS_STALE_SECONDS=900 # --- Claude usage snapshot (POST /claude-usage, GET /claude-usage) --------- # Bearer token for POST /claude-usage, pushed by the ThinkPad agent. Distinct # from HOSTS_INGEST_TOKEN and HEALTH_TOKEN: each one is refused on the others' # routes. Same Coolify rule — is_runtime=true, is_buildtime=false. Unset -> # POST /claude-usage answers 503. CLAUDE_USAGE_INGEST_TOKEN=change-me-to-a-strong-secret # File the API WRITES (atomic rename). Its directory must be its own read-write # mount owned by uid 1000, like HOSTS_DIR. CLAUDE_USAGE_PATH=/data/claude-usage/claude-usage.json # Age (seconds) past which GET /claude-usage reports stale: true. Default 2700. CLAUDE_USAGE_STALE_SECONDS=2700