Skip to content

donna.api.auth.config

donna.api.auth.config

Auth config loader with strict validation. Fail-closed on missing keys.

RateLimit dataclass

RateLimit(max: int, window_seconds: int)

max instance-attribute

max: int

window_seconds instance-attribute

window_seconds: int

IPGateConfig dataclass

IPGateConfig(default_trust_duration: str, durations_allowed: list[str], rate_limit_request_access: RateLimit, rate_limit_verify: RateLimit)

default_trust_duration instance-attribute

default_trust_duration: str

durations_allowed instance-attribute

durations_allowed: list[str]

rate_limit_request_access instance-attribute

rate_limit_request_access: RateLimit

rate_limit_verify instance-attribute

rate_limit_verify: RateLimit

ImmichSettings dataclass

ImmichSettings(internal_url: str, external_url: str, admin_api_key_env: str, user_cache_ttl_seconds: int, allowlist_sync_interval_seconds: int, allowlist_stale_tolerance_seconds: int)

internal_url instance-attribute

internal_url: str

external_url instance-attribute

external_url: str

admin_api_key_env instance-attribute

admin_api_key_env: str

user_cache_ttl_seconds instance-attribute

user_cache_ttl_seconds: int

allowlist_sync_interval_seconds instance-attribute

allowlist_sync_interval_seconds: int

allowlist_stale_tolerance_seconds instance-attribute

allowlist_stale_tolerance_seconds: int

DeviceTokenSettings dataclass

DeviceTokenSettings(sliding_window_days: int, absolute_max_days: int, max_per_user: int)

sliding_window_days instance-attribute

sliding_window_days: int

absolute_max_days instance-attribute

absolute_max_days: int

max_per_user instance-attribute

max_per_user: int

EmailSettings dataclass

EmailSettings(from_addr: str, subject: str, verify_base_url: str, token_expiry_minutes: int)

from_addr instance-attribute

from_addr: str

subject instance-attribute

subject: str

verify_base_url instance-attribute

verify_base_url: str

token_expiry_minutes instance-attribute

token_expiry_minutes: int

BootstrapSettings dataclass

BootstrapSettings(admin_email_env: str)

admin_email_env instance-attribute

admin_email_env: str

AuthConfig dataclass

AuthConfig(ip_gate: IPGateConfig, trusted_proxies: list[IPv4Network | IPv6Network], internal_cidrs: list[IPv4Network | IPv6Network], immich: ImmichSettings, device_tokens: DeviceTokenSettings, email: EmailSettings, bootstrap: BootstrapSettings)

ip_gate instance-attribute

ip_gate: IPGateConfig

trusted_proxies instance-attribute

trusted_proxies: list[IPv4Network | IPv6Network]

internal_cidrs instance-attribute

internal_cidrs: list[IPv4Network | IPv6Network]

immich instance-attribute

immich: ImmichSettings

device_tokens instance-attribute

device_tokens: DeviceTokenSettings

email instance-attribute

email: EmailSettings

bootstrap instance-attribute

bootstrap: BootstrapSettings

load

load(path: Path) -> AuthConfig
Source code in src/donna/api/auth/config.py
def load(path: Path) -> AuthConfig:
    data = yaml.safe_load(path.read_text())
    if not data:
        raise ValueError("auth.yaml is empty")

    trusted = _parse_cidrs(data.get("trusted_proxies") or [])
    internal = _parse_cidrs(data.get("internal_cidrs") or [])

    ig = data["ip_gate"]
    rate = ig["rate_limit_per_ip"]
    ip_gate = IPGateConfig(
        default_trust_duration=ig["default_trust_duration"],
        durations_allowed=list(ig["durations_allowed"]),
        rate_limit_request_access=RateLimit(**rate["request_access"]),
        rate_limit_verify=RateLimit(**rate["verify"]),
    )

    im = data["immich"]
    immich = ImmichSettings(
        internal_url=im["internal_url"],
        external_url=im["external_url"],
        admin_api_key_env=im["admin_api_key_env"],
        user_cache_ttl_seconds=int(im["user_cache_ttl_seconds"]),
        allowlist_sync_interval_seconds=int(im["allowlist_sync_interval_seconds"]),
        allowlist_stale_tolerance_seconds=int(im["allowlist_stale_tolerance_seconds"]),
    )

    dt = data["device_tokens"]
    device_tokens = DeviceTokenSettings(
        sliding_window_days=int(dt["sliding_window_days"]),
        absolute_max_days=int(dt["absolute_max_days"]),
        max_per_user=int(dt["max_per_user"]),
    )

    em = data["email"]
    email = EmailSettings(
        from_addr=em["from"],
        subject=em["subject"],
        verify_base_url=em["verify_base_url"],
        token_expiry_minutes=int(em["token_expiry_minutes"]),
    )

    bs = data["bootstrap"]
    bootstrap = BootstrapSettings(admin_email_env=bs["admin_email_env"])

    return AuthConfig(
        ip_gate=ip_gate,
        trusted_proxies=trusted,
        internal_cidrs=internal,
        immich=immich,
        device_tokens=device_tokens,
        email=email,
        bootstrap=bootstrap,
    )