Experimento 2: Seguridad - AndersenCastanedaUniAndes/proyecto-1 GitHub Wiki

Diseño del experimento 2 de arquitectura

Modelos de arquitectura

Vista funcional

Diagrama Funcional

Vista de secuencia

Diagrama Funcionalde secuencia

Vista de infromación

Diagrama datos



Seguridad de acceso (JWT + RBAC + Refresh + Revocación)

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

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.


Patrones de arquitectura

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.


ASR (Rendimiento) p95 <8 ms en validación

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.


Listado de componentes (Microservicio) involucrados en el experimento

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

Tareas especificas

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


Casos funcionales (Sanity check)

(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.

Casos de experimento arquitectónico

(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

Ejecución del experimento:

Contenedores:

Contenedores

Salud del microservicio:

Postman

Metricas redis:

Postman

Crear usuarios y logins (Admin y user):

Usuario Amdin

Crear admin

Login admin

Usuario Regular

Crear usuario regular

Login usuario regular

Prueba RBAC (fail-closed)

Admin lee su usuario

Admin lee su usuario

User regular intenta borrar

User intenta borrar

Admin borra

Admin borra

Revocación de token (lista negra)

Access token vigente (admin o user) comprueba que funciona: GET /users/{id}

Access token vigente

Revoca el refresh token correspondiente

Revocar token Admin

Revocar token User

Obtener usuario con token revocado

Logs del contenedor

Token revocado

Conclusión parcial del experimento:

Caso Descripción
RBAC fail-closed Las rutas protegidas exigen Bearer; con rol insuficiente devuelven 403, con rol correcto 200. No hay “bypass” por ruta.
Revocación efectiva por jti El flujo POST /auth/revoke (con Authorization: Bearer y body { "token": "<token_a_revocar>" }) invalida el token y los usos posteriores responden 401.
Observabilidad útil y segura. /metrics expone latencias y errores del middleware sin PII/secretos. Prometheus y Grafana levantan y consumen métricas.
Despliegue reproducible docker compose levanta app + Postgres + Redis + Prometheus + Grafana + Nginx. El acceso vía http://localhost: es correcto porque los puertos de los contenedores están mapeados al host.

Qué falta para cerrar la hipótesis completa:

Caso Descripción
Resiliencia con Redis caído (fallback SQLite) validar 0 accesos indebidos y revocación operativa sin Redis.
Revocación efectiva por jti El flujo POST /auth/revoke (con Authorization: Bearer y body { "token": "<token_a_revocar>" }) invalida el token y los usos posteriores responden 401.
Rotación de claves bajo tráfico continuidad de servicio y errores espurios ≤ 0.5%.
Rendimiento Medir p95 < 8 ms / p99 < 12 ms en 200–500 rps.
Clock skew ±60 s sin falsos 401 dentro de la tolerancia.
⚠️ **GitHub.com Fallback** ⚠️