# Autenticación

> Documentación para agentes: índice en https://api.staging.flowence.tech/connect/docs/llms.txt. La documentación completa requiere una credencial de Flowence Connect: la herramienta `docs` del servidor MCP o la clave API en el encabezado Authorization.

Cada pedido a Flowence Connect lleva una credencial. Hay dos tipos:

| Credencial | Para qué | Dónde sirve |
| --- | --- | --- |
| **Conexión OAuth** | Asistentes que se conectan pegando la URL del servidor (Claude, ChatGPT, Claude Code, Cursor) | Servidor MCP |
| **Clave API** | Integraciones, scripts y agentes configurados a mano | Servidor MCP y API REST |

## Conexiones OAuth

El usuario pega `https://api.staging.flowence.tech/mcp` en su asistente. El asistente descubre la autorización por su cuenta y abre Flowence en
el navegador:

1. El usuario inicia sesión (con su segundo factor o passkey, si los usa).
2. Flowence muestra la pantalla de consentimiento: qué aplicación pide acceso, el dominio que publicó sus metadatos, a
   dónde vuelve, cuándo y desde qué IP se inició el pedido, con qué usuario y contexto se conectará, el nivel de acceso
   (solo lectura, o lectura y operación) y las áreas. Si usted no inició el pedido hace instantes, no lo autorice:
   alguien pudo haberle reenviado el enlace.
3. Al autorizar, el navegador vuelve al asistente, que obtiene sus tokens.

Solo Claude y ChatGPT figuran como aplicaciones conocidas (sus documentos de metadatos bajo `https://claude.ai/oauth/`
y `https://chatgpt.com/oauth/`). En cualquier otra, el nombre y el logo los declara la propia aplicación: autorice solo
si usted inició la conexión y reconoce el dominio. Los dominios se muestran en punycode (`xn--...`), así un dominio
con letras de otro alfabeto no puede pasar por uno conocido. El logo se muestra únicamente si lo sirve el mismo
dominio que publicó los metadatos.

Si rechaza el pedido, Flowence vuelve a la aplicación con `error=access_denied` solo si es una aplicación conocida o
se ejecuta en su computadora (dirección loopback). En cualquier otro caso muestra un aviso y no redirige.

Detalles técnicos para clientes MCP:

- Metadatos del recurso protegido (RFC 9728): `https://api.staging.flowence.tech/.well-known/oauth-protected-resource/mcp`.
- Metadatos del servidor de autorización (RFC 8414): `https://api.staging.flowence.tech/.well-known/oauth-authorization-server`.
- Código de autorización con PKCE S256 obligatorio, parámetro `resource` (RFC 8707) e `iss` en la respuesta (RFC 9207).
- Clientes públicos (`token_endpoint_auth_method: none`), identificados con Client ID Metadata Documents o registro
  dinámico (RFC 7591). El `client_id` de un documento de metadatos se acepta solo en ASCII: los dominios
  internacionales van en punycode (`xn--...`). Los documentos de metadatos y su `jwks_uri` se descargan solo por HTTPS
  en el puerto 443. El registro dinámico recibe `application/json` y el canje y la revocación,
  `application/x-www-form-urlencoded`. Un registro dinámico idéntico a uno anterior (mismas direcciones de retorno,
  nombre, URI y logo) recibe el mismo `client_id`.
- `redirect_uri` es obligatoria en `/oauth/authorize` y en el canje, y debe coincidir exactamente con una registrada. Las
  direcciones loopback (`http://localhost`, `http://127.0.0.1` y `http://[::1]`) se comparan sin el puerto. Un esquema
  propio (por ejemplo `cursor://`) se acepta si es de un cliente conocido (`cursor`, `vscode`, `vscode-insiders` o
  `windsurf`) o tiene forma de dominio invertido (`com.example.app:/callback`); los que abren programas del sistema
  operativo se rechazan.
- Si una aplicación envía una `client_assertion` (por ejemplo ChatGPT, que declara `private_key_jwt`), Flowence la
  valida: JWT RS256 o ES256 firmado con una clave del JWKS de su documento de metadatos, `iss` y `sub` iguales al
  `client_id`, `aud` igual al emisor o al endpoint de token, vencimiento corto y `jti` de un solo uso si viene. Una
  aserción inválida recibe `invalid_client`. Sin aserción, el cliente se trata como público, igual que antes.
- Los errores anteriores al consentimiento (por ejemplo, falta PKCE o el alcance es desconocido) vuelven
  automáticamente a la aplicación solo si su dirección de retorno es loopback, o si es una aplicación conocida (Claude o
  ChatGPT) que vuelve a su propio dominio. En cualquier otro caso, Flowence muestra una página de error y no redirige.
- Alcances OAuth: `flowence.read` y `flowence.write`. El servidor MCP anuncia los dos, así que el cliente los pide y
  el usuario elige en el consentimiento: solo lectura (la opción marcada por defecto) o lectura y escritura.
- Token de acceso de 60 minutos y refresh token rotativo de 30 días; la conexión dura hasta 180 días.
- Rotación del refresh token: cada canje emite un par nuevo. Si el mismo refresh token se presenta otra vez dentro de
  los 30 segundos (por ejemplo, un reintento), la respuesta es el mismo par ya emitido; nunca otro. Si se presenta
  después de esa ventana, Flowence lo trata como posible robo y revoca la conexión completa.
- Código de autorización de un solo uso: si se presenta dos veces un pedido completo y válido (mismo `client_id`,
  `redirect_uri` y `code_verifier` correcto), se revoca la conexión. Un pedido repetido inválido solo recibe
  `invalid_grant`.
- Revocación: `https://api.staging.flowence.tech/oauth/revoke` (RFC 7009) o desde **Flowence Connect → Conexiones**. Un token vencido o ya
  revocado no revoca nada y, si el pedido incluye `client_id`, el token tiene que pertenecer a esa aplicación.
- Los tokens OAuth sirven solo en el servidor MCP. Para la API REST use una clave API.

## Claves API

### Crear una clave

1. En Flowence, vaya a **Flowence Connect → Claves API → Nueva clave API**. Hace falta el permiso "Administrar Flowence
   Connect".
2. Indique un nombre que identifique al agente o la integración (por ejemplo "Agente de cobranzas").
3. Elija los alcances (ver abajo), la vigencia (30, 90 o 365 días) y, si quiere, las IP o rangos desde los que se
   podrá usar.
4. Copie la clave. **Se muestra una sola vez**: Flowence guarda solo un hash.

La clave actúa en nombre del usuario que la crea (el **usuario responsable**) y conserva el contexto de empresa con
que ese usuario inició sesión.

### Formato

| Prefijo | Ambiente |
| --- | --- |
| `flw_live_` | Producción |
| `flw_test_` | Pruebas y desarrollo |

Después del prefijo vienen 40 caracteres alfanuméricos. Si una clave aparece en un repositorio o un registro, el
prefijo permite detectarla y revocarla.

### Cómo enviarla

```http
Authorization: Bearer flw_live_...
```

También se acepta el encabezado `X-API-Key: flw_live_...`. **Nunca la envíe en la URL**: las claves en parámetros de
consulta se rechazan.

## Alcances

Los alcances limitan qué áreas puede usar la credencial. Toda credencial incluye `companies:read`, necesario para
resolver proveedores y monedas.

| Alcance | Permite |
| --- | --- |
| `companies:read` | Proveedores, grupos de empresas y monedas |
| `debtors:read` | Deudores y estados de cuenta |
| `debtors:write` | Dar de alta deudores vinculados a un proveedor (con vista previa y confirmación) |
| `documents:read` | Documentos, saldos pendientes, notas de crédito sin asignar e incidencias de la facturación electrónica |
| `documents:write` | Cargar documentos, aplicar notas de crédito y recuperar comprobantes de la facturación electrónica (con vista previa y confirmación) |
| `receipts:read` | Recibos y créditos del estado de cuenta histórico |
| `receipts:write` | Registrar, imputar y enviar recibos (con vista previa y confirmación) |
| `bank:read` | Movimientos bancarios y sugerencias de conciliación |
| `bank:write` | Importar extractos y conciliar (con vista previa y confirmación) |
| `reminders:send` | Enviar recordatorios de pago (con vista previa y confirmación) |
| `collectibility:read` | Cobrabilidad y requisitos |
| `reports:read` | Antigüedad de deuda, vencidos y proyección de cobros |
| `payables:read` | Cuentas a pagar |
| `expenses:read` | Gastos cobrables |
| `onboarding:read` | Onboarding de proveedores: estado de la ronda, deudores, filas fallidas y preparación de archivos |
| `onboarding:write` | Preparar archivos y operar el onboarding (con vista previa y confirmación) |

## Qué puede hacer realmente una credencial

El acceso efectivo es la intersección de tres cosas:

1. **Los alcances** de la credencial.
2. **Los permisos** del usuario responsable en Flowence (sus roles).
3. **El alcance por proveedor** del usuario: un operador que gestiona solo algunos proveedores ve solo esos proveedores,
   y no ve los deudores que tiene excluidos.

Por eso una credencial nunca puede más que su usuario responsable. Si al usuario le quitan un permiso, la credencial
lo pierde en el acto. Si el usuario se desactiva o se bloquea, la credencial deja de funcionar. Lo mismo pasa si el
usuario pierde el rol con que se creó la credencial (por ejemplo, pasa de administrador a operador): la credencial deja
de funcionar y hay que crear otra con el rol actual, para que se aplique el alcance que corresponde.

Solo pueden ser responsables los usuarios con contexto de gestión (administrador, operador o supervisión). Los
usuarios de portales (deudores, cadetes, distribuidores) no pueden crear credenciales.

## Vencimiento, rotación y revocación

- **Vencimiento.** La clave deja de funcionar al vencer. `status` avisa cuando faltan menos de 7 días.
- **Rotación.** Cree una clave nueva, actualice el agente y revoque la anterior.
- **Revocación.** En **Flowence Connect → Claves API**, use **Revocar**. El efecto es inmediato: la caché de
  autenticación se descarta al revocar y otra vez cuando se confirma el cambio, así que el pedido siguiente ya se
  rechaza.
- **Actividad.** En **Flowence Connect → Actividad** se ve cada pedido: operación, resultado, IP y cliente.

## Restricción por IP

Si indica IP o rangos (por ejemplo `203.0.113.10` o `203.0.113.0/24`, separados por coma), los pedidos desde otras
direcciones se rechazan con `401`.

## Errores de autenticación

| Estado | Código | Qué significa |
| --- | --- | --- |
| `401` | `unauthorized` | Falta la clave, es inválida, venció, fue revocada, la IP no está permitida o el usuario responsable perdió el rol o el permiso |
| `403` | `insufficient_scope` | La credencial no tiene el alcance que pide la operación |
| `403` | `forbidden` | El usuario responsable no tiene el permiso de Flowence que pide la operación |

La respuesta `401` no indica el motivo concreto. Si la credencial existe (por ejemplo, está revocada, vencida o se usa
desde una IP no permitida), el rechazo queda en **Flowence Connect → Actividad** del tenant, con la credencial y el
usuario responsable: lo ven quien administra Flowence Connect y el propio usuario. Una credencial desconocida no tiene
tenant al que atribuirla y no aparece en la actividad del tenant.

Ante `insufficient_scope` o `forbidden`, el agente debe explicar al usuario qué acceso falta; no debe intentar
rodearlo. Vea [Límites y errores](https://api.staging.flowence.tech/connect/docs/limites-y-errores).

Con OAuth, cuando la conexión no tiene el nivel que pide la acción (por ejemplo, se conectó solo para lectura y la
acción es de escritura), el servidor MCP pide volver a autorizar: responde `403` con
`WWW-Authenticate: Bearer error="insufficient_scope"` y, en ChatGPT, un resultado de herramienta con el mismo desafío en
`_meta["mcp/www_authenticate"]`. Si la conexión ya tiene ese nivel pero el usuario no marcó el área al aprobar, no hay
desafío: el error indica el área (`details.area`) y hay que desconectar y volver a conectar marcándola. Vea
[Límites y errores](https://api.staging.flowence.tech/connect/docs/limites-y-errores).

El acceso también respeta el alcance del usuario responsable: si es un operador, solo ve y opera los proveedores que
tiene asignados, sin los deudores excluidos.
