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
|
## Requirements
|
||||||
|
|
||||||
- Python 3.8+
|
- Python 3.8+
|
||||||
- Mediastack API key
|
- Mediastack API key (required for fetching news data)
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
@ -34,7 +34,12 @@ A FastAPI application that aggregates news from various sources using the Medias
|
|||||||
```
|
```
|
||||||
3. Set up environment variables:
|
3. Set up environment variables:
|
||||||
```
|
```
|
||||||
|
# Required for fetching news from Mediastack API
|
||||||
MEDIASTACK_API_KEY=your_api_key_here
|
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
|
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
|
- `app/services`: Business logic services
|
||||||
- `migrations`: Database migrations
|
- `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
|
## Development
|
||||||
|
|
||||||
To run linting checks:
|
To run linting checks:
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
from typing import List, Union
|
from typing import List, Union
|
||||||
|
import logging
|
||||||
|
import secrets
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from pydantic import AnyHttpUrl, field_validator
|
from pydantic import AnyHttpUrl, field_validator
|
||||||
from pydantic_settings import BaseSettings, SettingsConfigDict
|
from pydantic_settings import BaseSettings, SettingsConfigDict
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
model_config = SettingsConfigDict(env_file=".env", case_sensitive=True)
|
model_config = SettingsConfigDict(env_file=".env", case_sensitive=True)
|
||||||
@ -30,9 +34,23 @@ class Settings(BaseSettings):
|
|||||||
MEDIASTACK_BASE_URL: str = "http://api.mediastack.com/v1"
|
MEDIASTACK_BASE_URL: str = "http://api.mediastack.com/v1"
|
||||||
|
|
||||||
# Security
|
# Security
|
||||||
SECRET_KEY: str = "your-secret-key-here"
|
SECRET_KEY: str = ""
|
||||||
ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24 * 8 # 8 days
|
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
|
||||||
DATABASE_PATH: Path = Path("/projects/newsaggregationservice-ks0ts2/app/storage/db/db.sqlite")
|
DATABASE_PATH: Path = Path("/projects/newsaggregationservice-ks0ts2/app/storage/db/db.sqlite")
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user