Autenticación
La API de Dashboard Mágico usa un access token de la Cuenta Kobana para autenticar todas las solicitudes.
El token
El token es un JWT RS256 emitido por el Authorization Server de Kobana (account.kobana.com.br). Esta API solo lo verifica, contra la clave pública que ese servidor publica: no guarda clave de firma y no puede emitir ningún token. El claim org identifica tu organización: todos los datos devueltos quedan automáticamente acotados a ella.
Requisitos verificados en cada solicitud:
| Claim | Exigencia |
|---|---|
iss | El identificador del Authorization Server, como URL: https://account[.{env}].kobana.com.br |
aud | La URL de esta API: https://api.pages[.{env}].kobana.com.br. Puede ser una lista: la regla es contiene, no igualdad |
exp | Obligatorio. Un token sin expiración se rechaza |
org | La cuenta Kobana en cuyo nombre actúa el token: es la que resuelve la organización aquí, y es obligatoria |
sub | La persona (users.public_id). Se usa para auditoría y atribución; no acota nada |
jti | Id único del token: base de la revocación y de la auditoría |
:::caution Cambio respecto a la clave de API
Hasta septiembre de 2026 la credencial era una clave creada en el dashboard (kb_…), con prefijo público y secret mostrado una sola vez. La clave era a la vez la credencial y lo que la verificaba: quien leyera el repositorio de claves actuaba como cualquier organización, y cada rotación era una conversación con un cliente. Ahora quien emite es el Authorization Server, y la plataforma solo verifica. Una clave creada en Configuración → API ya no autentica esta API.
:::
El token es diferente entre Sandbox y Producción: el aud de uno no vale en el otro. No lo reutilices entre entornos.
Cómo enviar el token
Incluye el encabezado Authorization: Bearer <token> en cada solicitud.
export KOBANA_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxx
curl -i \
-H "Authorization: Bearer $KOBANA_TOKEN" \
-H 'Content-Type: application/json' \
-H 'User-Agent: Mi Nombre (minombre@example.com)' \
-X GET 'https://api.dashboards.sandbox.kobana.com.br/v1/organization'
Solicitud válida
Con un token válido, la respuesta trae los datos de la Organización autenticada.
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Request-Id: req_01HABCDEF
{
"id": "org_01HORG",
"name": "Mi Empresa",
"email": "contacto@miempresa.com",
"document_type": "cnpj",
"document_number": "12345678000190",
"environment": "sandbox",
"created_at": "2026-01-01T00:00:00.000Z"
}
Solicitud inválida
Un token ausente, malformado o revocado devuelve 401 Unauthorized.
curl -i \
-H "Authorization: Bearer tokeninvalido" \
-H 'Content-Type: application/json' \
-H 'User-Agent: Mi Nombre (minombre@example.com)' \
-X GET 'https://api.dashboards.sandbox.kobana.com.br/v1/organization'
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
{
"error": {
"code": "invalid_token",
"message": "Token de acceso inválido o expirado."
}
}
Los códigos detallados ayudan a encontrar el error al instante: invalid_token (ausente, malformado o firma inválida), invalid_audience (token de otra app Kobana), token_revoked y unknown_organization; este último es 403: el token es válido, la organización es la que no está aquí.
Si nuestro Authorization Server está caído, la respuesta es 5xx, no 401. Es deliberado: un 401 te haría depurar una credencial perfecta durante nuestra caída. Inténtalo de nuevo en unos instantes.
:::note sub no es el tenant
sub es la persona y org es la organización: son uuids de tablas distintas, así que intercambiarlos no da error de formato. Un token sin org se rechaza en lugar de recurrir a sub: ese fallback no coincidiría con ninguna organización y respondería 403 a todo, con el síntoma apuntando a permisos y no al claim leído.
:::
Scopes
Los scopes del token tienen dos ejes ortogonales: el recurso, siempre con el prefijo de la app (dashboards/users), y el verbo, un scope global sin prefijo (write). Un recurso sin verbo significa lectura. Escribir exige ambos: el scope del recurso y el verbo.
| Scope | Qué alcanza |
|---|---|
dashboards/builder | Constructor del portal: páginas, borrador, publicación y versiones |
dashboards/users | Usuarios del portal y el mapeo que los genera |
dashboards/portal | El portal: acceso, marca, apariencia, SEO, tracking, dominios y proveedores de inicio de sesión |
dashboards/connectors | Conectores (fuentes de datos) |
dashboards/entities | Entidades y sus registros |
dashboards/assets | Biblioteca de archivos |
dashboards/ai | Uso y facturación de IA |
dashboards/workspaces | Workspaces |
dashboards/members | Miembros del panel, roles y permisos |
dashboards/admin | Organización y configuración, notificaciones y plantillas de e-mail, eventos, webhooks, auditoría, claves de API, backups, exportaciones, importaciones, consumo y límites |
| Comodín de recurso | dashboards/all: lee todos los recursos anteriores y no concede ningún verbo |
| Verbo global | write: toda escritura (POST, PUT, PATCH, DELETE) en los recursos que lleva el token |
Dos ejemplos: dashboards/users lee usuarios del portal y no escribe; dashboards/users write también invita, modifica y elimina, y sigue sin alcanzar a los miembros del panel.
La forma granular dashboards/users:write es una excepción de la gramática, no el formato por defecto: satisface ambos ejes solo para ese recurso, y existe para "leo un recurso, escribo otro". dashboards/* es un comodín de registro y nunca se emite en un token: la comparación aquí es siempre literal. No existe el scope read: la lectura es el recurso sin verbo.
:::info Los scopes aún no se exigen
Los scopes anteriores ya son el vocabulario de esta API, pero todavía no se exigen: primero deben registrarse en el Authorization Server y, mientras no lo estén, ningún token en circulación lleva scopes; exigirlos ahora liberaría todo (teatro) o bloquearía todas las integraciones activas. Hoy lo que vincula el token a esta API es el aud, que el verificador exige. Cuando empiece la exigencia, la falta de scope responderá 403 insufficient_scope; pide desde ya el scope mínimo de cada integración para no tener que cambiarlo después.
:::
Buenas prácticas
- Nunca versiones tokens en git. Usa variables de entorno o bóvedas (AWS Secrets Manager, Vault, etc.).
- Usa tokens distintos por integración (CRM, ERP, frontend, etc.): facilita revocar uno sin tumbar los demás, y la auditoría por
jtiqueda legible. - Pide los scopes mínimos necesarios (principio del menor privilegio): recurso sin verbo cuando la integración solo lee.
- Revoca de inmediato cualquier token filtrado: la revocación es por
jtiy vale en la llamada siguiente, sin esperar elexp. - HTTPS obligatorio: las llamadas por HTTP se rechazan.