1
0

settings.php 3.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. <?php
  2. declare(strict_types=1);
  3. use App\Domain\Auth\Role;
  4. use Monolog\Level;
  5. $appEnv = getenv('APP_ENV') ?: 'production';
  6. if ($appEnv === 'development' && file_exists(__DIR__ . '/../.env')) {
  7. $dotenv = Dotenv\Dotenv::createImmutable(__DIR__ . '/..');
  8. $dotenv->safeLoad();
  9. }
  10. $logLevelName = strtoupper((string) (getenv('LOG_LEVEL') ?: 'info'));
  11. $logLevel = match ($logLevelName) {
  12. 'DEBUG' => Level::Debug,
  13. 'NOTICE' => Level::Notice,
  14. 'WARNING' => Level::Warning,
  15. 'ERROR' => Level::Error,
  16. 'CRITICAL' => Level::Critical,
  17. 'ALERT' => Level::Alert,
  18. 'EMERGENCY' => Level::Emergency,
  19. default => Level::Info,
  20. };
  21. $oidcDefaultRoleName = strtolower((string) (getenv('OIDC_DEFAULT_ROLE') ?: 'viewer'));
  22. $oidcDefaultRole = $oidcDefaultRoleName === 'none'
  23. ? null
  24. : (Role::tryFrom($oidcDefaultRoleName) ?? Role::Viewer);
  25. return [
  26. 'app_env' => $appEnv,
  27. 'log_level' => $logLevel,
  28. 'db' => [
  29. 'driver' => getenv('DB_DRIVER') ?: 'sqlite',
  30. 'sqlite_path' => getenv('DB_SQLITE_PATH') ?: '/data/irdb.sqlite',
  31. 'mysql_host' => getenv('DB_MYSQL_HOST') ?: '',
  32. 'mysql_port' => (int) (getenv('DB_MYSQL_PORT') ?: 3306),
  33. 'mysql_database' => getenv('DB_MYSQL_DATABASE') ?: '',
  34. 'mysql_username' => getenv('DB_MYSQL_USERNAME') ?: '',
  35. 'mysql_password' => getenv('DB_MYSQL_PASSWORD') ?: '',
  36. ],
  37. 'ui_service_token' => getenv('UI_SERVICE_TOKEN') ?: '',
  38. 'internal_job_token' => getenv('INTERNAL_JOB_TOKEN') ?: '',
  39. 'internal_cidr_allowlist' => (string) (getenv('INTERNAL_CIDR_ALLOWLIST') ?: ''),
  40. 'ui_origin' => getenv('UI_ORIGIN') ?: 'http://localhost:8080',
  41. // SEC_REVIEW F68: gate `/api/docs` and `/api/v1/openapi.yaml`
  42. // behind an explicit env flag. The OpenAPI spec leaks the full
  43. // surface (admin endpoints, internal-job endpoints, expected
  44. // body shapes, error contracts); reachable-by-default would
  45. // hand a recon attacker the entire menu. Operators who want
  46. // public docs (open APIs, dev environments) set
  47. // `API_DOCS_PUBLIC=true`. Default false → both routes 404.
  48. 'api_docs_public' => filter_var(getenv('API_DOCS_PUBLIC') ?: 'false', FILTER_VALIDATE_BOOL),
  49. 'oidc_default_role' => $oidcDefaultRole,
  50. 'score_hard_cutoff_days' => (int) (getenv('SCORE_REPORT_HARD_CUTOFF_DAYS') ?: 365),
  51. 'rate_limit_per_second' => (int) (getenv('API_RATE_LIMIT_PER_SECOND') ?: 60),
  52. 'job_recompute_max_runtime_seconds' => (int) (getenv('JOB_RECOMPUTE_MAX_RUNTIME_SECONDS') ?: 240),
  53. 'job_recompute_max_rows_per_tick' => (int) (getenv('JOB_RECOMPUTE_MAX_ROWS_PER_TICK') ?: 5000),
  54. 'job_audit_retention_days' => (int) (getenv('JOB_AUDIT_RETENTION_DAYS') ?: 180),
  55. 'cidr_evaluator_ttl_seconds' => (int) (getenv('CIDR_EVALUATOR_TTL_SECONDS') ?: 60),
  56. 'blocklist_cache_ttl_seconds' => (int) (getenv('BLOCKLIST_CACHE_TTL_SECONDS') ?: 30),
  57. 'geoip' => [
  58. 'enabled' => filter_var(getenv('GEOIP_ENABLED') ?: 'true', FILTER_VALIDATE_BOOL),
  59. 'provider' => strtolower((string) (getenv('GEOIP_PROVIDER') ?: 'dbip')),
  60. 'country_db' => getenv('GEOIP_COUNTRY_DB') ?: '/data/geoip/country.mmdb',
  61. 'asn_db' => getenv('GEOIP_ASN_DB') ?: '/data/geoip/asn.mmdb',
  62. 'maxmind_license_key' => getenv('MAXMIND_LICENSE_KEY') ?: '',
  63. 'ipinfo_token' => getenv('IPINFO_TOKEN') ?: '',
  64. 'refresh_interval_days' => (int) (getenv('JOB_GEOIP_REFRESH_INTERVAL_DAYS') ?: 7),
  65. ],
  66. ];