| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 |
- # =============================================================================
- # IRDB — IP Reputation Database — environment configuration
- # =============================================================================
- # Copy this file to `.env` and fill in the blanks.
- # Generate 32-byte hex secrets with: openssl rand -hex 32
- # =============================================================================
- # -----------------------------------------------------------------------------
- # Shared (consumed by both api and ui containers)
- # -----------------------------------------------------------------------------
- # IRDB-format service token. The api uses this to authenticate the ui's
- # calls; the ui presents it on every API request together with
- # X-Acting-User-Id. Format: irdb_svc_<32 base32 chars>. Generate one with:
- # docker compose run --rm -T api php -r 'require "/app/vendor/autoload.php";
- # echo (new App\Domain\Auth\TokenIssuer())->issue(App\Domain\Auth\TokenKind::Service);'
- UI_SERVICE_TOKEN=
- # -----------------------------------------------------------------------------
- # api container
- # -----------------------------------------------------------------------------
- APP_ENV=production # development | production
- LOG_LEVEL=info
- # Database
- DB_DRIVER=sqlite # sqlite | mysql
- DB_SQLITE_PATH=/data/irdb.sqlite
- DB_MYSQL_HOST=
- DB_MYSQL_PORT=3306
- DB_MYSQL_DATABASE=
- DB_MYSQL_USERNAME=
- DB_MYSQL_PASSWORD=
- # OIDC role mapping (defaults applied if no group mapping matches)
- OIDC_DEFAULT_ROLE=viewer # viewer | none
- # Reputation engine
- SCORE_RECOMPUTE_INTERVAL_SECONDS=300
- SCORE_REPORT_HARD_CUTOFF_DAYS=365
- # Internal jobs
- INTERNAL_JOB_TOKEN= # 32-byte hex (api refuses to boot if shorter than 32 hex chars)
- # Comma- or whitespace-separated CIDR list of sources allowed to reach
- # /internal/*. Empty (the default) means loopback-only (127.0.0.1/32 +
- # ::1/128). The bundled `compose.scheduler.yml` shares the api's network
- # namespace, so its calls hit loopback and need no extra entries.
- # Production topologies that genuinely need extra sources (host cron on
- # a private bridge, etc.) list them here AND mirror them into the api
- # Caddyfile's @internal matcher.
- INTERNAL_CIDR_ALLOWLIST=
- # Comma- or whitespace-separated CIDR list of trusted reverse-proxy IPs
- # whose `X-Forwarded-For` header Caddy should honour for REMOTE_ADDR
- # rewriting. Default (loopback-only) means no XFF rewriting from any
- # real client. Set to your reverse proxy's CIDR (e.g. "10.0.0.5/32") if
- # the api sits behind one — required for accurate audit-log source IPs.
- # SEC_REVIEW F25: never include broad RFC1918 ranges in deployments
- # where untrusted neighbours can reach the api on the same docker bridge.
- TRUSTED_PROXIES=
- # HSTS header value — applied prod-only by both Caddyfiles. Default is
- # 1 year + subdomains, NO preload (preload-listing is a one-way
- # commitment; browser preload removals take months). Operators who
- # want to apply for the HSTS preload list at https://hstspreload.org/
- # set:
- # HSTS_HEADER="max-age=31536000; includeSubDomains; preload"
- # SEC_REVIEW F60.
- HSTS_HEADER=
- JOB_RECOMPUTE_MAX_RUNTIME_SECONDS=240
- JOB_RECOMPUTE_MAX_ROWS_PER_TICK=5000
- JOB_AUDIT_RETENTION_DAYS=180
- JOB_GEOIP_REFRESH_INTERVAL_DAYS=7
- # Manual blocks / allowlist evaluator
- # In-process cache TTL for the CidrEvaluator. Mutations invalidate explicitly,
- # so this only matters for cross-replica visibility (per replica is fine).
- CIDR_EVALUATOR_TTL_SECONDS=60
- # Distribution endpoint
- # Per-policy blocklist cache TTL. Mutations to policies / manual_blocks /
- # allowlist invalidate explicitly; this is the cross-replica window.
- BLOCKLIST_CACHE_TTL_SECONDS=30
- # GeoIP / ASN enrichment
- # Three pluggable MMDB providers — pick one. The on-disk paths below are
- # provider-agnostic; the refresh-geoip job atomic-replaces them with the
- # selected provider's files.
- # - dbip (default, no auth required, CC BY 4.0 — UI shows attribution)
- # - maxmind (opt-in, requires MAXMIND_LICENSE_KEY)
- # - ipinfo (opt-in, requires IPINFO_TOKEN — UI shows attribution)
- GEOIP_ENABLED=true
- GEOIP_PROVIDER=dbip
- GEOIP_COUNTRY_DB=/data/geoip/country.mmdb
- GEOIP_ASN_DB=/data/geoip/asn.mmdb
- MAXMIND_LICENSE_KEY=
- IPINFO_TOKEN=
- # CORS — origin of the ui container (or future SPA frontend)
- UI_ORIGIN=http://localhost:8080
- # Rate limiting (public API)
- API_RATE_LIMIT_PER_SECOND=60
- # -----------------------------------------------------------------------------
- # ui container
- # -----------------------------------------------------------------------------
- # (APP_ENV / LOG_LEVEL above are reused; the ui reads its own copies of those.)
- PUBLIC_URL=http://localhost:8080
- # Where the ui finds the api (internal docker network DNS)
- API_BASE_URL=http://api:8081
- # OIDC (Entra ID) — lives in ui only
- OIDC_ENABLED=true
- OIDC_ISSUER=https://login.microsoftonline.com/<tenant>/v2.0
- OIDC_CLIENT_ID=
- OIDC_CLIENT_SECRET=
- OIDC_REDIRECT_URI=https://reputation.example.com/oidc/callback
- # Local admin — lives in ui only
- LOCAL_ADMIN_ENABLED=true
- LOCAL_ADMIN_USERNAME=admin
- # Generate with: php -r "echo password_hash('s3cret', PASSWORD_ARGON2ID);"
- LOCAL_ADMIN_PASSWORD_HASH=
- # Optional BCP 47 locale fallback for date/time formatting (e.g. "de-CH",
- # "en-GB"). The browser's locale wins; this is appended as a fallback so
- # JavaScript's Intl.DateTimeFormat picks something sensible if the
- # browser's preference isn't supported. Empty = browser-only.
- UI_LOCALE=
- # How often (seconds) the UI re-validates the cached user role/identity
- # against `GET /api/v1/admin/me`. Lower = faster propagation of Entra
- # group changes and explicit user-disable actions; higher = fewer api
- # calls per active user. Default 300 (5 min).
- UI_SESSION_REVALIDATE_SECONDS=300
|