Credenciales de bots y webhooks

Cada bot tiene sus propias credenciales, distintas de la clave API de la organización socia.

Modelo de seguridad (recomendado)

CredencialObjetivoAlmacenamiento
Clave API de socio (sk_…)Gestionar todos los bots, rotar los secretos y enviar mensajes al hubHasheada en reposo
Token de bot (bot_….…)Llamadas API limitadas al bot (webhook entrante, futuras API de bot)Hasheado en reposo · se muestra una sola vez
Secreto de webhook (whsec_…)Firmar y verificar los cuerpos de webhook mediante HMACAlmacenado (necesario para firmar) · trátelo como una contraseña
URL de webhookEndpoint HTTPS del socio para los eventos de MorisBoxURL en texto claro

¿Por qué no usar client_id + client_secret de OAuth?

Las credenciales de cliente OAuth son más adecuadas para un acceso delegado por el usuario. Los bots se comunican de máquina a máquina; un único token de bot de alta entropía más firmas HMAC en los webhooks es una solución más sencilla y robusta para este caso de uso.

Buenas prácticas

  1. Use únicamente webhooks HTTPS (localhost está permitido durante el desarrollo)
  2. Incluya firmas HMAC-SHA256 del cuerpo en cada evento saliente
  3. Configure opcionalmente una lista de IP permitidas por bot
  4. Rote el token o el secreto sin volver a crear el bot
  5. Nunca registre tokens completos

Crear un bot (los secretos se devuelven una sola vez)

POST /api/v1/bots

{
  "code": "portail",
  "name": "SEED Portail",
  "runtime_mode": "local",
  "webhook_url": "https://partner.example/hooks/morisbox/portail"
}

Respuesta 201

{
  "bot": {
    "code": "portail",
    "credentials": {
      "token_prefix": "bot_a1b2c3",
      "token_configured": true,
      "webhook_url": "https://partner.example/hooks/morisbox/portail",
      "webhook_secret_prefix": "whsec_ab12",
      "inbound_webhook_path": "/api/v1/bots/portail/webhook"
    }
  },
  "bot_token": "bot_a1b2c3d4e5f6.xxxxxxxx",
  "webhook_secret": "whsec_xxxxxxxx",
  "warning": "Store bot_token and webhook_secret now…"
}

Guarde bot_token y webhook_secret en su gestor de secretos. No se pueden volver a consultar; solo es posible regenerarlos mediante una rotación.


Gestionar las credenciales

MétodoRutaAutenticaciónDescripción
GET/bots/{code}/credentialsClave de socio o token de botSolo prefijos
POST/bots/{code}/token/rotateClave de socioNuevo bot_token (una sola vez)
PUT/bots/{code}/webhookClave de socioDefinir webhook_url; opción rotate_secret
POST/bots/{code}/webhook/secret/rotateClave de socioNuevo secreto de webhook
POST/bots/{code}/webhook/testClave de socioEnviar un evento de prueba firmado
PATCH/bots/{code}Clave de socioActualizar nombre, canales, allowed_ips, …

Definir el webhook

PUT /api/v1/bots/portail/webhook
Authorization: Bearer sk_…
{
  "webhook_url": "https://partner.example/hooks/morisbox/portail",
  "rotate_secret": true,
  "allowed_ips": "203.0.113.10"
}

Webhooks salientes (MorisBox → usted)

Cuando MorisBox envía una solicitud POST a su webhook_url:

POST https://partner.example/hooks/morisbox/portail
Content-Type: application/json
X-Seed360-Event: bot.webhook.test
X-Seed360-Bot: portail
X-Seed360-Signature: sha256=<hex>
X-Seed360-Bot-Secret: <webhook_secret>

Cuerpo

{
  "event": "bot.webhook.test",
  "bot": {
    "ref": "…",
    "code": "portail",
    "partner_code": "seed"
  },
  "payload": {}
}

Verificar la firma (Python)

import hmac, hashlib

def verify(raw_body: bytes, header_sig: str, secret: str) -> bool:
    sig = header_sig.removeprefix("sha256=")
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig)

Es preferible verificar el HMAC en lugar de confiar únicamente en la cabecera del secreto.


Webhooks entrantes (usted → MorisBox)

POST /api/v1/bots/{code}/webhook

Autentíquese con uno de los métodos siguientes:

  1. Authorization: Bearer <bot_token>
  2. X-Seed360-Bot-Secret: <webhook_secret>
  3. X-Seed360-Signature: sha256=<hmac of body with webhook_secret>
{
  "event": "custom.event",
  "data": { "ok": true }
}

Usar el token de bot

GET /api/v1/bots/portail
Authorization: Bearer bot_a1b2c3d4e5f6.xxxx

Los tokens de bot están limitados a ese bot. Las claves API de socio gestionan toda la organización.


Lista de verificación operativa

  1. Cree el bot → guarde bot_token + webhook_secret
  2. Despliegue el receptor HTTPS → PUT …/webhook
  3. Ejecute POST …/webhook/test hasta obtener ok: true
  4. En caso de filtración, rote mediante token/rotate / webhook/secret/rotate