Los eventos de datos de los webhooks pueden ir directamente a tu propio bus de eventos: un bus de Amazon EventBridge, un flujo de datos de Amazon Kinesis o un tema de Google Pub/Sub. No nos das ninguna clave y no guardamos ninguna tuya. En AWS creas un rol que asume nuestro propio rol, y solo con el ExternalId que emitimos para esa dirección; en Google Cloud das acceso a un tema a nuestra cuenta de servicio. Cada dirección escribe un evento por petición, en el orden en que llegan los eventos, y una escritura que falla se reintenta como cualquier mensaje de los webhooks (webhooks: recibir y comprobar los mensajes).
Qué envía cada formato
- Amazon EventBridge (
eventbridge): unPutEventspor mensaje al bus, por su ARN, concom.mercamapcomoSource, el evento comoDetailType(gap.opened) y nuestro cuerpo comoDetail({ "id", "type", "data", "event_id", "created_at" }), de modo que una regla del bus puede filtrar por{"source": ["com.mercamap"]}. - Amazon Kinesis (
kinesis): unPutRecordpor mensaje al flujo, por su ARN, con el cuerpo plano (un nivel de claves en snake_case) como datos del registro y el identificador de la tienda como clave de partición, para que los eventos de una tienda conserven su orden en un mismo fragmento (shard); un evento sin tienda usa el identificador de tu cuenta. - Google Pub/Sub (
pubsub): un mensaje por publicación en el tema, con nuestro cuerpo como datos y, como atributos,event_type,event_id,event_versiony, si el evento nombra una tienda,store_id, por los que una suscripción puede filtrar.
Ninguno lleva nuestras cabeceras de firma: el bus confía en el rol o en la identidad a la que diste acceso, y en nada más nuestro. Un mensaje que se reintenta tras agotar el tiempo de espera puede llegar dos veces, así que descarta el repetido por su event_id. La muestra de cada formato está en la referencia de webhooks.
EventBridge o Kinesis: el rol
- En «Conectores», en la página de «Amazon EventBridge» o de «Amazon Kinesis», añade una dirección con el ARN del bus o del flujo y el ARN del rol que vas a crear para nosotros. El bus o el flujo debe estar en una región comercial de AWS (se rechazan GovCloud y China) y en la cuenta del rol.
- La ficha de la dirección muestra entonces su ExternalId, el ARN de nuestro rol y las dos políticas del rol, listas para copiar. Crea el rol con el ARN que diste: su política de confianza deja que lo asuma nuestro rol solo con este ExternalId, y su política de permisos permite
events:PutEventsen el bus, okinesis:PutRecorden el flujo, y nada más. - Si el flujo está cifrado con una clave tuya de KMS, el rol necesita además
kms:GenerateDataKeyen esa clave: la ficha muestra la instrucción. - Pulsa «Enviar una prueba» en la ficha de la dirección.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": { "AWS": "arn:aws:iam::…:role/…" },
"Action": "sts:AssumeRole",
"Condition": { "StringEquals": { "sts:ExternalId": "…" } }
}
]
}
El ExternalId se emite al azar cuando se añade la dirección y no cambia nunca, y cada dirección tiene el suyo, así que el rol solo deja pasar a esa dirección, ni siquiera a otra nuestra (la guía de AWS sobre el ExternalId). Nuestra sesión se llama mercamap- seguido del identificador de tu cuenta de MercaMap, para que tu CloudTrail muestre cada escritura. Ninguno de los dos lados guarda una clave: cada envío toma una sesión que dura unos minutos.
Antes de cada sesión comprobamos que el rol exige su ExternalId: nuestro rol lo pide una vez con otro valor, bajo una política que no permite nada, y AWS debe negarlo; tu CloudTrail lo muestra como un AssumeRole rechazado. Un rol que nos deja pasar con otro ExternalId dejaría pasar a cualquier cuenta que lo nombrara, así que nunca lo usamos y rechazamos la dirección. La sesión que tomamos después solo puede hacer la escritura de la dirección, events:PutEvents en el bus o kinesis:PutRecord en el flujo (y usar su clave solo desde Kinesis), aunque el rol permita más.
Pub/Sub: los permisos y la etiqueta
- En «Conectores», en la página de «Google Pub/Sub», añade una dirección con el ID del proyecto y el del tema.
- La ficha de la dirección muestra nuestra cuenta de servicio y tres comandos de
gcloudlistos para copiar: dos dan acceso al tema a nuestra cuenta de servicio,roles/pubsub.publisherpara publicar yroles/pubsub.viewerpara leer la etiqueta del tema, y el tercero etiqueta el tema para tu cuenta. - Pulsa «Enviar una prueba».
gcloud pubsub topics update TOPIC --project=PROJECT --update-labels=mercamap-account=ACCOUNT_ID
Todos los clientes dan acceso a la misma cuenta de servicio, así que antes de escribir en el tema leemos su etiqueta mercamap-account, que debe nombrar tu cuenta: un tema etiquetado para otra cuenta, sin etiqueta o que no podemos leer rechaza la dirección y no se publica nada. Un tema que pasó la comprobación se vuelve a leer al cabo de 15 minutos. Solo quien puede cambiar tu tema puede etiquetarlo, así que ninguna otra cuenta puede hacer que nuestra cuenta de servicio escriba en él, y tus eventos nunca van a un tema etiquetado para otra.
Cuando se rechaza una escritura
La ficha de la dirección muestra su último fallo con nuestras palabras:
| Último fallo | Qué hacer |
|---|---|
AWS refused MercaMap the role (its trust policy or the ExternalId) |
Crea el rol, o comprueba que su política de confianza nombra nuestro rol y este ExternalId |
AWS let MercaMap assume the role with another ExternalId: … |
Exige este ExternalId en la política de confianza (StringEquals en sts:ExternalId) |
EventBridge refused the event (AccessDeniedException) |
Permite events:PutEvents en el bus en la política de permisos del rol |
Kinesis refused the event (ResourceNotFoundException) |
Revisa el ARN del flujo y, con una clave tuya de KMS, su instrucción |
the topic is not set up for this account (…) |
Revisa el tema, etiquétalo con el comando que muestra la ficha y da roles/pubsub.viewer en él |
Pub/Sub answered HTTP 403 (PERMISSION_DENIED) |
Da roles/pubsub.publisher en el tema |
Estos terminan el mensaje. Una limitación o un fallo del servicio (ThrottlingException, ProvisionedThroughputExceededException, InternalFailure, un 429 o un 5xx) dice «did not take the event» y se reintenta más tarde, igual que un rechazo de nuestra propia sesión, token o proyecto, o un inicio de sesión en AWS o en Google que no responde: nada de esto cuenta como fallo de la dirección. Cada intento rechazado cuenta como un fallo de la dirección: tras 20 seguidos se desactiva, y la vuelves a activar desde su ficha cuando esté arreglado.
Cada bus es del conector desde cuya página lo añades (Amazon EventBridge, Amazon Kinesis o Google Pub/Sub) y solo aparece en esa página. Desde su ficha puedes pausarlo: conserva el rol o los permisos y no recibe nada hasta que pulses «Activar», sin correo ni fallo que cuente. Si el equipo de MercaMap desactiva un bus, la desactivación alcanza a los demás de tu cuenta en la misma cuenta de AWS o el mismo proyecto de Google Cloud (cláusula 12.4).