Seguridad#
Superficies de ataque#
- API FastAPI (puerto 8096): expone endpoints de Binance, riesgo, jobs, analitica y Ops.
- En produccion/demos externas se opera con
AUTH_ENABLED=true(login multiusuario + JWT). - Endpoints publicos esperados (aun con auth habilitado):
GET /yPOST /auth/login. - Frontend Next.js (puerto 3000): consola operativa. Se protege con middleware (cookie
SDP_AUTH). - Binance API keys: acceso a cuenta (demo/testnet o live). Impacto alto si se filtran.
- Reverse proxy (NPM): expone servicios por dominio; configuracion incorrecta puede dejar endpoints abiertos.
- Proveedores externos: claves
NEWSAPI_KEY,PRIXE_API_KEY,TRADINGECONOMICS_API_KEY/FMP_API_KEY,OPENAI_API_KEY. - PostgreSQL: no debe exponerse al exterior; uso interno en
192.168.100.0/24. - Archivos locales:
storage/models,storage/bi_exports,storage/alerts/alert_state.json.
Autenticacion / Autorizacion#
Login (multiusuario)#
- Backend:
POST /auth/logindevuelveaccess_token(JWT HS256).- Con
AUTH_ENABLED=true, casi toda la API requiereAuthorization: Bearer <token>. - Bootstrap inicial (solo si no existen usuarios):
AUTH_BOOTSTRAP_EMAIL+AUTH_BOOTSTRAP_PASSWORD(+ opcionalAUTH_BOOTSTRAP_ROLE). - Frontend:
/loginguarda token en cookieSDP_AUTHy enlocalStoragepara el cliente HTTP.- El middleware de Next bloquea navegacion sin login.
- Roles:
admin: puede gestionar usuarios (UI/users).viewer(o equivalente): acceso de lectura/operacion limitada (segun endpoints).- Invalidez global de sesiones (forzar relogin):
AUTH_MIN_IAT=<epoch_seconds>invalida cualquier JWT emitido antes de ese instante.- flujo recomendado de rotacion: cambiar
AUTH_JWT_SECRET+ subirAUTH_MIN_IAT(timestamp actual UTC).
Ops (lectura)#
- Opcional:
OPS_READ_TOKENpara proteger endpoints/ops/*con headerX-Ops-Token. - Si
AUTH_ENABLED=true,/ops/*puede pasar middleware conX-Ops-Tokenvalido y luego autoriza en el router de Ops. - Recomendado: mantener ambas capas (
AUTH_ENABLED=true+OPS_READ_TOKEN) para endpoints operativos y timers. - Scripts operativos (
run_ops_daily_brief.py,notify_external_alerts.py) soportanOPS_READ_TOKEN/OPS_TOKENpara leer/ops/*.
Manejo de secretos#
- Local:
.envosetenv.ps1cargados antes de ejecutar scripts. - Externo (CT110):
.envvive fuera de git y es consumido por Docker Compose (deploy/docker-compose.ct110.yml). - Recomendado: gestor de secretos (Vault/Bitwarden/1Password/etc.) para demo/live.
- Nunca commitear
.envni claves (anadir a.gitignore). OPENAI_API_KEYyOPS_READ_TOKENdeben tratarse como secretos de alto impacto (no log, no screenshots, no tickets).- Verificacion rapida antes de commit:
scripts/check_secrets.sh.
Dependencias criticas#
fastapi,uvicorn,sqlalchemy,pydantic,requests,httpx.scikit-learn,numpy,scipy: usados en entrenamiento.
Amenazas y mitigaciones#
| Amenaza | Impacto | Mitigacion |
|---|---|---|
| Fuga de credenciales Binance | Acceso a cuenta demo/live. | Rotar keys, restringir IPs en Binance (si aplica), separar demo/live, usar secrets manager. |
| JWT secret filtrado | Acceso total a endpoints privados. | Rotar AUTH_JWT_SECRET, invalidar sesiones (forzar relogin), limitar acceso a host/FS, no loguear envs. |
| Fuerza bruta al login | Acceso no autorizado. | Rate limit en reverse proxy, lockout en app (pendiente), passwords fuertes, logs y alertas. |
| Cron jobs detenidos | Sin ingestion ni metas; decisiones ciegas. | Monitor externo (TODO) + alertas de no data. |
| Manipulacion de alert_state | Repeticion/omision de alertas. | Restringir permisos sobre storage/alerts, validar integridad. |
| CORS/proxy mal configurado | Exposicion accidental a terceros. | Restringir CORS_ALLOW_ORIGINS, proteger API por auth, exponer solo 80/443 via NPM. |
| Postgres expuesto | Lectura/modificacion total de datos. | Nunca exponer 5432 al exterior, firewall + subred privada, backups cifrados. |
Checklist de seguridad para cada release#
- Revisar
requirements.txtconpip-audit(TODO automatizar en CI). - Confirmar que
AUTH_ENABLED=trueen despliegues externos (demo/prod). - Confirmar que no hay valores sensibles en logs (
rg -i \"(api_secret|jwt|password|secret)\" storage/logs || true). - Validar permisos de archivos
storage/*(solo usuario del servicio). - Ejecutar
spectral lint docs/api/rest-openapi.yamlpara detectar contratos inconsistentes. - Confirmar CORS restringido en produccion:
CORS_ALLOW_ORIGINS=https://sdp.perlatec.net(y otros dominios necesarios).- Ejecutar scanner de secretos local:
scripts/check_secrets.sh