Saltar al contenido principal

Autenticación y alcances

Próximamente

El emisor de tokens está implementado y probado, pero el servicio aún no está desplegado: todavía no hay URL pública ni sandbox.

La API del CMS v1 usa OAuth 2.0 client_credentials con private_key_jwt (RFC 7523). Tu sistema se autentica con una aserción firmada con su llave privada; FINORA solo conoce tu llave pública. No hay contraseñas que robar ni secretos compartidos que rotar.

La aserción del cliente​

CampoRegla
AlgoritmoES256 (recomendado) o RS256. Nunca none ni HMAC
kid (cabecera)El de una llave de tu JWKS registrado
iss y subTu client_id, los dos iguales
audLa URL exacta del token, por ejemplo https://api-cms.example.com/v1/oauth/token
expObligatorio; como máximo 5 minutos en el futuro
iatRecomendado
jtiObligatorio, hasta 128 caracteres y de un solo uso: una aserción reutilizada responde 401

La petición es un formulario application/x-www-form-urlencoded:

ParámetroValor
grant_typeclient_credentials
client_assertion_typeurn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertionLa aserción firmada
scopeOpcional. Alcances separados por espacio; deben ser un subconjunto de los concedidos. Sin scope, recibes todos los concedidos

El ejemplo completo de firma en Node.js está en el Inicio rápido.

El token de acceso​

El gateway emite un JWT ES256 de 5 minutos (expires_in: 300, cabecera typ: at+jwt) que envías como Authorization: Bearer <token>. Puedes verificarlo con las llaves públicas de GET /.well-known/jwks.json. Sus claims:

ClaimContenido
issURL del gateway
sub, client_idTu client_id
audfinora-cms-api
scopeAlcances concedidos en este token, separados por espacio
productosCódigos de producto a los que tienes acceso
instalacionIdentificador de la instalación del emisor
envEntorno (production o sandbox)
iat, nbf, exp, jtiVigencia e identificador del token

Trátalo como opaco salvo para leer exp: renueva el token un poco antes de que venza. Un token vencido responde 401 TOKEN_VENCIDO; uno ausente o inválido, 401 NO_AUTENTICADO.

Errores del endpoint de token​

Esta ruta sigue el formato OAuth 2.0 (RFC 6749 §5.2), no RFC 9457:

HTTPerrorCausa
400unsupported_grant_typegrant_type distinto de client_credentials
400invalid_requestFalta client_assertion o client_assertion_type es otro
400invalid_scopePediste un alcance que no tienes concedido
401invalid_clientAserción inválida, vencida, de un cliente suspendido o reutilizada
429—Demasiados fallos desde tu IP (20 fallos la bloquean 15 minutos); trae Retry-After
503—El gateway no puede verificar la aserción (AUTENTICACION_NO_DISPONIBLE); reintenta tras Retry-After
{ "error": "invalid_client", "error_description": "Aserción reutilizada." }

Rotación de tu llave​

Tu JWKS puede tener varias llaves. Para rotar: agrega la nueva al registro, empieza a firmar con su kid y retira la anterior cuando ya no la uses. Si registraste una URL https de JWKS, basta con publicar la nueva llave allí.

Alcances​

Cada operación exige un alcance. Sin él, 403 ALCANCE_INSUFICIENTE. Además, cada objeto se valida contra tus productos: un objeto de otro producto responde 404, nunca 403.

AlcancePermiteOperaciones
accounts:readLeer cuentas y productos.GET /v1/customers/{customerId}/accounts, GET /v1/accounts/{accountId}, GET /v1/products
balances:readLeer saldos y la serie del IDI.GET /v1/accounts/{accountId}/balance, GET /v1/indices/IDI
cards:blockBloquear y desbloquear plásticos.POST /v1/cards/{cardId}/block, POST /v1/cards/{cardId}/unblock
cards:linksVincular y desvincular cuentas; solicitar cambio de principal.POST /v1/cards/{cardId}/accounts, POST /v1/cards/{cardId}/accounts/{linkId}/deactivation, POST /v1/cards/{cardId}/accounts/{linkId}/principal-requests, POST /v1/principal-requests/{solicitudId}/cancellation
cards:pan-lookupBuscar un plástico por PAN (fase 2, con mTLS).POST /v1/cards/lookup (Próximamente)
cards:readLeer plásticos y vínculos.GET /v1/accounts/{accountId}/cards, GET /v1/cards/{cardId}, GET /v1/cards/{cardId}/accounts, GET /v1/principal-requests/{solicitudId}
cards:reportReportar pérdida o robo.POST /v1/cards/{cardId}/reports
credit-limit:requestSolicitar cambios de línea.POST /v1/accounts/{accountId}/credit-limit-requests, DELETE /v1/credit-limit-requests/{requestId}
customers:readLeer clientes.GET /v1/customers, GET /v1/customers/{customerId}
events:readLeer eventos.GET /v1/events, GET /v1/subscriptions/{subscriptionId}/events, POST /v1/subscriptions/{subscriptionId}/cursors
limits:bulkSolicitar y consultar lotes.POST /v1/limit-jobs, GET /v1/limit-jobs/{jobId}, GET /v1/limit-jobs/{jobId}/rows, POST /v1/limit-jobs/{jobId}/cancel
limits:readLeer topes, línea, historial y solicitudes.GET /v1/cards/{cardId}/limits, GET /v1/products/{productCode}/limits, GET /v1/accounts/{accountId}/credit-limit, GET /v1/accounts/{accountId}/credit-limit/history, GET /v1/accounts/{accountId}/credit-limit-requests, GET /v1/credit-limit-requests/{requestId}
limits:writeFijar topes del plástico.PUT /v1/cards/{cardId}/limits
movements:adjustmentsVer los ajustes por indexación y suscribirse a sus eventos.GET /v1/accounts/{accountId}/indexation-adjustments
movements:readLeer movimientos y operaciones.GET /v1/accounts/{accountId}/movements, GET /v1/operations/{operationId}
prepaid:adjustSolicitar ajustes prepago.POST /v1/accounts/{accountId}/adjustments, GET /v1/adjustments/{adjustmentId}
prepaid:adjust-approveAprobar o rechazar ajustes DEBITO pendientes (nunca junto con prepaid:adjust en el mismo cliente).GET /v1/adjustments/{adjustmentId}, POST /v1/adjustments/{adjustmentId}/decision
prepaid:loadRecargar prepago.POST /v1/accounts/{accountId}/loads
statements:readLeer estados de cuenta.GET /v1/accounts/{accountId}/statements, GET /v1/accounts/{accountId}/statements/{statementId}, GET /v1/accounts/{accountId}/statements/{statementId}/document
webhooks:writeAdministrar suscripciones.GET /v1/subscriptions, POST /v1/subscriptions, GET /v1/subscriptions/{subscriptionId}, DELETE /v1/subscriptions/{subscriptionId}, POST /v1/subscriptions/{subscriptionId}/secrets:rotate, POST /v1/subscriptions/{subscriptionId}/replay, GET /v1/subscriptions/{subscriptionId}/deliveries

Reglas especiales:

  • movements:adjustments también es necesario para pedir movimientos con incluirAjustes=true o con la naturaleza AJUSTE_INDEXACION, y para suscribirse a los eventos opt-in de indexación. Ver Movimientos y ajustes.
  • prepaid:adjust-approve nunca se concede al mismo cliente que prepaid:adjust: quien pide un ajuste no puede aprobarlo (cuatro ojos).
  • cards:pan-lookup y POST /v1/cards/lookup llegan en la fase 2 y exigirán además mTLS (Próximamente).

TLS mutuo (fase 2)​

Próximamente

En la fase 2, los alcances de dinero, de límites y cards:pan-lookup exigirán además un certificado de cliente (mTLS, RFC 8705). Sin él responderán 403 MTLS_REQUERIDO. Hoy no se exige.