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.