Resumen — qué hace
InfraGuard tiene dos planos de autenticación:
- Consola web = inicio de sesión por sesión. Un operador entra con
login_id+passwordyAuthControllercrea una sesión propia. A partir de ahí, cada página de la consola pasa por el middlewareinfr.auth(InfrAuth), que comprueba la sesión y vuelve a leer de la base de datos el nivel, el nombre y el idioma del usuario en cada petición para mantener sincronizada la copia guardada en la sesión. - API de ingesta externa = clave de API sin estado (bearer). Cuando una aplicación externa publica incidentes, informes de copia o análisis de seguridad, se autentica con un token de clave de API (
Authorization: Bearer …oX-Infr-Api-Key) a través del middlewareinfr.apikey, no con una sesión. Sin sesión y sin CSRF.
Características clave:
- Resincronización de la sesión — cuando un administrador cambia el nivel, el nombre o el idioma de un usuario, surte efecto desde la petición siguiente sin necesidad de volver a entrar.
- Aplicación a nivel de URL — ocultar elementos del menú no basta. Grupos de rutas como
/security,/backupy/adminimponen el nivel mínimo directamente sobre la URL con el middlewareinfr.level:N. - Acciones destructivas = nueva comprobación de nivel + auditoría — bloquear, restaurar, cambiar ajustes, etc. están protegidos por una barrera de nivel de escritura, un registro en
infr_audit_logy una confirmación en la interfaz.
Cuándo usarlo
- Va a entrar en la consola por primera vez, o le han devuelto de golpe a
/loginy quiere entender por qué. - Está conectando una aplicación Laravel externa a la API de ingesta de incidentes o a la integración del informe de copia y necesita saber qué cabecera la autentica.
- Un administrador cambió un nivel, un nombre o un idioma y usted debe explicar por qué no hace falta volver a entrar.
Disposición
La pantalla de inicio de sesión (/login) es una única tarjeta sencilla.
| Elemento | Descripción |
|---|---|
| Marca · lema | Logotipo Infra**Guard** + «Consola de operación, defensa y resiliencia de infraestructura convergente» |
| Usuario | Campo login_id. autocomplete=username, con el foco puesto automáticamente |
| Contraseña | Campo password + icono de ojo para mostrar/ocultar |
| Aviso de error | Al fallar: «Las credenciales no coinciden con nuestros registros.» |
Campo oculto next |
Ruta de retorno tras el inicio de sesión (debe empezar por /) |
| Botón de envío | «Iniciar sesión →» |
El formulario de acceso lleva un token
@csrfestándar de Blade. La consola está protegida por sesión + CSRF y no pide ningún token bearer aparte en la interfaz.
Cómo usarlo
Iniciar sesión
- Vaya a
/login(si ya tiene la sesión iniciada, se le redirige a/). - Escriba su
Login IDy suPassword.- Validación:
login_idmáximo 60 caracteres,passwordde 4 a 120 caracteres.
- Validación:
- Pulse Iniciar sesión. El servidor busca la cuenta en
infr_userporlogin_id+is_close=0y verifica la contraseña. - Si todo va bien, la sesión se regenera (
session()->regenerate()) y se le envía anext(o a/).
Un inicio de sesión correcto rellena estas claves de sesión:
| Clave de sesión | Valor |
|---|---|
infr_user_id |
infr_user.id (la fuente de verdad de «está autenticado») |
infr_login_id |
Identificador de acceso |
infr_user_level |
user_level (entero) — Nivel RBAC |
infr_name |
Nombre mostrado |
infr_lang |
Idioma de la interfaz (por omisión ko) |
Además, la columna last_log se sella con la hora actual.
Cerrar sesión
- Use el elemento Cerrar sesión del menú desplegable de usuario en la barra superior (o
POST /logout). - El servidor olvida
infr_user_id, invalida la sesión, regenera el token CSRF y redirige a/login.
Duración de la sesión y resincronización en cada petición
Cada página de la consola pasa por infr.auth (InfrAuth), que en cada petición:
- Vuelve a cargar al usuario por el
infr_user_idde la sesión (ruta caliente, columnas mínimas: id · login_id · name · email · user_level · role_id · team_id · lang · avatar · is_close). - Si la cuenta no existe o tiene
is_close=1(desactivada), destruye la sesión y redirige a/login(o devuelve un 401 JSON). - Sobrescribe
infr_user_level·infr_name·infr_langcon los valores de la base de datos, de modo que el cambio de nivel, nombre o idioma hecho por un administrador se refleja desde la petición siguiente sin volver a entrar. - Guarda el modelo de usuario en el atributo de petición
infr_usery fija el idioma de la interfaz conapp()->setLocale(). - Llama a
OpsPolicy::markPresence()para registrar la presencia (el modo económico de la política de operaciones la usa para decidir si «hay ahora mismo un usuario activo en la consola» y regular la recolección de la base de datos; véase Política de operaciones).
La duración de la sesión sigue a SESSION_LIFETIME (120 minutos por defecto).
El acceso a la consola no tiene una casilla «recordarme» aparte. La sesión dura lo indicado arriba; cuando caduca hay que volver a entrar.
Autenticación de la API de ingesta externa (clave bearer)
Cuando una aplicación externa publica en /api/v1/* se autentica con una clave de API (sin estado: sin sesión y sin CSRF).
| Método | Cabecera de ejemplo |
|---|---|
| Bearer | Authorization: Bearer YOUR_KEY |
| Cabecera propia | X-Infr-Api-Key: YOUR_KEY |
Comportamiento:
- El servidor convierte el token recibido en un hash y lo compara en tiempo constante (una comparación de tiempo constante) con
infr_api_key.key_hash(solo claves activas). La clave en claro nunca se almacena. - Límite de 120 peticiones por minuto por clave. Superarlo devuelve
429 rate_limitedy una cabeceraRetry-After. - Cada llamada actualiza
last_used_at·last_used_ip·use_count.
Endpoints principales:
# Comprobación de conectividad / de la clave
curl -sS https://infraguard.example.com/api/v1/ping \
-H "Authorization: Bearer YOUR_KEY"
# Registrar un incidente automáticamente (con deduplicación · source=pulse)
curl -sS -X POST https://infraguard.example.com/api/v1/incidents \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{"title":"NPE in checkout","fingerprint":"abc123","severity":"crit"}'
Emita y revoque claves y copie el código de integración en Administración ▸ Claves API (la clave en claro se muestra solo una vez, al emitirla).
Step-up — proteger las acciones destructivas
Las acciones de riesgo como bloquear, desbloquear, restaurar o cambiar ajustes están protegidas —no por volver a escribir la contraseña— sino por tres defensas:
- Nueva comprobación de nivel — las acciones de escritura exigen al menos el nivel de escritura (2 o más) y las administrativas exigen administrador (10), y se vuelven a verificar en el servidor.
- Registro de auditoría — los valores anterior y posterior, junto con el autor y la IP, se escriben en el registro de auditoría (
infr_audit_log). - Confirmación en la interfaz — un diálogo de confirmación (step-up) protege la acción en pantalla.
Fuentes de datos
| Objeto | Propósito |
|---|---|
infr_user |
Cuentas de operador. Columnas: login_id · password · user_level · name · email · lang · is_close · role_id · team_id · last_log · avatar |
| Almacén de sesiones (Redis) | Claves de sesión como infr_user_id (REDIS_PREFIX infr_) |
infr_api_key |
El hash (key_hash) de las claves de la API de ingesta · is_active · use_count · last_used_at/ip |
infr_audit_log |
Rastro de auditoría de las acciones destructivas o de seguridad |
La columna
infr_user.passwordnunca se expone en registros, URL ni cookies. La clave de API en claro solo se muestra al emitirla; la base de datos guarda únicamente el hash.
Acceso
/login·/logout— accesibles para cualquiera (invitado).- Toda la consola — requiere una sesión válida (
infr.auth). Sin ella, las peticiones de página redirigen a/loginy las peticiones AJAX reciben401 unauthenticated.
Barreras a nivel de URL (se evalúan después del inicio de sesión):
| Área | Middleware | Nivel mínimo |
|---|---|---|
| Consola general (Resumen · Infraestructura · lectura de Activos) | infr.auth |
Solo iniciar sesión (1) |
/security · /backup |
infr.level:2 |
2 |
/admin |
infr.level:10 |
10 |
/horizon · /pulse |
infr.admin |
10 |
| Sección de desarrollo | infr.dev |
9 |
Escalones de nivel: demo=1 · staff=5 · admin=10. Consulte Niveles de acceso para la política completa.
Solución de problemas y preguntas frecuentes
Inicio sesión pero me devuelve una y otra vez a /login.
La cookie de sesión no se está guardando (desajuste de dominio o de SESSION_DOMAIN, o una cookie solo para HTTPS servida por HTTP), o la cuenta quedó con is_close=1 (desactivada). Pida a un administrador que revise el estado de la cuenta.
Veo «Las credenciales no coinciden con nuestros registros.»
Un error de escritura en login_id, una contraseña incorrecta o una cuenta desactivada (is_close=1). Por seguridad, el mensaje no dice cuál de las tres.
Una cuenta no puede iniciar sesión. La contraseña puede ser incorrecta o la cuenta estar desactivada. Un administrador restablece la contraseña en Usuarios y equipos.
Puedo entrar pero no puedo abrir /admin.
Su nivel está por debajo de 10. /admin está protegido por infr.level:10, así que solo llegan los administradores. Del mismo modo, /security y /backup exigen nivel 2 o superior.
Una llamada AJAX devuelve 401.
La sesión de la consola ha caducado. Actualice la página y vuelva a entrar. Las peticiones JSON reciben {"error":"unauthenticated"} con 401 en lugar de una redirección.
Un administrador subió mi nivel pero no se aplicó.
InfrAuth resincroniza la sesión en cada petición, así que se aplica desde la navegación siguiente, sin volver a entrar. Actualice la página para aplicarlo de inmediato.
El menú o la interfaz están en un idioma inesperado.
El idioma de la interfaz sigue a infr_user.lang (la clave de sesión infr_lang) y se resincroniza en cada petición. Cámbielo en Localización.
La API devuelve 401 invalid_api_key / 429 rate_limited.
Una clave inactiva o mal escrita da 401; más de 120 peticiones por minuto dan 429 (+ Retry-After). Compruebe el estado de la clave en Claves API y reduzca el ritmo.
Relacionado
- Niveles de acceso —
user_level↔min_req, escalones demo/staff/admin - Roles y equipos — alcance de los roles y propiedad de los equipos
- Gestión de usuarios y equipos — crear cuentas, restablecer contraseñas, desactivar
- Claves API — emitir claves de la API de ingesta y código de integración
- Localización — idioma de la interfaz y respaldo de locale
- Registro de auditoría — seguimiento de las acciones destructivas
