From 4256eb403d5882354b28b71f7acf3268279c0a62 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Thu, 11 Dec 2025 15:56:27 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=92=EF=B8=8F(summary)=20refactor=20con?= =?UTF-8?q?figuration=20secrets=20to=20use=20Pydantic=20SecretStr?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace plain string fields with Pydantic SecretStr class for all sensitive configuration values in FastAPI settings to prevent accidental exposure in logs, error messages, or debugging output, following security best practices for credential handling. --- src/summary/summary/core/celery_worker.py | 11 +++++++---- src/summary/summary/core/config.py | 10 +++++----- src/summary/summary/core/security.py | 2 +- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/summary/summary/core/celery_worker.py b/src/summary/summary/core/celery_worker.py index 1f120bd2..b86063c6 100644 --- a/src/summary/summary/core/celery_worker.py +++ b/src/summary/summary/core/celery_worker.py @@ -93,7 +93,8 @@ class LLMService: def __init__(self): """Init the LLMService once.""" self._client = openai.OpenAI( - base_url=settings.llm_base_url, api_key=settings.llm_api_key + base_url=settings.llm_base_url, + api_key=settings.llm_api_key.get_secret_value(), ) def call( @@ -148,7 +149,9 @@ def format_actions(llm_output: dict) -> str: def post_with_retries(url, data): """Send POST request with automatic retries.""" session = create_retry_session() - session.headers.update({"Authorization": f"Bearer {settings.webhook_api_token}"}) + session.headers.update( + {"Authorization": f"Bearer {settings.webhook_api_token.get_secret_value()}"} + ) try: response = session.post(url, json=data) response.raise_for_status() @@ -195,7 +198,7 @@ def process_audio_transcribe_summarize_v2( minio_client = Minio( settings.aws_s3_endpoint_url, access_key=settings.aws_s3_access_key_id, - secret_key=settings.aws_s3_secret_access_key, + secret_key=settings.aws_s3_secret_access_key.get_secret_value(), secure=settings.aws_s3_secure_access, ) @@ -226,7 +229,7 @@ def process_audio_transcribe_summarize_v2( logger.info("Initiating WhisperX client") whisperx_client = openai.OpenAI( - api_key=settings.whisperx_api_key, + api_key=settings.whisperx_api_key.get_secret_value(), base_url=settings.whisperx_base_url, max_retries=settings.whisperx_max_retries, ) diff --git a/src/summary/summary/core/config.py b/src/summary/summary/core/config.py index cb5c24fb..f7879606 100644 --- a/src/summary/summary/core/config.py +++ b/src/summary/summary/core/config.py @@ -15,7 +15,7 @@ class Settings(BaseSettings): app_name: str = "app" app_api_v1_str: str = "/api/v1" - app_api_token: str + app_api_token: SecretStr # Audio recordings recording_max_duration: Optional[int] = None @@ -32,18 +32,18 @@ class Settings(BaseSettings): aws_storage_bucket_name: str aws_s3_endpoint_url: str aws_s3_access_key_id: str - aws_s3_secret_access_key: str + aws_s3_secret_access_key: SecretStr aws_s3_secure_access: bool = True # AI-related settings - whisperx_api_key: str + whisperx_api_key: SecretStr whisperx_base_url: str = "https://api.openai.com/v1" whisperx_asr_model: str = "whisper-1" whisperx_max_retries: int = 0 # ISO 639-1 language code (e.g., "en", "fr", "es") whisperx_default_language: Optional[str] = None llm_base_url: str - llm_api_key: str + llm_api_key: SecretStr llm_model: str # Transcription processing @@ -54,7 +54,7 @@ class Settings(BaseSettings): webhook_max_retries: int = 2 webhook_status_forcelist: List[int] = [502, 503, 504] webhook_backoff_factor: float = 0.1 - webhook_api_token: str + webhook_api_token: SecretStr webhook_url: str # Output related settings diff --git a/src/summary/summary/core/security.py b/src/summary/summary/core/security.py index d8503e91..5cd5a295 100644 --- a/src/summary/summary/core/security.py +++ b/src/summary/summary/core/security.py @@ -14,6 +14,6 @@ def verify_token( ): """Verify the bearer token from the Authorization header.""" token = credentials.credentials - if token != settings.app_api_token: + if token != settings.app_api_token.get_secret_value(): raise HTTPException(status_code=401, detail="Invalid token") return token