Add secure SECRET_KEY generation and improve key documentation
- Update config.py to auto-generate a secure SECRET_KEY if not provided - Add warning log when using an auto-generated key - Update README with clearer information about the two different keys - Add detailed security notes explaining each key's purpose
This commit is contained in:
parent
90c1cdef34
commit
493289730d
15
README.md
15
README.md
@ -23,7 +23,7 @@ A FastAPI application that aggregates news from various sources using the Medias
|
||||
## Requirements
|
||||
|
||||
- Python 3.8+
|
||||
- Mediastack API key
|
||||
- Mediastack API key (required for fetching news data)
|
||||
|
||||
## Setup
|
||||
|
||||
@ -34,7 +34,12 @@ A FastAPI application that aggregates news from various sources using the Medias
|
||||
```
|
||||
3. Set up environment variables:
|
||||
```
|
||||
# Required for fetching news from Mediastack API
|
||||
MEDIASTACK_API_KEY=your_api_key_here
|
||||
|
||||
# Optional - For JWT authentication security
|
||||
# If not set, a secure random key will be generated on startup
|
||||
# but JWT tokens will be invalidated when the server restarts
|
||||
SECRET_KEY=your_secret_key_here
|
||||
```
|
||||
|
||||
@ -71,6 +76,14 @@ The API is documented with Swagger UI, available at `/docs` when the server is r
|
||||
- `app/services`: Business logic services
|
||||
- `migrations`: Database migrations
|
||||
|
||||
## Security Notes
|
||||
|
||||
The application uses two distinct keys for different purposes:
|
||||
|
||||
1. **Mediastack API Key**: Used to authenticate with the external Mediastack news API service. This key is required to fetch news data.
|
||||
|
||||
2. **Secret Key**: Used internally for JWT token generation and verification in the authentication system. If not provided via the SECRET_KEY environment variable, a secure random key will be generated automatically on each startup. Note that this means all active JWT tokens will be invalidated when the server restarts.
|
||||
|
||||
## Development
|
||||
|
||||
To run linting checks:
|
||||
|
@ -1,9 +1,13 @@
|
||||
from typing import List, Union
|
||||
import logging
|
||||
import secrets
|
||||
from pathlib import Path
|
||||
|
||||
from pydantic import AnyHttpUrl, field_validator
|
||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Settings(BaseSettings):
|
||||
model_config = SettingsConfigDict(env_file=".env", case_sensitive=True)
|
||||
@ -30,8 +34,22 @@ class Settings(BaseSettings):
|
||||
MEDIASTACK_BASE_URL: str = "http://api.mediastack.com/v1"
|
||||
|
||||
# Security
|
||||
SECRET_KEY: str = "your-secret-key-here"
|
||||
SECRET_KEY: str = ""
|
||||
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 # 8 days
|
||||
|
||||
@field_validator("SECRET_KEY", mode="before")
|
||||
@classmethod
|
||||
def generate_secret_key_if_needed(cls, v: str) -> str:
|
||||
"""Generate a secure secret key if none is provided."""
|
||||
if not v:
|
||||
generated_key = secrets.token_hex(32)
|
||||
logger.warning(
|
||||
"No SECRET_KEY provided. Using a randomly generated key. "
|
||||
"This is OK for development but not recommended for production. "
|
||||
"The authentication tokens will be invalidated on server restart."
|
||||
)
|
||||
return generated_key
|
||||
return v
|
||||
|
||||
# Database
|
||||
DATABASE_PATH: Path = Path("/projects/newsaggregationservice-ks0ts2/app/storage/db/db.sqlite")
|
||||
|
Loading…
x
Reference in New Issue
Block a user