Configuracion de Secretos¶
GexCom usa Pydantic Settings para gestionar configuracion y secretos via variables de entorno. La clave JWT es validada en startup — una clave por defecto en produccion causa un error inmediato.
Variables de Entorno¶
| Variable | Descripcion | Por defecto | Requerida en prod |
|---|---|---|---|
DATABASE_URL |
URL de conexion PostgreSQL async | SQLite local | Si |
DATABASE_SYNC_URL |
URL de conexion PostgreSQL sync (API) | SQLite local | Si |
SECRET_KEY |
Clave secreta para firmar JWT | changeme-insecure-key |
Si |
JWT_ALGORITHM |
Algoritmo JWT | HS256 |
No |
JWT_EXPIRATION_MINUTES |
Duracion del token en minutos | 480 |
No |
ENVIRONMENT |
Entorno actual | development |
No |
Archivo .env (Desarrollo Local)¶
Crear .env en la raiz del proyecto (ignorado por git):
# .env — NO commitear
DATABASE_URL=sqlite+aiosqlite:///./gexcom_dev.db
DATABASE_SYNC_URL=sqlite:///./gexcom_dev.db
SECRET_KEY=mi-clave-secreta-local-solo-desarrollo
ENVIRONMENT=development
Docker Compose (PostgreSQL)¶
# docker-compose.yml (fragmento)
environment:
- DATABASE_URL=postgresql+asyncpg://gexcom:gexcom_dev@postgres:5432/gexcom
- DATABASE_SYNC_URL=postgresql+psycopg2://gexcom:gexcom_dev@postgres:5432/gexcom
- SECRET_KEY=${SECRET_KEY:-changeme-insecure-key}
- ENVIRONMENT=production
Para produccion, pasar SECRET_KEY como variable de entorno del host:
Validacion en Startup¶
Settings valida que la clave JWT no sea el valor por defecto fuera de development/test:
# src/gexcom/infrastructure/config.py
_DEFAULT_SECRET = "changeme-insecure-key"
class Settings(BaseSettings):
secret_key: str = _DEFAULT_SECRET
environment: str = "development"
@model_validator(mode="after")
def validate_secret_key(self) -> "Settings":
if self.environment not in ("development", "test"):
if self.secret_key == _DEFAULT_SECRET:
raise ValueError(
"SECRET_KEY must be changed in non-development environments. "
"Set the SECRET_KEY environment variable."
)
return self
Si el servidor arranca en environment=production con la clave por defecto, falla inmediatamente con un ValueError claro.
Generar una Clave Segura¶
# Generar clave aleatoria de 256 bits
import secrets
print(secrets.token_hex(32))
# → "a8f5f167f44f4964e6c998dee827110c..."
O con OpenSSL:
Secretos de Dispatch¶
Los dispatchers leen credenciales desde variables de entorno:
# Email SMTP
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=notificaciones@csj-bello.gov.co
SMTP_PASSWORD=app-password-gmail
# WhatsApp Meta API
WHATSAPP_TOKEN=EAAxxxxx
WHATSAPP_PHONE_ID=1234567890
Nunca en el codigo fuente
Los tokens de API, contrasenas SMTP y claves JWT nunca deben aparecer hardcodeados en el codigo. Usar siempre variables de entorno o un gestor de secretos (Vault, AWS Secrets Manager, etc.).
Checklist de Produccion¶
-
SECRET_KEYgenerada consecrets.token_hex(32)y almacenada como variable de entorno -
ENVIRONMENT=productionconfigurado -
DATABASE_URLapunta a PostgreSQL (no SQLite) - Credenciales SMTP configuradas
- Tokens WhatsApp configurados
-
.envexcluido de git (verificar.gitignore) -
Dockerfileno contiene secretos hardcodeados