Saltar a contenido

Identidad

Cómo sabe kubelatch quién eres, cómo se vincula tu cuenta con GitHub y qué pasa con tu acceso cuando dejas la organización. También explica por qué existen las cuentas de emergencia.

Sujetos: personas y bots

Todo lo que puede tener permisos en kubelatch es un sujeto. Hay dos clases:

  • Personas. Entran en la interfaz web, piden credenciales para sí mismas y pueden ser administradoras.
  • Bots. No tienen contraseña ni sesión: solo credenciales. Un admin emite las suyas desde «Credenciales», o la CI las obtiene canjeando su token OIDC de GitHub Actions (ver trust rules).

Cada sujeto tiene un login inmutable que nunca se reutiliza, ni siquiera tras deshabilitar la cuenta. Es el nombre con el que lo ven los clusters: user:<login> para personas y bot:<nombre> para bots, más el identificador interno del sujeto como uid. Si un login se reciclara, la auditoría nativa del cluster mezclaría a dos personas.

No hay autorregistro. Un admin crea las cuentas desde «Usuarios» y comparte un enlace de invitación de un solo uso (<KUBELATCH_BASE_URL>/cuenta#kli_…, válido 72 h). El token va en el fragmento de la URL, así que no llega a los logs de ningún servidor. La otra vía es la CLI del binario (ver CLI).

Dos modos: contraseñas o GitHub

kubelatch funciona en uno de dos modos, según estén o no las variables GITHUB_*:

Sin GitHub Con la GitHub App
Cómo entran las personas Login y contraseña locales «Entrar con GitHub»
Contraseñas Todas las cuentas Solo las cuentas de emergencia
Doble factor No El que impone la organización de GitHub
Bajas Manuales Automáticas al salir de la organización

El modo sin GitHub no tiene doble factor ni bajas automáticas: sirve para probar kubelatch o para entornos sin GitHub (ver Modelo de seguridad). En producción, configura la GitHub App (Login con GitHub).

Cambiar de modo no toca las cuentas: mismo login, mismos permisos, mismas credenciales. Solo hay que vincular cada cuenta con su cuenta de GitHub.

Vincular una cuenta con GitHub

Vincular es asociar una cuenta de kubelatch con el id numérico de una cuenta de GitHub. kubelatch no usa el login de GitHub como identidad, porque GitHub permite renombrarlo y reciclarlo; lo guarda solo para mostrarlo y lo refresca cuando cambia. Una cuenta de GitHub solo puede estar vinculada a una cuenta de kubelatch.

Hay tres caminos, todos con el mismo resultado:

  • El enlace de invitación de una cuenta nueva lleva a «Vincular con GitHub y entrar».
  • El «Enlace de vinculación» que genera un admin en «Usuarios» (24 h) vincula una cuenta existente, o la cambia a otra cuenta de GitHub. Generarlo ya cierra sus sesiones.
  • Una persona que ya puede entrar usa «Mi cuenta» → «Vincular con GitHub», solo si su cuenta aún no está vinculada.

Desvincular es cosa de un admin («Desvincular GitHub»), y cierra las sesiones de esa persona. No hay alta automática: una cuenta de GitHub que no está vinculada a nadie no entra, aunque sea miembro de la organización.

Qué comprueba el login con GitHub

sequenceDiagram
    participant N as Navegador
    participant K as kubelatch
    participant G as GitHub
    N->>K: «Entrar con GitHub»
    K-->>N: Cookie de estado firmada + redirección
    N->>G: Autoriza la GitHub App
    G-->>N: Redirección al callback con code y state
    N->>K: /api/auth/github/callback
    K->>K: state == cookie
    K->>G: Canjea el code (client secret)
    K->>G: GET /user (id numérico)
    K->>G: Pertenencia activa a la organización
    K->>G: ¿La organización exige 2FA?
    K->>K: Cuenta vinculada a ese id y habilitada
    K-->>N: Sesión y redirección a «Inicio»

Cada paso puede fallar con un código que la página de login traduce (la lista está en Errores). Detalles que importan:

  • Solo miembros activos de la organización configurada. Una invitación pendiente no vale.
  • El state va en una cookie firmada con una clave derivada de KUBELATCH_ENCRYPTION_KEY, válida 10 minutos y limitada a la ruta del callback. El código se canjea en el servidor con el client secret, y el token de GitHub de la persona se descarta tras el login.
  • El callback comparte el límite por IP del login con contraseña.
  • El login con GitHub ignora a propósito el bloqueo por contraseñas fallidas. Si lo respetara, cualquiera podría bloquear a una persona que entra con GitHub probando contraseñas con su login.

Qué pide kubelatch a GitHub

Para qué Con qué token Llamada
Identidad de quien entra El de la persona, solo durante el login GET /user
Pertenencia a la organización El de la persona GET /user/memberships/orgs/<org>, que debe responder state: active
Token de instalación de la App Un JWT RS256 firmado con la clave privada de la App GET /orgs/<org>/installation y POST /app/installations/<id>/access_tokens
Lista de miembros (sincronización) El de instalación GET /orgs/<org>/members?per_page=100, siguiendo la paginación
¿La organización exige 2FA? El de instalación El campo two_factor_requirement_enabled de GET /orgs/<org>. GitHub solo lo devuelve a una App con Administration: read.

Doble factor: lo impone la organización

kubelatch no tiene segundo factor propio. Se apoya en el que la organización de GitHub exige a todos sus miembros. Si la organización lo exige, toda persona que entra con GitHub lo ha pasado.

kubelatch solo puede comprobarlo si la App tiene el permiso Organization → Administration: read. Con él, y con GITHUB_REQUIRE_ORG_2FA en true, rechaza los logins mientras la organización no lo exija. Sin ese permiso, GitHub no le dice nada: kubelatch deja entrar y avisa en cada sincronización. Si no puede preguntar por un fallo real (un 5xx, un timeout), rechaza el login.

En resumen: el 2FA lo garantiza la configuración de la organización, no kubelatch.

Cuentas de emergencia

Con GitHub activo, ninguna contraseña abre sesión salvo las de las cuentas de emergencia (break-glass). Existen para cuando GitHub no está: una caída, la App desinstalada, un error de configuración.

  • Solo se marcan desde la CLI (kubelatch user create --break-glass o kubelatch user set-break-glass), nunca desde la interfaz ni la API.
  • No tienen doble factor. Deben ser pocas, con contraseñas largas en un gestor de secretos, y usarse solo en emergencias.
  • En la página de login, su formulario está bajo «Cuenta de emergencia (contraseña)».
  • Una cuenta de emergencia que se vincula con GitHub queda sujeta a las bajas automáticas como cualquier otra. Las que nunca se vinculan quedan fuera de la sincronización.

kubelatch impide quitar el rol, deshabilitar, desvincular o desmarcar como emergencia al último administrador que puede entrar. Al arrancar con GitHub activo y sin ningún admin que pueda entrar, lo registra como error en el log.

Esto no sustituye al acceso nativo de emergencia a cada cluster, que no depende de kubelatch (ver Cuentas y recuperación).

Bajas automáticas

Con la GitHub App configurada, quien sale de la organización se deshabilita solo, por dos vías:

  • Sincronización horaria. Cada réplica lo intenta una vez por hora (la primera, un minuto después de arrancar) y se turnan con un advisory lock. Lista los miembros de la organización con un token de instalación de la App y deshabilita las cuentas vinculadas cuyo id ya no aparece. Refresca también los logins de GitHub renombrados.
  • Webhook member_removed. Con GITHUB_WEBHOOK_SECRET, GitHub avisa en el momento y la baja es inmediata. La firma HMAC es la autenticación.

La sincronización es conservadora a propósito. Nunca deshabilita ante un error: un 5xx, un timeout, una página que falla, la App desinstalada o una lista con cero miembros abortan la pasada sin tocar a nadie. Y nunca rehabilita: si alguien vuelve a la organización, un admin lo rehabilita a mano.

Por eso la sincronización no corrige una baja indebida, como la que puede causar una entrega repetida del webhook, que no deduplica (ver Modelo de seguridad). Lo que sí corrige es un webhook perdido: da de baja a quien salió aunque la entrega no llegara.

Qué pasa al deshabilitar una cuenta

Da igual quién deshabilite (un admin con «Deshabilitar», la sincronización o el webhook), los efectos son los mismos y ocurren en la misma transacción:

  • Sesiones: todas se cierran al instante. Cada petición a la API recarga la cuenta y rechaza la cookie.
  • Enlaces pendientes de invitación o vinculación: se revocan.
  • Credenciales: todas las vigentes se revocan. La siguiente petición al proxy recibe 401, y los exec o watch abiertos se cortan en 10 s como máximo.
  • Clusters: la siguiente reconciliación saca a la persona de la lista de usuarios que el proxy puede impersonar, y sus bindings si nadie más los sostiene.
  • Permisos: se conservan, pero no cuentan mientras la cuenta esté deshabilitada.

Rehabilitar devuelve el efecto de los permisos, pero no las credenciales: esas quedan revocadas y hay que emitir otras. El TTL máximo de las credenciales (30 días para personas por defecto) acota lo que un olvido podría dejar abierto.

Sesiones

La sesión web es una cookie kubelatch_session firmada, de 12 h, HttpOnly y SameSite=Lax (Secure con una URL base https). Cerrar sesión, cambiar la contraseña, usar un enlace de reset o de vinculación, desvincular GitHub, deshabilitar la cuenta o el «Cerrar sesiones» de un admin invalidan todas las sesiones de esa persona a la vez.

La sesión web no sirve para hablar con los clusters. Para eso hace falta una credencial, que es independiente de la sesión.