Skip to content

OAuth y Service Canvas

Queria se integra con APIs externas autenticadas mediante Service Canvas -- canvas DSL especiales con purpose = SERVICE que describen como autorizar un proveedor OAuth2 y que operaciones expone. Las credenciales del usuario se guardan cifradas en un vault y son referenciadas por canvas consumidores (CHAT, INGESTION, WIDGET) via el tipo connection_ref.

BYO (Bring Your Own)

V1/V2 solo soportan el enfoque BYO: el tenant aporta su propio client_id y client_secret OAuth registrados en el proveedor. Queria no provee ni certifica apps OAuth propias hacia proveedores terceros.

Cuando se necesita

Caso de usoEjemplo
Chat que envia mensajes a un canalSlack, Microsoft Teams
Pipeline que crea eventos de calendarioGoogle Calendar, Microsoft 365
Ingestion automatica desde SaaSNotion, Confluence, GitHub Issues
Constructor que llama APIs de pagoStripe, Salesforce, HubSpot
Cloud storage avanzadoGoogle Drive con permisos delegados, OneDrive

Para cloud storage basico con login personal del usuario ya existen conectores estandar documentados en Configuracion > Cloud Storage.

Arquitectura

+----------------------------------------+
|  Service Canvas "Slack OAuth"          |
|  purpose = SERVICE                     |
|  +--------------+  +------------------+|
|  | oauth2_config|  | operation_def[]  ||
|  | client_id    |  | post_message     ||
|  | client_secret|  | list_channels    ||
|  | auth_url     |  | get_user_email   ||
|  | token_url    |  +------------------+|
|  | scopes[]     |                      |
|  +--------------+                      |
+----------------------------------------+
            ^ referenciado por
            |
+-----------------------------+
|  Canvas CHAT consumer       |
|  ... -> external_tool(      |
|    serviceCanvasId='slack', |
|    operationId='post_msg')  |
+-----------------------------+
            | runtime
            v
+------------------------------------+
|  ExternalServiceConnection (DB)    |
|  per (serviceCanvasId,             |
|       companyId, userId)           |
|  -> accessToken (AES-256 cifrado)  |
|  -> refreshToken (cifrado)         |
|  -> scopes, expiresAt              |
+------------------------------------+

Tres conceptos clave:

  1. Service canvas -- definicion del proveedor (quien es, como autorizar, que endpoints expone).
  2. External_tool node -- usado en canvas CHAT/INGESTION para llamar a una operacion del service canvas.
  3. Connection -- fila en DB con los tokens cifrados para el par (usuario, service).

Crear un service canvas

El admin sigue estos pasos:

1. Registra la app OAuth en el proveedor

Ejemplo Slack:

  1. Ve a https://api.slack.com/apps y crea una nueva app.
  2. Configura Redirect URL = https://admin.queria.pro/api/oauth/callback/slack (sustituye con tu dominio Queria del tenant).
  3. Define los scopes requeridos (ej. chat:write, channels:read).
  4. Copia client_id y client_secret.

2. Crea el service canvas

  1. Panel admin > DSL y Pipelines > OAuth y Service Canvas > Nuevo.
  2. Elige una plantilla provider (Slack, Google Workspace, Microsoft 365, GitHub, Notion, Custom).
  3. Pega client_id y client_secret en los campos del nodo oauth2_config. El client_secret se cifra server-side (AES-256-GCM).
  4. Verifica auth_url, token_url, scopes (precompilados por la plantilla, editables).
  5. Anade los nodos operation_def con metodo HTTP, path, parametros input/output. Puedes importarlos desde OpenAPI 3.x (para providers que lo expongan).
  6. Guarda. El canvas se valida y se marca ACTIVE.

3. Los usuarios se autorizan

En el service canvas aparece un boton Connect. Cuando un usuario lo pulsa:

  1. Redirect al proveedor para autorizacion (consentimiento del usuario, scopes).
  2. El proveedor redirige con un code.
  3. Backend intercambia code por access_token + refresh_token.
  4. Los tokens se cifran y se guardan en ExternalServiceConnection para (serviceCanvasId, companyId, userId).
  5. El usuario ve la conexion como Connected y puede revocarla cuando quiera.

Usar la conexion en un canvas

En el canvas CHAT/INGESTION anade un nodo external_tool:

json
{
  "type": "external_tool",
  "params": {
    "serviceCanvasId": "slack-oauth-canvas-id",
    "operationId": "post_message",
    "inputs": {
      "channel": "{{sys.target_channel}}",
      "text": "{{llm_writer_1.output}}"
    },
    "outputName": "slack_response"
  }
}

En runtime:

  • El motor carga el service canvas.
  • Encuentra la operacion post_message.
  • Resuelve la connection para (serviceCanvasId, companyId, ctx.userId).
  • Si el token expiro, lo refresca automaticamente.
  • Ejecuta la llamada HTTP con Authorization: Bearer <access_token>.
  • Escribe la respuesta en sys.slack_response.

Gestion de conexiones

Panel admin > OAuth y Service Canvas > [service] > Connections:

  • Tabla de todas las conexiones para ese service canvas (usuarios, scopes, estado, ultimo uso).
  • Estado posible: ACTIVE, EXPIRED (refresh fallido), REVOKED, ERROR.
  • Revocar desde Queria (elimina los tokens cifrados) y -- si el provider lo soporta -- llama al endpoint de revoke remoto.
  • Audit log: quien autorizo, cuando, con que scopes, que canvas consumio la connection.

Seguridad

  • Tokens en reposo: cifrados con AES-256-GCM. La clave maestra LLM_VAULT_KEK se deriva de JWT_SECRET (en produccion asegurarse que no sea el default dev-secret-change-me).
  • Tokens en transito: solo HTTPS al proveedor; las llamadas internas pasan por la red Docker aislada.
  • Scopes minimos: la plantilla sugiere los minimos por operacion. No solicites admin:* si no hace falta.
  • Por-usuario: cada connection pertenece a un solo usuario. Cuando se ejecuta un canvas, usa el token del usuario que trigereo la ejecucion (ctx.userId).
  • Audit: cada llamada external_tool con OAuth registra (userId, serviceCanvasId, operationId, statusCode, latencyMs) en IntegrationCallLog.

Limites y roadmap

V1/V2 actuales:

  • Solo flow authorization_code.
  • BYO client only (no apps Queria-owned verificadas).
  • No client_credentials (M2M) -- en roadmap V3.
  • No flow device_code.
  • No domain-wide delegation Google Workspace.
  • No webhooks inbound del provider (en roadmap separado).
  • Import operaciones desde OpenAPI 3.x en V1.2.

Best practice

  1. Un service canvas por proveedor, aunque uses varias operaciones: simplifica la gestion de tokens.
  2. Documenta los scopes en el nombre o description del canvas: "Slack (chat:write only)" mejor que "Slack OAuth".
  3. Limita los operation_def activos: anade solo las operaciones realmente usadas.
  4. Test en tenant piloto: antes de habilitar para todos, prueba en una empresa interna.
  5. Monitorea EXPIRED: una caida de refresh exitosos suele indicar que el provider revoco la app o cambio politicas.

Queria v3.5.0 -- External Tools OAuth V2 + Service Canvas

Queria - Document Intelligence con Cog-RAG