Ir al contenido
FINORA Academy
SistemaFINORA Core

FINORA Core · Guía

Rotar una credencial de API con periodo de gracia

ImplementadoImplementado

Un secreto que nunca cambia es un secreto que, tarde o temprano, se filtra. Pero cambiarlo de golpe corta a todos los sistemas que lo usan hasta que alguien actualiza su configuración. La rotación con periodo de gracia resuelve las dos cosas: durante un plazo valen el secreto nuevo y el anterior; tú migras con calma y, al vencer el plazo, el anterior deja de servir.

flowchart LR
  A["Antes<br/>solo vale el anterior"] -->|"rotación"| B["Periodo de gracia<br/>valen los dos"]
  B -->|"despliegas el nuevo<br/>en tu sistema"| C["Tu sistema ya usa<br/>el nuevo"]
  C -->|"vence el plazo"| D["Solo vale el nuevo"]

Hay dos credenciales distintas, y conviene no confundirlas:

Secreto del consumidor del gatewayAPI key ante el core
La usaTu sistema, para pedir token a /v1/oauth/token o en la cabecera apiKeyUn sistema que llama al core directo con X-Api-Key, o el propio gateway
La rotaQuien opera el gatewayEl administrador del core, por API
Plazo de graciaHasta la fecha que fije el operadorDe 0 a 7 días (30 minutos por defecto)
  1. Pide la rotación a quien opera el gateway de tu institución y acuerden la fecha límite del secreto anterior.

  2. El operador registra el secreto nuevo conservando el anterior hasta esa fecha y aplica el cambio. Desde ese momento tu sistema puede entrar con cualquiera de los dos. El gateway nunca guarda los secretos en claro: solo su huella SHA-256.

  3. Recibe el secreto nuevo por un canal seguro y guárdalo en el almacén de secretos de tu sistema.

  4. Mientras tu sistema siga entrando con el anterior, cada respuesta del token (o cada petición con la cabecera apiKey) trae la cabecera X-Finora-Secret-Expires con la fecha límite. Es la alarma: haz que tu sistema la registre.

    Ventana de terminal
    curl -s -D - -o /dev/null -u "$CLIENT_ID:$SECRETO_ANTERIOR" -d grant_type=client_credentials "$GW/v1/oauth/token" \
    | rg -i 'x-finora-secret-expires'
  5. Despliega tu sistema con el secreto nuevo. Comprueba que la cabecera ya no aparece:

    Ventana de terminal
    curl -s -D - -o /dev/null -u "$CLIENT_ID:$SECRETO_NUEVO" -d grant_type=client_credentials "$GW/v1/oauth/token" \
    | rg -ic 'x-finora-secret-expires' # 0
  6. Pasada la fecha, el secreto anterior responde 401 GW_CREDENCIAL_INVALIDA. El operador lo retira de la configuración en el siguiente cambio.

El core rota una API key por su nombre con POST /api/v1/ext/api-keys/{name}:rotate. Esta ruta no está en el gateway: es una operación del administrador del core, con una credencial que tenga el alcance apikey:rotate. Es un alcance crítico: una credencial con acceso general no lo tiene si no se le da de forma expresa.

  1. Rota la key y fija el plazo en segundos (de 0 a 604 800; sin cuerpo, 1800):

    Ventana de terminal
    curl -s -X POST "https://<su-core>/api/v1/ext/api-keys/erp-contable:rotate" \
    -H "X-Api-Key: $CLAVE_DEL_ADMINISTRADOR" -H "Content-Type: application/json" \
    -d '{ "graceSeconds": 86400 }'

    La respuesta llega con Cache-Control: no-store:

    {
    "name": "erp-contable",
    "apiKey": "<LA_KEY_NUEVA>",
    "previousValidUntil": "2026-09-20T10:00:00",
    "rotatedAt": "2026-09-19T10:00:00"
    }

    apiKey se muestra esta única vez: el core solo guarda su huella. Cópiala al almacén de secretos del sistema que la usa.

  2. Despliega el sistema con la key nueva antes de previousValidUntil. Hasta esa hora valen las dos.

  3. Pasado el plazo, la key anterior deja de ser aceptada.

Cuidado: rotar no es idempotente. Cada llamada genera otra key y manda la que estaba vigente al periodo de gracia. Si repites la llamada por error, la key que acabas de entregar pasa a ser la «anterior». Si no recibiste la respuesta, no reintentes a ciegas: rota una vez más a propósito y entrega esa.

graceSeconds: 0 invalida la anterior de inmediato: úsalo solo cuando sabes que la key se filtró.

Lo que vesPor qué
400 invalid-gracegraceSeconds fuera de 0 a 604 800
404 api-key-not-foundNo existe una key con ese nombre (o es de otra compañía: una key con compañía solo rota keys de la suya)
409 api-key-name-ambiguousHay más de una key con ese nombre
409 api-key-not-usableLa key está inactiva o vencida
403Tu credencial no tiene apikey:rotate

El gateway entra a cada core con su propia API key. Para rotarla sin corte: rótala en el core con un plazo holgado, actualiza la variable del gateway que la contiene y reinicia el gateway antes de que venza el plazo. Mientras el gateway use una key que el core ya no acepta, toda petición responde 502 CORE_CREDENCIAL_RECHAZADA.