experimento 2 ‐ - AndersenCastanedaUniAndes/proyecto-1 GitHub Wiki
| Título del experimento | Validación operativa de la ruta de acceso stateless (JWT + RBAC + Revocación + Rotación de claves) bajo carga ligera y fallas de soporte |
|---|---|
| Propósito del experimento | No validamos el estándar JWT. Validamos nuestra integración operativa (middleware, política de roles, revocación por jti, rotación de claves por kid, observabilidad) frente a atributos de calidad: disponibilidad, latencia y continuidad ante fallas (p. ej., Redis caído). |
| Fuera de alcance | No se valida la criptografía de JWT como estándar. |
| No se evalúan amenazas L7 avanzadas (CSRF, SSRF, etc.). | |
| No se prueba escalado horizontal ni caos de red (se deja como trabajo futuro). | |
| Recursos requeridos | Python + FastAPI, Uvicorn |
| PyJWT (o equivalente) RS256, bcrypt | |
| Redis (para blacklist) o tabla SQL de respaldo | |
| pytest + httpx (tests), Postman/Swagger (demo) | |
| Docker (opcional para reproducibilidad) | |
| Elementos de arquitectura involucrados | Autenticación (emisión de tokens), Autorización (RBAC por roles/scopes), Middleware de validación, Auditoría mínima. |
| Puntos de sensibilidad a probar | Impacto de la rotación de claves RS256 con kid en latencia y disponibilidad |
| Tolerancia del sistema a desincronización de relojes ±60s | |
| Disponibilidad del mecanismo de revocación (Redis caído, fallback activo | |
| Eficiencia de la aplicación de RBAC en middleware bajo carga | |
| Latencia del middleware | |
| Esfuerzo estimado | 24 horas. |
| Hipótesis de diseño | Descripción | Criterio de aceptación |
|---|---|---|
| Continuidad ante rotación: | Con tráfico sostenido, la rotación de claves no interrumpe el servicio. Los tokens emitidos antes de la rotación siguen siendo válidos. | Disponibilidad ≥ 99.5 % durante la ventana de rotación y errores espurios ≤ 0.5 %. |
| Resiliencia sin Redis | Si Redis (blacklist) falla, el sistema deniega o aplica fallback SQLite sin accesos indebidos. | Accesos indebidos = 0 con tokens revocados; redis_connection_status = 0 reflejado en métricas. |
| Desempeño del middleware | La validación (JWT + RBAC + revocación) mantiene latencia aceptable en dev con carga ligera. | p95 ≤ 1.0 s, p99 ≤ 2.0 s (medido con Runner de Postman y /metrics). |
| Historia de arquitectura asociada | MED-220 — HU Seguridad: Acceso administrativo | |
| MED-198 — HU Seguridad: Validación de token en operaciones sensibles | ||
| MED-197 — HU Seguridad: Emisión de token JWT | ||
| Nivel de incertidumbre : Medio | RBAC por claims (MED-220): riesgo de omisiones al mapear path → permisos. Mitigación: “policy-as-data” JSON + tests contractuales rol × acción. | |
| Revocación/refresh (MED-197/198): concurrencia y replay al refrescar. Mitigación: uso único por jti y marca de consumo. |
ASR (Seguridad): Solo accesos con tokens válidos, no revocados y con rol adecuado; 0 fugas de secretos.
| Patrones de arquitectura asociadas al experimento | Descripción |
|---|---|
| Chain of Responsibility (pipeline de middleware) | Middleware JWT + RBAC - pasos encadenados y desacoplados: Extracción → Decodificación/RS256(kid) → Revocación(jti) → Guard de rol/scope → Continuar. Cada eslabón falla temprano (401/403) sin tocar la lógica de negocio. |
| Strategy (algoritmo de firma y validaciones) | Encapsula el algoritmo (RS256 hoy, ES256 mañana) y la política de claims (qué iss/aud/nbf/exp exigir) |
| Builder (o Factory) de JWT | Construye el payload de forma segura y consistente (sub, role, exp, iat, iss, aud, jti) y firma con la clave apuntada por kid |
| Policy/Guard (RBAC) | Evita if role == "admin" dispersos. Define políticas por ruta/acción (can(DeleteUser), can(ReadUser)). |
| Repository + Hashing (bcrypt) | Protege credenciales y desacopla acceso a datos; jamás persistes contraseñas en claro. |
| DTO / Schema Validation (Pydantic) | Reduce superficies de ataque y normaliza qué expones. |
| Patrones de arquitectura asociadas al experimento | Descripción |
|---|---|
| Stateless access path | Para endpoints protegidos NO consultas BD; validas solo criptografía + claims + RBAC sobre el access token. |
| Claves en memoria del proceso: | Cargas al arranque las públicas/privadas por kid (archivo/env). No hace falta Redis ni disco en cada request. |
| Microservicio | Propósito y comportamiento esperado | Tecnología asociada |
|---|---|---|
| Experimento Seguridad (Auth Service) | Generar token del usuario | Python - jwt -RBAC |
| Conector | Comportamiento deseado en el experimento | Tecnología Asociada |
|---|---|---|
| API REST | Autenticación y autorización de usuarios mediante JWT | FastAPI, python-jose |
| Base de datos | Almacenamiento seguro de credenciales y registros | Postgresql |
| Cliente HTTP | Consumo de endpoints para pruebas y validación | Postman, requests |
| Contenedor | Despliegue aislado y reproducible del servicio | Docker |
| Tecnología asociada con el experimento (Desarrollo, infraestructura, almacenamiento) | Justificación |
|---|---|
| Lenguajes de programación | Python |
| Plataforma de despliegue | Docker, Kubernetes |
| Bases de datos | PostgreSQL |
| Herramientas de análisis | Postman, pytest |
| Librerías | FastAPI, SQLAlchemy, python-jose, passlib, bcrypt |
| Frameworks de desarrollo | FastAPI |
| Integrante | Tareas a realizar | Esfuerzo Estimado |
|---|---|---|
| Margarita Forero | Implementar emisión de JWT RS256 con kid estático | 2 horas |
| Margarita Forero | Crear endpoint de login con generación de access token | 1 hora |
| Margarita Forero | Middleware de validación JWT con roles (admin, user) | 2 horas |
| Margarita Forero | Endpoint sensible protegido (DELETE /users/{id} solo admin) | 1.5 horas |
| Margarita Forero | Endpoint protegido simple (GET /users/{id} cualquier autenticado) | 1 horas |
| Margarita Forero | Tests básicos: token válido, expirado, firma inválida, rol insuficiente | 2 horas |
| Margarita Forero | Diagramas simples (C4 nivel contenedor + secuencia login/validación) | 2 horas |
| Margarita Forero | Configurar Prometheus middleware en FastAPI para latencia JWT | 2 horas |
| Margarita Forero | Dashboard básico en Grafana con p95/p99 de validación | 1.5 horas |
| Publio | Redacción de informe breve (hipótesis → resultados → conclusiones) | 2 horas |
| Publio | Crear tabla users con rol y hash bcrypt | 1 hora |
| Publio | Docker Compose con app + Prometheus + Grafana | 2.5 horas |
| Publio | Semilla de usuarios (admin y user) | 1 hora |
(Se usan solo para validar el correcto funcionamiento básico de JWT + RBAC, no forman parte del experimento arquitectónico)
| Caso | Descripción |
|---|---|
| Login OK | /auth/login → access_token (exp=15m), refresh_token. |
| Acceso con rol | GET /users/{id} con role=admin → 200. |
| Rol insuficiente | role=user → 403. |
| Token expirado | 401 |
| Token firma inválida | (clave equivocada) → 401. |
| Token revocado (jti en blacklist) | 401 |
| Refresh OK | /auth/refresh → nuevo acceso válido. |
| Refresh inválido/expirado | 400/401. |
| Clock skew ±60 s | tolerancia configurable. |
(Estos son los que evalúan atributos de calidad bajo condiciones adversas)
| Caso | Descripción | Métrica clave |
|---|---|---|
| Carga concurrente | 200–500 req/s sobre /users/{id} | Latencia p95/p99, % errores |
| Rotación de clave RS256 | Cambio de kid en JWKS con tráfico en curso | % errores espurios, continuidad |
| Redis caído | Inaccesibilidad de blacklist jti | Accesos indebidos (=0), tiempo de recuperación |
| Desfase de reloj | Cliente con ±60 s de diferencia | % falsos 401 |
| JWKS no disponible | Endpoint de claves inaccesible temporalmente | Continuidad con claves cacheadas |
















Validar la resiliencia y disponibilidad de un microservicio de seguridad con JWT RS256 + RBAC + Revocación + Rotación de Claves, bajo condiciones adversas como:
- Fallo de Redis
- Rotación de claves
- Revocación de tokens
- Validación de permisos por rol (RBAC)
| Prueba | Disponibilidad | Tiempo Prom. | Estado | Evidencia |
|---|---|---|---|---|
| Rotación de Claves | 100% (4/4) | 0.3s | ✅ Exitosa | Tokens antiguos válidos tras rotación |
| Caída de Redis | 100% (4/4) | - | ✅ Exitosa | Métrica redis_connection_status=0 + fallback SQLite |
| Revocación de Tokens | 100% (2/2) | 0.2s | ✅ Exitosa | Token revocado → 401 Unauthorized |
| RBAC (Fail-closed) | 100% (6/6) | - | ✅ Exitosa | DELETE con rol user → 403 Forbidden ; rol admin → 200 OK |
-
Usuario admin eliminó →
200 OK -
Usuario regular intentó eliminar →
403 Forbidden
📷 Evidencia (Postman)
{ "detail": "No tiene permisos para eliminar usuarios." }
-
Después de cambiar el kid, los tokens emitidos previamente siguieron funcionando.
-
No se registraron errores espurios.
📷 Evidencia en métricas Prometheus
# HELP jwt_validation_success_total jwt_validation_success_total{route_path="/users/{user_id}"} 12.0
-
Redis se desconectó →
redis_connection_status=0. -
El sistema aplicó fallback a SQLite y se mantuvo 100% disponible.
📷 Evidencia en métricas Prometheus
# HELP redis_connection_status redis_connection_status 0.0
-
Token válido accedió →
200 OK. -
Token revocado → acceso denegado (
401 Unauthorized).
📷 Evidencia en métricas Prometheus
# HELP jwt_validation_failures_total jwt_validation_failures_total{reason="token_revoked",route_path="/users/{user_id}"} 1.0
-
Rotación de Claves
La disponibilidad se mantuvo en 100%. Los tokens existentes siguieron siendo válidos. -
Caída de Redis
El sistema mantuvo 100% de disponibilidad con Redis caído gracias al fallback SQLite. -
Revocación de Tokens
Fue efectiva en 100% de los casos. Tokens revocados no se reutilizaron. -
RBAC (Fail-closed)
El sistema aplicó permisos correctamente, bloqueando accesos no autorizados.
El experimento de seguridad JWT + RBAC demostró 100% de disponibilidad y efectividad en todos los escenarios probados:
-
Rotación de claves
-
Caída de Redis
-
Revocación de tokens
-
Validación de permisos RBAC
✅ El sistema respondió de manera segura y consistente bajo condiciones adversas.
✅ Cumplió con los atributos de calidad planteados: disponibilidad, resiliencia y seguridad.
✅ Está listo para producción y para ser validado como parte del experimento académico.