Autenticación
Autentícate contra la API de KLA Control Plane con inicio de sesión OAuth 2.0 para personas y cuentas de servicio de client-credentials para máquinas.
Cada llamada a la API de KLA Control Plane se autentica con un token de acceso bearer OAuth 2.0 de corta duración y queda acotada a un único tenant. El KLA Control Plane es una capa de seguridad, auditoría y gobernanza en tiempo de ejecución que gobierna en el lugar (govern-in-place) para agentes de IA empresariales; su API es la forma en que registras agentes, evalúas políticas, enrutas aprobaciones y extraes evidencias. Esta página explica los dos tipos de credenciales, cómo obtener un token, cómo llamar a la API y cómo mantener las credenciales con el mínimo privilegio y debidamente rotadas.
Dos tipos de credenciales
KLA emite tokens a través de su proveedor de identidad, un servicio OpenID Connect (OIDC). El flujo que uses depende de quién realiza la llamada.
| Inicio de sesión interactivo | Cuenta de servicio | |
|---|---|---|
| Quien llama | Una persona en la Console (la aplicación web de KLA) | Un servicio de backend, un script o una tarea de CI |
| Flujo | OAuth 2.0 / OIDC con PKCE | OAuth 2.0 client credentials |
| Secreto | Ninguno almacenado por la aplicación | client_id + client_secret |
| Identidad | Una persona, con sus roles | Un principal de máquina que tú creas |
| Úsalo para | Revisar el Decision Desk, construir políticas | Llamadas a SDK y API, automatización |
El inicio de sesión interactivo es lo que usa la Console. El navegador ejecuta el flujo OAuth 2.0 de Authorization Code con PKCE (Proof Key for Code Exchange), de modo que ningún client secret reside jamás en el código del front-end. No tienes que implementarlo tú mismo; viene incluido con la Console.
Las cuentas de servicio son las que usan tus integraciones. KLA crea un cliente de cuenta de servicio para tu tenant bajo petición; le concedes los roles mínimos que necesita e intercambias su client_id y client_secret por un token de acceso usando el grant de client-credentials. Un agente que solicita decisiones o propone acciones no necesita una cuenta de servicio: un administrador del tenant crea para él una clave API con alcances definidos (consulta Claves de API más abajo), y los SDK de gobernanza aceptan esa clave.
flowchart LR H["Persona en la Console"] -->|"Inicio de sesión PKCE"| IDP["Proveedor de identidad de KLA"] M["Servicio de backend"] -->|"client credentials"| IDP IDP -->|"token bearer"| API["API de KLA Control Plane"]
Obtener un token de cuenta de servicio
Intercambia tus credenciales de cliente en el endpoint de token del proveedor de identidad. La ruta del realm es tu tenant, así que sustituye <tenant> por el slug de tu tenant.
curl -s -X POST \
"https://auth.kla.digital/realms/<tenant>/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=svc-claims-triage" \
-d "client_secret=$KLA_CLIENT_SECRET"
La respuesta es un objeto JSON que contiene el token de acceso bearer y su tiempo de vida en segundos. El ejemplo siguiente muestra una respuesta de un realm de dev; cada entorno configura su propio tiempo de vida, así que lea expires_in en cada respuesta:
{
"access_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6...",
"expires_in": 1800,
"token_type": "Bearer",
"scope": "agents:read decisions:write"
}
Captura el token para las llamadas que siguen:
export KLA_ACCESS_TOKEN=$(curl -s -X POST \
"https://auth.kla.digital/realms/<tenant>/protocol/openid-connect/token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials" \
-d "client_id=svc-claims-triage" \
-d "client_secret=$KLA_CLIENT_SECRET" | jq -r .access_token)
Llamar a la API
Envía el token en el encabezado Authorization. El claim de tenant verificado del token selecciona el tenant actual. El host de la API es https://api.kla.digital. Usa esta comprobación de ida y vuelta para confirmar que tu token funciona:
curl -s https://api.kla.digital/v1/tenants.current \
-H "Authorization: Bearer $KLA_ACCESS_TOKEN"
Una llamada exitosa devuelve el tenant al que está acotado el token:
{
"result": {
"data": {
"json": {
"id": "123e4567-e89b-42d3-a456-426614174000",
"externalId": "acme-prod",
"name": "Acme Corp",
"displayName": "Acme Corp",
"branding": {
"displayName": "Acme Corp",
"logoUrl": null,
"logoMarkUrl": null,
"logoAlt": "Acme Corp",
"accentColor": null,
"coBranding": "kla-first"
}
}
}
}
}
Dos encabezados opcionales tienen significados distintos:
| Encabezado | Comportamiento |
|---|---|
x-kla-tenant-id |
UUID interno del tenant. La autenticación y la pertenencia verificada determinan el tenant. |
x-kla-tenant-external-id |
Selecciona otro tenant por su ID externo cuando el sujeto autenticado tiene una membresía activa en ese tenant. |
Un sujeto sin una membresía activa recibe 403 cuando intenta seleccionar otro tenant:
curl -s https://api.kla.digital/v1/tenants.current \
-H "Authorization: Bearer $KLA_ACCESS_TOKEN" \
-H "x-kla-tenant-external-id: another-tenant"
{ "error": "Tenant access denied" }
La secuencia siguiente muestra el recorrido completo que sigue un cliente de máquina en cada ciclo de token.
sequenceDiagram participant C as Servicio cliente participant IDP as Proveedor de identidad de KLA participant API as API de KLA Control Plane C->>IDP: POST al endpoint de token con client credentials IDP-->>C: access_token más expires_in C->>API: GET v1/tenants.current con bearer API-->>C: 200 payload del tenant Note over C,IDP: En 401 expirado, solicita un token nuevo y reintenta
Claves de API
Las claves de API autentican a un llamante de máquina con scope limitado en el tenant que creó la clave. Crea una clave con la API de Secrets o la CLI y luego almacena el valor devuelto en tu gestor de secretos del lado del servidor. KLA devuelve la clave completa una sola vez.
kla api secrets createApiKey \
--input '{"name":"kyc-onboarding-agent","permissions":["actions:propose","policy:evaluate"],"expiresAt":"2027-01-07"}'
Envía la clave en el encabezado x-kla-api-key. Este es el encabezado de clave de API para el Control Plane.
curl -sG "https://api.kla.digital/v1/approvals.getPending" \
-H "x-kla-api-key: $KLA_API_KEY" \
--data-urlencode 'input={"json":{"limit":1}}'
Un agente con actions:propose envía el mismo cuerpo de propuesta que envían los SDK de gobernanza. Los SDK de gobernanza envían la misma cabecera cuando pasas la clave como apiKey (Node.js) o api_key (Python). También aceptan un token bearer de credenciales de cliente como credential; un cliente usa uno de los dos.
curl -s -X POST "https://api.kla.digital/v1/agent-actions" \
-H "x-kla-api-key: $KLA_API_KEY" \
-H "Content-Type: application/json" \
-d @proposal.json
Un agente con policy:evaluate que ejecuta sus propias herramientas pide una decisión antes de cada llamada a una herramienta. KLA registra la decisión y no ejecuta nada; el agente actúa según el resultado. La herramienta debe ser una entrada activa del Tool Catalog del tenant:
curl -s -X POST "https://api.kla.digital/v1/policy/evaluate" \
-H "x-kla-api-key: $KLA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"context": {
"occurredAt": "2026-10-10T09:00:00Z",
"identifiers": {
"workspaceId": "<tenant external ID>",
"runId": "onboarding-case-1042",
"gateId": "open-account-1",
"agentId": "<agent ID>",
"environment": "production"
},
"action": {
"actionType": "tool_call",
"toolName": "open_customer_account",
"toolArgs": { "risk_score": 15, "pep_match": false, "sanctions_hit": false }
}
},
"policyReference": { "policyId": "kyc-onboarding-gate" }
}'
| Campo | Obligatorio | Significado |
|---|---|---|
context.occurredAt |
sí | Momento en que el agente propuso la acción (ISO 8601). |
context.identifiers.workspaceId |
sí | El ID externo de tu tenant. |
context.identifiers.runId, gateId |
sí | Tus identificadores de la ejecución y de este punto de decisión. Reenviar el mismo runId y gateId con el mismo cuerpo devuelve la decisión registrada; un cuerpo modificado devuelve 409. |
context.identifiers.agentId, environment |
si la política está limitada a ellos | Deben coincidir con scope.agentIds y scope.environments de la política. |
context.action.actionType |
sí | tool_call antes de ejecutar la herramienta, tool_result para su salida. |
context.action.toolName, toolArgs |
sí | La clave del Tool Catalog y los argumentos que leen las reglas de la política. |
policyReference.policyId |
no | Evalúa esta política publicada. Sin ella, KLA resuelve la política cuyo alcance coincide con el contexto. |
KLA deriva la identidad del llamante y los permisos de la herramienta de la clave y del Tool Catalog, por lo que el cuerpo no lleva ningún objeto entitlements. La respuesta decision.decision es allow, warn, require_approval o block. Una decisión require_approval abre una Decision Request en el Decision Desk. Una respuesta 400 enumera cada campo no válido por su ruta completa en issues.paths.
Los scopes de claves de API se amplían únicamente mediante la asignación documentada a continuación. Ninguna otra cadena de scope almacenada concede permisos en el Control Plane.
| Scope de clave de API | Permiso canónico | Acceso al Control Plane |
|---|---|---|
actions:propose |
rol agent_client |
Envía acciones de agente a decisión de política mediante POST /v1/agent-actions y lee, reanuda o cancela sus propias propuestas. |
policy:evaluate |
execution:create |
Solicita una decisión de política mediante POST /v1/guardrails/evaluate o POST /v1/policy/evaluate. |
decisions:read |
approval:list |
Lee la cola de aprobaciones pendientes mediante approvals.getPending. |
Cualquier otro valor de alcance se rechaza al crear la clave con 400 BAD_REQUEST. Una clave solo alcanza las operaciones de sus alcances; cualquier otra solicitud devuelve 403 (api_key_scope_denied).
Revocar una clave de API es permanente. secrets.revoke acepta cualquiera de los dos identificadores que devuelve la respuesta de creación: apiKey.id o secretId. Ambos se resuelven dentro del tenant que realiza la llamada; un identificador desconocido o de otro tenant devuelve NOT_FOUND. Guarda apiKey.id de la respuesta de creación en API_KEY_ID y revoca la clave con él. Crea una clave de reemplazo y actualiza la integración después de revocar una clave.
kla api secrets revoke --set id="$API_KEY_ID"
Tiempo de vida y renovación del token
Los realms de dev emiten actualmente tokens de acceso de 30 minutos (expires_in: 1800). Lee expires_in en cada respuesta de token, ya que cada entorno puede configurar una duración diferente. Nunca fijes ni almacenes en caché un token más allá de su expiración.
- Las cuentas de servicio simplemente solicitan un nuevo token al endpoint de token cuando el actual se acerca a su expiración. El grant de client-credentials no emite un refresh token; volver a ejecutar el intercambio es la renovación.
- Las sesiones interactivas de la Console usan un refresh token independiente y de mayor duración, gestionado por el navegador, para obtener nuevos tokens de acceso de forma silenciosa.
- Un
401 Unauthorizedde la API significa que el token está expirado o no es válido. Solicita un token nuevo y reintenta una vez.
Scopes y roles de mínimo privilegio
Cada token lleva consigo los roles de su principal, y la API autoriza cada solicitud frente a ellos. Concede a una cuenta de servicio solo los roles que requiere su tarea:
- Un agente que emite telemetría necesita acceso de escritura a las trazas, no a la autoría de políticas.
- Un runtime de agente necesita
actions:propose, ypolicy:evaluatesi solicita decisiones antes de actuar. No necesita derechos de despliegue de agentes. - Un monitor de la cola necesita
decisions:ready nada más. - Un exportador de evidencias de solo lectura necesita acceso de lectura a las evidencias y nada más.
Crea una cuenta de servicio por integración para poder revocar o reajustar el scope de un único llamante sin afectar a los demás. Los roles se gestionan en el Agent Registry y en la configuración del tenant de la Console.
Rotar los secretos de las cuentas de servicio
Un client_secret es una credencial de larga duración: trátala como la contraseña de una base de datos. Rótala según un calendario e inmediatamente ante cualquier sospecha de exposición.
Almacena y rota los secretos de las cuentas de servicio en el Secrets Vault, la superficie de la Console para el almacenamiento sensible. Genera allí un nuevo secreto, despliégalo en tu integración, confirma que los nuevos tokens se generan correctamente y, a continuación, retira el secreto antiguo. El Secrets Vault admite secretos solapados durante una rotación, de modo que puedas avanzar sin tiempo de inactividad.
Registros de claves API retiradas
La revocación de una clave API es permanente. El secreto de respaldo de una clave API revocada no tiene una operación de restauración ni de rotación. secrets.get con includeValue: true devuelve NOT_FOUND para un registro revocado, archivado, expirado, ausente o perteneciente a otro tenant. Las lecturas autorizadas de metadatos pueden devolver datos del ciclo de vida de registros revocados o expirados; nunca devuelven el valor del secreto. Crea una clave API nueva y actualiza la integración.
Nunca incrustes un client_secret de larga duración, ni ninguna credencial de cuenta de servicio, en código de navegador, aplicaciones móviles, repositorios públicos o bundles del lado del cliente. Cualquier cosa enviada al dispositivo de un usuario o a un repositorio público queda comprometida. Mantén los secretos de las cuentas de servicio únicamente en el lado del servidor, inyéctalos desde el Secrets Vault o tu gestor de secretos en tiempo de ejecución y usa el inicio de sesión PKCE de la Console para cualquier cosa que toque una persona.
