Switch JWT signing from HS256 to RS256 (4096-bit RSA)
- Replace symmetric SECRET_KEY with JWT_PRIVATE_KEY / JWT_PUBLIC_KEY (PEM) - Add iat claim to every token - Add expand_newlines validator in config for single-line .env PEM values - Add scripts/generate_jwt_keys.py key-generation helper - Update security-auditor agent JWT checklist with RS256 enforcement rules - Mark RS256 as done in TODO.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
from pydantic import field_validator
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
|
||||
@@ -6,12 +7,20 @@ class Settings(BaseSettings):
|
||||
|
||||
DATABASE_URL: str = "postgresql+asyncpg://postgres:password@localhost:5432/destroying_sap"
|
||||
|
||||
SECRET_KEY: str = "change-me-in-production"
|
||||
ALGORITHM: str = "HS256"
|
||||
# RS256 asymmetric signing — generate keys with scripts/generate_jwt_keys.py
|
||||
ALGORITHM: str = "RS256"
|
||||
JWT_PRIVATE_KEY: str = "" # PEM, required; set via env var
|
||||
JWT_PUBLIC_KEY: str = "" # PEM, required; set via env var
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 8 # 8 hours — no permanent sessions
|
||||
|
||||
CORS_ORIGINS: list[str] = ["http://localhost:5173"]
|
||||
|
||||
@field_validator("JWT_PRIVATE_KEY", "JWT_PUBLIC_KEY", mode="before")
|
||||
@classmethod
|
||||
def expand_newlines(cls, v: str) -> str:
|
||||
"""Allow PEM keys stored on a single line with literal \\n in .env."""
|
||||
return v.replace("\\n", "\n") if isinstance(v, str) else v
|
||||
|
||||
class Config:
|
||||
env_file = ".env"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user