fix: PEM newline parsing + shared config extra=ignore
- Add field_validator to expand literal \n in PEM keys (auth config + shared config) - Set extra='ignore' on shared Settings so service-specific .env vars don't cause ValidationError - Add *.pem to .gitignore
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,6 +13,9 @@ env/
|
||||
# Environment variables
|
||||
.env
|
||||
|
||||
# Cryptographic keys
|
||||
*.pem
|
||||
|
||||
# IDE
|
||||
.vscode/
|
||||
.idea/
|
||||
|
||||
@@ -4,6 +4,7 @@ Contains secrets that ONLY the Auth Service needs (e.g., JWT private key).
|
||||
These are NOT in shared/config.py to prevent other services from accessing them.
|
||||
"""
|
||||
|
||||
from pydantic import field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
@@ -20,6 +21,13 @@ class AuthSettings(BaseSettings):
|
||||
# openssl rsa -in private.pem -pubout -out public.pem
|
||||
JWT_PUBLIC_KEY: str = ""
|
||||
|
||||
@field_validator("JWT_PRIVATE_KEY", "JWT_PUBLIC_KEY", mode="before")
|
||||
@classmethod
|
||||
def _expand_pem_newlines(cls, v: str) -> str:
|
||||
if isinstance(v, str) and r"\n" in v:
|
||||
return v.replace(r"\n", "\n")
|
||||
return v
|
||||
|
||||
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
|
||||
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ of the vars, but keeping one Settings class avoids fragmentation.
|
||||
|
||||
from typing import Literal
|
||||
|
||||
from pydantic import field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
|
||||
@@ -18,6 +19,14 @@ class Settings(BaseSettings):
|
||||
# JWTs locally (optional — Traefik ForwardAuth handles this in prod).
|
||||
# The private key lives ONLY in the Auth Service config.
|
||||
JWT_PUBLIC_KEY: str = ""
|
||||
|
||||
@field_validator("JWT_PUBLIC_KEY", mode="before")
|
||||
@classmethod
|
||||
def _expand_pem_newlines(cls, v: str) -> str:
|
||||
if isinstance(v, str) and r"\n" in v:
|
||||
return v.replace(r"\n", "\n")
|
||||
return v
|
||||
|
||||
JWT_ACCESS_TOKEN_EXPIRE_MINUTES: int = 30
|
||||
JWT_REFRESH_TOKEN_EXPIRE_DAYS: int = 30
|
||||
|
||||
@@ -67,7 +76,9 @@ class Settings(BaseSettings):
|
||||
# ── Environment ──────────────────────────────────────────────────
|
||||
ENV: Literal["dev", "prod"] = "dev"
|
||||
|
||||
model_config = SettingsConfigDict(env_file=".env", env_file_encoding="utf-8")
|
||||
model_config = SettingsConfigDict(
|
||||
env_file=".env", env_file_encoding="utf-8", extra="ignore"
|
||||
)
|
||||
|
||||
|
||||
settings = Settings()
|
||||
|
||||
Reference in New Issue
Block a user