Autenticación y acceso

Truke KF resuelve cada petición —una sesión de navegador, un inicio de sesión único, una petición tras un proxy corporativo o una llamada de API— a un único registro de usuario en la base de datos de KF. Ese registro lleva las etiquetas de acceso del usuario (ACL). La autenticación es cómo demuestras quién eres; la ACL es lo que tienes permitido ver. Ambas se mantienen separadas: sea cual sea la forma de iniciar sesión, el acceso siempre proviene de tu registro de usuario en KF.

Conceptos

Identidad. Cada usuario tiene un uid estable (un identificador corto y sin espacios, que nunca se reutiliza, ni siquiera tras eliminar un usuario), un nombre visible, un correo (siempre presente, usado para notificaciones) y una cadena de etiquetas ACL. Véase control de acceso para el significado de las etiquetas.

Canales de inicio de sesión. Hay cuatro formas de autenticarse. Pueden activarse de forma independiente y usarse a la vez:

CanalPara quiénCómo funciona
Localequipos pequeños, predeterminadousuario + contraseña en la base de datos de KF
OIDCun proveedor de identidad moderno (Google, Entra, Okta, Keycloak)inicio de sesión único; KF habla directamente con el proveedor
Cabeceraempresas con SAML / LDAP / MFAun proxy inverso de confianza autentica y pasa la identidad a KF
Tokenclientes de API y MCPun token de acceso personal enviado como `Authorization: Bearer …`

La autorización es independiente. Ninguno de estos canales concede acceso por sí mismo. Un usuario nuevo aprovisionado por SSO empieza con lo que indique la política de ACL por defecto (por defecto, sin etiquetas — solo ve ítems sin restricción) hasta que un administrador le otorgue etiquetas. Los proveedores de identidad nunca deciden el acceso directamente.

Visión general de la configuración

Toda la autenticación se configura en una sección `[auth]` de kf.ini. A diferencia de las demás secciones, `[auth]` se escribe como un árbol indentado (la primera línea tras la cabecera no lleva `=`):

[auth]
session
  cookie_name kf_session
  ttl         24h
  secret_env  KF_SESSION_SECRET
local
  enabled     true
oidc
  enabled     false
header
  enabled     false
token
  enabled     true
groups
  enabled     false

Los secretos nunca se escriben en kf.ini. Cada secreto se referencia por el nombre de una variable de entorno, mediante una clave terminada en _env. KF lee el valor del entorno al arrancar. Por ejemplo `secret_env KF_SESSION_SECRET` significa que KF usará el valor de KF_SESSION_SECRET:

export KF_SESSION_SECRET="$(openssl rand -hex 32)"

Si activas un canal pero dejas vacío un campo obligatorio, KF se niega a arrancar e indica qué falta — no hay un modo a medio configurar silencioso.

Cuentas locales

Es lo predeterminado y no requiere configuración. Las credenciales viven en la base de datos de KF. Cada usuario tiene nombre de usuario, contraseña y una cadena de etiquetas ACL. Añade, modifica o elimina usuarios desde la interfaz de administración en `/admin/users`.

El inicio de sesión local está activo salvo que lo desactives:

local
  enabled true

Los usuarios creados por SSO no tienen contraseña y no pueden usar el formulario de contraseña; deben usar su canal de inicio de sesión único.

Inicio de sesión único (OIDC)

OIDC delega la autenticación en un proveedor de identidad (IdP) externo —Google, Microsoft Entra, Okta, Keycloak y similares—. El usuario inicia sesión en el proveedor; KF nunca ve la contraseña. La página de inicio ofrece tanto el formulario de contraseña como un botón de inicio de sesión único, de modo que usuarios locales y SSO coexisten.

oidc
  enabled        true
  issuer         "https://accounts.google.com"
  client_id      kf-app
  client_secret_env KF_OIDC_SECRET
  redirect_url   "https://kf.ejemplo.com/oidc/callback"
  jit            true
  default_acl    ""
  uid_claim      preferred_username
  subject_claim  sub
ClaveRequeridaDescripción
issuerURL base del proveedor — KF descubre los endpoints en `…/.well-known/openid-configuration`
client_idID de cliente emitido por el proveedor
client_secret_envNombre de la variable de entorno con el secreto de cliente
redirect_urlDebe coincidir exactamente con el callback registrado en el proveedor: https://kf.ejemplo.com/oidc/callback
jitnoCrear usuarios automáticamente en el primer inicio (véase abajo); por defecto false
default_aclnoEtiquetas asignadas a los usuarios creados automáticamente; por defecto vacío (sin etiquetas)
uid_claimnoClaim del token del que se deriva el uid; por defecto preferred_username
subject_claimnoClaim estable para reconocer a los usuarios que vuelven; por defecto sub

Define el secreto en el entorno antes de arrancar KF:

export KF_OIDC_SECRET="GOCSPX-…"

Aprovisionamiento automático (JIT)

Con `jit true`, el usuario que inicia sesión por primera vez se crea automáticamente. KF deriva un uid de uid_claim (o de la parte local del correo) y reconoce a los usuarios que vuelven por el claim estable subject_claim — nunca solo por el correo, de modo que un cambio de dirección no crea un duplicado ni se apropia de otra cuenta. El nuevo usuario recibe las etiquetas de default_acl (ninguna, por defecto). Su nombre y correo se sincronizan desde el proveedor en cada inicio; su ACL no la toca el SSO — permanece bajo control de KF.

Con `jit false`, solo pueden iniciar sesión los usuarios que ya existen en la base de datos de KF; los desconocidos se rechazan. Para preaprovisionar, añade al usuario en


### Ejemplos de proveedor

Google

issuer "https://accounts.google.com"

Microsoft Entra (Azure AD)

issuer "https://login.microsoftonline.com//v2.0"

Keycloak

issuer "https://keycloak.ejemplo.com/realms/"


Registra `https://kf.ejemplo.com/oidc/callback` como URI de redirección en el
proveedor y copia el ID de cliente y el secreto en `kf.ini` / el entorno.

## SSO empresarial mediante proxy inverso (canal de cabecera)

KF deliberadamente **no** lleva código de SAML, LDAP, Kerberos ni MFA. Cuando
necesites alguno, coloca un proxy inverso (nginx, Caddy o Apache) con un módulo de
autenticación delante de KF. El proxy gestiona el protocolo empresarial y reenvía la
identidad verificada a KF como cabeceras HTTP.

header enabled true user_header X-Authenticated-User email_header X-Authenticated-Email name_header X-Authenticated-Name groups_header X-Authenticated-Groups secret_header X-Auth-Secret shared_secret_env KF_HEADER_SECRET trusted_proxy 127.0.0.1 jit true default_acl ""


Cómo se mantiene seguro KF al confiar en cabeceras:

- **Secreto compartido.** El proxy añade una cabecera secreta (`X-Auth-Secret`) con un
  valor que solo él y KF conocen (`shared_secret_env`). Una petición cuyo secreto
  falte o sea incorrecto se rechaza con `403`, sin importar qué cabeceras de identidad
  lleve. Esto impide que un usuario falsifique `X-Authenticated-User`.
- **Vinculación de red.** KF solo respeta las cabeceras cuando la petición proviene de
  la dirección `trusted_proxy` configurada.
- **Vincula KF a loopback.** KF no debe ser accesible salvo a través del proxy
  (`127.0.0.1:8080`, o una interfaz privada con cortafuegos). Si KF es accesible
  directamente, el canal de cabecera es falsificable.

Genera el secreto y compártelo en ambos lados:

export KF_HEADER_SECRET="$(openssl rand -hex 32)"


Un terminador nginx mínimo (junto a un módulo de autenticación OIDC/SAML como
oauth2-proxy) inyecta la identidad verificada y el secreto en cada petición, y elimina
cualquier copia provista por el cliente:

location / { auth_request /oauth2/auth; auth_request_set $kf_user $upstream_http_x_auth_request_preferred_username; auth_request_set $kf_email $upstream_http_x_auth_request_email;

proxy_set_header X-Authenticated-User $kf_user; proxy_set_header X-Authenticated-Email $kf_email; proxy_set_header X-Auth-Secret "REEMPLAZAR_CON_SECRETO";

proxy_pass http://127.0.0.1:8080; }


El flujo SAML/LDAP/MFA vive enteramente en el proxy; KF solo ve las cabeceras. El
aprovisionamiento funciona igual que con OIDC: con `jit true`, los usuarios se crean a
su primera llegada con la política `default_acl`.

Para confirmar la frontera, una petición falsificada sin secreto nunca debe iniciar
sesión:

curl -is https://kf.ejemplo.com/ -H 'X-Authenticated-User: atacante' | head -n1


## Tokens de acceso para API y MCP

Para el acceso programático —scripts, integraciones y clientes MCP— KF emite **tokens
de acceso personal**. Un token está ligado a tu usuario y lleva exactamente tu acceso;
no concede nada extra.

token enabled true


**Crear un token** (debes haber iniciado sesión). El texto en claro se devuelve
**una sola vez** — guárdalo ahora, no se puede recuperar después:

curl -X POST https://kf.ejemplo.com/auth/tokens \ -d name=ci-pipeline -d ttl=720h

{"id":"a1b2c3d4","token":"f0e1d2…"}


ejemplo 720h para 30 días). Omite ttl para un token que no caduca.

Usar un token enviándolo como credencial bearer:

curl https://kf.ejemplo.com/mcp -H "Authorization: Bearer f0e1d2…"

Revocar un token con el id devuelto al crearlo:

curl -X POST https://kf.ejemplo.com/auth/tokens/a1b2c3d4/revoke

Los tokens se almacenan solo como hash —KF nunca guarda el texto en claro— y un token caducado o revocado se rechaza con 401. El endpoint MCP (`/mcp`) y los endpoints de tokens requieren autenticación; nunca se sirven de forma anónima.

Correspondencia de grupos del proveedor con etiquetas de KF (opcional)

Normalmente un administrador asigna las etiquetas ACL. Si prefieres derivar las etiquetas iniciales de los grupos de tu proveedor de identidad, activa el mapa de grupos. Traduce los nombres de grupo del IdP a etiquetas de KF cuando se aprovisiona un usuario por primera vez; los grupos sin entrada se ignoran. Es una correspondencia que defines en KF — los grupos del proveedor nunca se confían directamente.

groups
  enabled true
  map
    QA-Automotive automotive
    Engineering   eng

Un usuario cuyos grupos del proveedor incluyan QA-Automotive se crea con la etiqueta

gestiona en KF y no se sobrescribe en inicios de sesión posteriores.

## Sesiones y secretos

Tras un inicio de sesión local o SSO correcto, KF establece una cookie de sesión
firmada (`cookie_name`, por defecto `kf_session`) para que las peticiones siguientes no
repitan el inicio. Firma la cookie con un secreto estable del entorno para que las
sesiones sobrevivan a un reinicio:

session cookie_name kf_session ttl 24h secret_env KF_SESSION_SECRET


export KF_SESSION_SECRET="$(openssl rand -hex 32)"


Las peticiones de cabecera y de token no usan la cookie de sesión — llevan su
identidad en cada petición.

## Referencia rápida

| Ruta | Propósito |
|------|-----------|
| `/oidc/login` | Iniciar un inicio de sesión único |
| `/oidc/callback` | URL de retorno OIDC (regístrala en tu proveedor) |
| `/auth/tokens` | `POST` para crear un token de acceso personal |
| `/auth/tokens/{id}/revoke` | `POST` para revocar un token |
| `/mcp` | Endpoint MCP (requiere token o sesión) |
| `/admin/users` | Gestionar usuarios locales y etiquetas ACL |