Saltar a contenido

API HTTP

Todas las rutas HTTP que sirve kubelatch, quién puede llamarlas y qué hacen. La interfaz web usa esta misma API; puedes llamarla con curl con una cookie de sesión.

Quién puede llamar

Acceso Qué hace falta
Anónimo Nada.
Sesión La cookie kubelatch_session de una persona con la cuenta habilitada. Sin ella, 401.
Admin Sesión de una persona con rol de administrador. Sin el rol, 403.
Bearer klt_ Authorization: Bearer klt_…, una credencial de kubelatch.
Token OIDC de Actions El id_token de un job de GitHub Actions en el cuerpo.
Firma de GitHub Cabecera X-Hub-Signature-256 con el HMAC del cuerpo y GITHUB_WEBHOOK_SECRET.

Convenciones de /api

  • Cuerpos JSON de hasta 64 KiB. Se rechazan los campos desconocidos y los datos sobrantes (400); un cuerpo mayor es 413.
  • Todas las respuestas llevan Cache-Control: no-store.
  • Los errores son {"error": "<mensaje en español>"} (ver Errores).
  • Una ruta desconocida bajo /api/ es 404; una ruta conocida con otro método es 405 con cabecera Allow.
  • Las peticiones que modifican (POST, PATCH, DELETE) enviadas por un navegador desde otro origen se rechazan con 403. curl y otros clientes que no son navegadores pasan.

Salud

Método Ruta Acceso Qué hace
GET /healthz Anónimo 200 ok si el proceso está vivo.
GET /readyz Anónimo 200 ok si Postgres responde en 2 s; si no, 503 database unavailable.

Solo admiten GET y HEAD; cualquier otro método es 405.

Proxy

Método Ruta Acceso Qué hace
Cualquiera /clusters/<id>/<ruta de la API de Kubernetes> Bearer klt_ Reenvía la petición al API server del cluster <id> actuando como el dueño de la credencial (impersonación). /clusters/<id> y /clusters/<id>/ equivalen a /. Ignora las cookies. Ver El viaje de una petición.

Los errores del proxy son objetos Status de Kubernetes, para que kubectl los muestre bien (Errores del proxy). /clusters sin barra responde 404.

CI y GitHub (fuera de /api)

Estas dos rutas no usan sesión, cookies ni la protección de origen: la autenticación viaja en la propia petición. Solo admiten POST (405 con Allow para lo demás).

Método Ruta Acceso Qué hace
POST /v1/ci/github-actions/token Token OIDC de Actions Canjea {"token": "<id_token>"} por una credencial de bot según la trust rule que coincida. Responde 201 con credential, token, kubeconfig, clusters y expires_at, una sola vez. Límite: 60 peticiones por minuto e IP. Ver Credenciales para GitHub Actions.
POST /v1/github/webhook Firma de GitHub Recibe los eventos de la GitHub App. organization/member_removed deshabilita al momento la cuenta vinculada; installation/deleted o suspend se registran en el log; el resto se acepta y se ignora. Exige Content-Type: application/json y un cuerpo de hasta 1 MiB. Sin GITHUB_WEBHOOK_SECRET responde 404.

Sesión y cuenta propia

Método Ruta Acceso Qué hace
POST /api/auth/login Anónimo Login con contraseña: {"login", "password"}. Abre sesión y devuelve la cuenta.
POST /api/auth/logout Sesión Cierra todas las sesiones de la persona. 204.
POST /api/auth/link Anónimo Consulta un enlace de invitación o vinculación sin consumirlo: {"token": "kli_…"} → login, display_name, purpose, expires_at, github_required.
POST /api/auth/link/complete Anónimo Completa un enlace fijando la contraseña: {"token", "password"}. Abre sesión.
GET /api/me Sesión La cuenta propia: login, nombre, email, admin, si tiene y puede usar contraseña, cuenta de emergencia y vínculo con GitHub.
POST /api/me/password Sesión Cambia la contraseña propia: {"current_password", "new_password"}. Cierra las demás sesiones.

Login con GitHub

Método Ruta Acceso Qué hace
GET /api/auth/methods Anónimo {"github": <booleano>, "org": "<org>"}: qué ofrece la página de login.
GET /api/auth/github/login Anónimo Fija la cookie de estado y redirige (302) a GitHub para autorizar la App.
GET /api/auth/github/callback Anónimo con cookie de estado Vuelta desde GitHub. Redirige a / con sesión, a /mi-cuenta?github=linked tras vincular desde «Mi cuenta», o a /login?error=<código> (/mi-cuenta?error=<código>) si falla.
POST /api/auth/github/link Anónimo Empieza a completar un enlace de invitación o vinculación con GitHub: {"token": "kli_…"} → {"url"} a la que navegar.
POST /api/me/github/link Sesión Empieza a vincular la cuenta propia, si aún no está vinculada (409 si ya lo está) → {"url"}.
GET /api/github/status Admin Configuración (configured, org, webhook, require_org_2fa) y resultado de la última sincronización de miembros (last_sync).

Sin GitHub configurado, /api/auth/github/login, /api/auth/github/callback, /api/auth/github/link y /api/me/github/link responden 404.

Usuarios y bots

Todas requieren admin.

Método Ruta Qué hace
GET /api/subjects Lista personas y bots.
POST /api/subjects Crea una persona ({"login", "display_name", "email", "is_admin"}) y devuelve su invite_link una sola vez; o un bot ({"kind": "bot", "login", "display_name"}).
PATCH /api/subjects/{id} Cambia display_name, email o is_admin de una persona.
POST /api/subjects/{id}/reset-link Genera un enlace de reset o de vinculación (24 h) y lo devuelve una vez como reset_link. Revoca los pendientes y cierra al momento las sesiones de esa persona. 409 si la cuenta está deshabilitada.
POST /api/subjects/{id}/disable Deshabilita a una persona o un bot: cierra sesiones y revoca credenciales.
POST /api/subjects/{id}/enable Rehabilita. Las credenciales revocadas siguen revocadas.
POST /api/subjects/{id}/logout Cierra todas las sesiones de una persona.
DELETE /api/subjects/{id}/github Desvincula la cuenta de GitHub de una persona y cierra sus sesiones.

Clusters

Todas requieren admin.

Método Ruta Qué hace
GET /api/clusters Lista los clusters con estado, última reconciliación y último error.
POST /api/clusters Registra un cluster: {"id", "name"}. El id es el slug de la URL del proxy.
GET /api/clusters/{id} Un cluster.
DELETE /api/clusters/{id} Limpia el RBAC que kubelatch gestiona en el cluster y borra el cluster, sus permisos y sus credenciales restringidas. Devuelve rbac_cleanup con status (ok, error o skipped), error, bindings_deleted, roles_deleted y lock_held.
GET /api/clusters/{id}/bootstrap.yaml Descarga el manifiesto de bootstrap para aplicarlo en el cluster.
POST /api/clusters/{id}/tokens Pega el JSON del bootstrap: {"server", "ca", "proxyToken", "reconcilerToken"}. Valida, cifra y lanza la primera reconciliación.
GET /api/clusters/{id}/namespaces Namespaces del cluster con su nivel PSA (psa_enforce).
POST /api/clusters/{id}/reconcile Reconcilia ahora, de forma síncrona. 502 con el error si falla el lado del cluster; 409 si hay otra pasada en curso o faltan tokens.

Permisos

Método Ruta Acceso Qué hace
GET /api/grants Sesión Lista permisos. Filtros: subject, cluster, include_revoked=true. Sin rol de admin, solo los propios (403 si pides otro sujeto).
POST /api/grants Admin Concede: {"subject_id", "cluster_id", "tier", "scope", "expires_at", "note"}.
DELETE /api/grants/{id} Admin Revoca un permiso.
GET /api/tiers Sesión Catálogo de niveles, namespaces protegidos y si se exige PSA.

Credenciales

Método Ruta Acceso Qué hace
GET /api/credentials Sesión Inventario: un admin ve todas; una persona, las suyas.
POST /api/credentials Sesión Emite una credencial: {"ttl", "name", "note", "cluster_id", "subject_id"}. ttl es obligatorio (7d, 12h). Sin cluster_id, vale en todos los clusters donde el sujeto tenga permisos. Solo un admin emite para otro sujeto. Devuelve token y kubeconfig una sola vez.
POST /api/credentials/{id}/revoke Sesión (dueño o admin) Revoca una credencial. Cuerpo opcional {"reason"}.

Auditoría

Método Ruta Acceso Qué hace
GET /api/audit Sesión Peticiones al proxy, de 50 en 50. Filtros: subject, cluster, namespace, verb, resource, credential, from y to (RFC 3339), include_discovery=true, page (1 a 10000). Sin rol de admin, solo las propias.
GET /api/audit/{id} Sesión Una petición por su Audit-ID. La de otra persona responde 404 si no eres admin.
GET /api/control-events Admin Acciones del plano de control e intentos de login, de 50 en 50. Filtro: page.

Por defecto /api/audit oculta las filas sin recurso (descubrimiento de la API y fallos de autenticación); include_discovery=true las muestra. Ambos listados responden events, page, page_size y has_more.

Trust rules de CI

Todas requieren admin.

Método Ruta Qué hace
GET /api/ci/trust-rules Lista las reglas y además la audiencia, el emisor, la duración de los tokens y la ruta de intercambio que debe usar un workflow.
POST /api/ci/trust-rules Crea una regla: {"name", "bot_subject_id", "repository_owner_id", "repository_id", "ref", "environment"}. ref y environment vacíos valen para cualquiera.
DELETE /api/ci/trust-rules/{id} Borra una regla. No revoca las credenciales ya emitidas.

Interfaz web

Cualquier otra ruta sirve la SPA embebida: el fichero si existe o index.html para las rutas de la interfaz (/login, /cuenta, /mi-cuenta, /admin/…). Un fichero ausente bajo /assets/ es 404. Solo admite GET y HEAD.