Files
security-alert-center/backend/app/config.py
T
PapaTramp 563b836acc feat: Seaca mobile API, enrollment, FCM push and admin UI (0.9.0)
Adds mobile device registration by admin codes, refresh tokens, push channel
in notification policy, and Settings section for managing Seaca clients.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-10 13:19:14 +10:00

122 lines
4.0 KiB
Python

import os
from functools import lru_cache
from pathlib import Path
from pydantic_settings import BaseSettings, SettingsConfigDict
ROOT = Path(__file__).resolve().parents[2]
SCHEMA_PATH = ROOT / "schemas" / "event-schema-v1.json"
DEFAULT_CONFIG_FILE = Path("/opt/security-alert-center/config/sac-api.env")
def _resolve_config_files() -> tuple[str, ...]:
"""Файлы конфигурации для pydantic (корректный разбор кавычек и URL)."""
candidates: list[Path] = []
explicit = os.environ.get("SAC_CONFIG_FILE", "").strip()
if explicit:
candidates.append(Path(explicit))
else:
candidates.append(DEFAULT_CONFIG_FILE)
candidates.append(Path(".env"))
return tuple(str(p) for p in candidates if p.is_file())
def _settings_config() -> SettingsConfigDict:
files = _resolve_config_files()
return SettingsConfigDict(
env_file=files if files else None,
env_file_encoding="utf-8",
extra="ignore",
)
class Settings(BaseSettings):
model_config = _settings_config()
database_url: str = "postgresql+psycopg2://sac:sac@localhost:5432/sac"
sac_public_url: str = "http://localhost:8000"
jwt_secret: str = "change-me-in-production"
jwt_algorithm: str = "HS256"
jwt_expire_minutes: int = 60 * 24
sac_bootstrap_api_key: str = ""
sac_admin_username: str = "admin"
sac_admin_password: str = ""
event_schema_path: str = str(SCHEMA_PATH)
cors_origins: str = "*"
telegram_enabled: bool = False
telegram_bot_token: str = ""
telegram_chat_id: str = ""
telegram_min_severity: str = "high"
webhook_enabled: bool = False
webhook_url: str = ""
webhook_secret_header: str = ""
webhook_secret: str = ""
webhook_min_severity: str = "high"
smtp_enabled: bool = False
smtp_host: str = ""
smtp_port: int = 587
smtp_user: str = ""
smtp_password: str = ""
smtp_from: str = ""
smtp_to: str = ""
smtp_starttls: bool = True
smtp_ssl: bool = False
smtp_min_severity: str = "high"
notify_min_severity: str = "warning"
notify_channels: str = "telegram,webhook,email"
# F-NOT-03: cooldown исходящих оповещений (dedup_key / fingerprint)
sac_notify_cooldown_enabled: bool = True
sac_notify_event_cooldown_sec: int = 90
sac_notify_problem_cooldown_sec: int = 300
# F-NOT-05: суточные отчёты из агрегации событий SAC (для exclusive / без отчёта агента)
sac_daily_report_enabled: bool = True
sac_daily_report_hour: int = 9
sac_daily_report_timezone: str = "Europe/Moscow"
sac_daily_report_skip_if_agent_sent: bool = True
sac_daily_report_require_activity: bool = True
# Порог «живости» агента
sac_heartbeat_stale_minutes: int = 780
# Периодическое сканирование stale heartbeat (proactive host_silence)
sac_host_silence_scan_enabled: bool = True
sac_host_silence_scan_interval_minutes: int = 5
# Окно корреляции Problems: host + type + rule в одном open Problem
sac_problem_correlation_window_minutes: int = 60
# rule:brute_force_burst — ssh.login.failed / rdp.login.failed
sac_brute_force_window_minutes: int = 15
sac_brute_force_threshold: int = 30
# rule:privilege_spike — privilege.sudo.command
sac_privilege_spike_window_minutes: int = 10
sac_privilege_spike_threshold: int = 10
# Retention (app.jobs.retention / systemd timer)
sac_events_retention_days: int = 90
sac_problems_retention_days: int = 180
# UI login brute-force protection
sac_login_max_failures: int = 3
sac_login_failure_window_minutes: int = 15
sac_login_alert_telegram: bool = True
# Seaca mobile (FCM push)
sac_fcm_enabled: bool = False
sac_fcm_project_id: str = ""
sac_fcm_service_account_json: str = ""
sac_mobile_refresh_expire_days: int = 90
@lru_cache
def get_settings() -> Settings:
return Settings()