Autenticación
La API de Finanzas Inteligentes 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.
Requisitos comprobados 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.finance[.{env}].kobana.com.br. Puede ser una lista — la regla es contiene, no igualdad |
exp | Obligatoria. 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). Va a la auditoría y a la atribución; no limita nada |
jti | Id único del token — la base de la revocación y de la auditoría |
El workspace viene del header X-Workspace-Id: el org dice la organización, y una organización puede tener varios workspaces. Es un selector, no una concesión — un workspace de otra organización no se alcanza adivinando su id. Sin el header, cuando hay más de un workspace, la respuesta es 400 WORKSPACE_REQUIRED.
:::caution Cambio respecto al token generado en el dashboard Antes la credencial era un token generado en la plataforma, con secret mostrado una única vez. El mismo valor firmaba y verificaba, así que una fuga en cualquiera de los dos lados era una fuga de la emisión. Ahora quien emite es el Authorization Server, y esta API solo verifica. :::
Si el Authorization Server está inalcanzable, la respuesta es 5xx, nunca 401 — un 401 ahí te mandaría a depurar una credencial perfecta durante una caída nuestra.
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 Sistema (contacto@miempresa.com.br)' \
-X GET 'https://api.finance.kobana.com.br/v1/financial-accounts'
Alcances (scopes)
Los alcances tienen dos ejes ortogonales: el recurso, siempre prefijado por la app (finance/payables), y el verbo, un alcance global sin prefijo (write). Un recurso sin verbo significa lectura. Escribir exige los dos: el alcance del recurso y el verbo.
| Recurso | Alcance | Qué cubre la lectura |
|---|---|---|
| Cuentas financieras | finance/accounts | cuentas y saldos |
| Catálogo de bancos | finance/banks | solo lectura, no hay escritura |
| Cuentas por pagar | finance/payables | títulos por pagar |
| Cuentas por cobrar | finance/receivables | títulos por cobrar |
| Envío al banco | finance/payable_dispatches | los envíos de pago y su estado |
| Emisión de cobro | finance/receivable_charges | los cobros (boleto/Pix) emitidos |
| Comprobantes de pago | finance/receipts | solo lectura |
| Notas fiscales recibidas | finance/fiscal_documents | solo lectura |
| Transacciones | finance/transactions | movimientos y transferencias |
| Conciliaciones | finance/reconciliations | conciliaciones (la escritura cubre crear y deshacer) |
| Flujo de caja proyectado | finance/cash_flow | solo lectura |
| Empresas | finance/companies | |
| Personas | finance/people | |
| Categorías | finance/categories | |
| Centros de clasificación | finance/cost_centers | el alcance nombra el grant, por eso cost_centers y no classification-centers como en la URL |
| Reglas automáticas | finance/automatic_rules | la escritura incluye reordenar |
| Impuestos | finance/taxes | |
| Adjuntos | finance/attachments | la escritura cubre subida y gestión |
| Comodín del recurso | finance/all | lee todos los recursos anteriores — y no concede ningún verbo |
| Verbo global | write | toda escritura (POST, PUT, PATCH, DELETE) sobre los recursos que lleva el token |
Dos ejemplos: finance/payables lee títulos por pagar y no escribe; finance/payables write también crea, modifica y borra, y sigue sin alcanzar cuentas por cobrar.
La forma granular finance/payables:write es una excepción de la gramática, no el formato por defecto: satisface los dos ejes para ese recurso solo, y existe para "lee un recurso, escribe otro". finance/* es un comodín de registro y nunca se emite en un token — la comparación aquí siempre es literal. En la gramática por recurso, leer es el recurso sin verbo; el read que existe es el nivel de acceso de la Cuenta Kobana, más abajo.
Reglas de resolución:
finance/allconcede toda lectura, y ninguna escritura. Para escribir hace falta el verbo:finance/all write.finance/receiptslista los comprobantes, pero no descarga el documento: eldownload_urlapunta al recurso de adjuntos, así que obtener los bytes exige tambiénfinance/attachments.finance/fiscal_documentslista las notas recibidas, pero no descarga el XML: elxml_download_urlapunta al recurso de adjuntos, así que obtener los bytes exige tambiénfinance/attachments.
Mover dinero es un recurso propio, no un verbo propio. Enviar un pago al banco y emitir un cobro son sensibles en un grado distinto del resto de la escritura, así que cada uno es un recurso: finance/payable_dispatches y finance/receivable_charges. Un token con finance/payables write registra el título y no dispara un pago; finance/all no alcanza ninguno de los dos ni con el verbo write, porque el comodín cubre lectura y el dinero exige el recurso por su nombre. Así un token de operación común no mueve dinero ni cobra a nadie.
Nivel de acceso — lo que se exige hoy
El alcance se exige en toda ruta. Los alcances por recurso anteriores todavía no están registrados en la Cuenta Kobana, así que los tokens que ella emite no los llevan — pero todo token trae el nivel de acceso que concediste al autorizar, y es eso lo que la API verifica:
| Nivel | Qué alcanza |
|---|---|
read | toda lectura (GET) |
write | toda lectura y toda escritura, excepto mover dinero |
all | todo, incluso enviar un pago al banco y emitir un cobro |
delete, import y export por sí solos no escriben. Un cliente que se registra solo en la Cuenta Kobana — un asistente de IA conectado por el MCP, por ejemplo — recibe solo read.
Cualquiera de los vocabularios basta: el nivel de acceso, los alcances por recurso anteriores o los alcances finance.<recurso>[.write] de los tokens de desarrollo.
Cuando el token trae alcances por recurso — el token personal que creas en la Cuenta Kobana, por ejemplo —, son ellos los que definen el alcance, y read, write y all solo valen dentro de esos recursos: finance/payables read write lee y escribe cuentas por pagar y nada más; finance/all read lee todo y no escribe nada. Mover dinero exige el recurso propio (finance/payable_dispatches, finance/receivable_charges) con write o all. Si falta, la respuesta es 403 INSUFFICIENT_SCOPE, con required, granted y accepted_levels — los niveles que habrían bastado — en details.
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 — facilita rotarlos/revocarlos sin tumbar todo.
- Pide los alcances mínimos necesarios (principio del menor privilegio) —
readcuando la integración solo lee, yallsolo para quien necesita mover dinero. - Revoca inmediatamente cualquier token filtrado.
- Apunta siempre a
https://— las llamadas en el puerto 80 son redirigidas al 443, pero los clientes no reenvían el cuerpo en un redirect.