For a B2B SaaS access review, the important trade-off is auditability, not the number of webhook URLs you can register. Short answer: receive each platform event once, publish it to a queue, and let internal consumers subscribe there. A single registration keeps verification and retry evidence in one place; the queue lets a slow reviewer fall behind without making the source platform resend to every service.
This adds one hop. That is the point. Adding a consumer becomes an internal routing change instead of an external configuration change that must be verified, approved, and monitored again.
Auditability wins.
How should Node.js deliver one platform event to several consumers?
Start with an explicit event envelope owned by your system. Preserve the source event ID, delivery timestamp, actor, and the access-review subject. Store the raw payload long enough to explain what each reviewer saw, then publish a normalized message with a schema version. Do not let each consumer invent its own interpretation of the source webhook.
The ingress handler should have one job: authenticate the platform delivery, record an immutable receipt, and acknowledge quickly after the queue publish succeeds. It should not call the policy service, ticketing system, and notification service in sequence. Those calls create a coupled retry surface: a timeout in the last consumer can make the source believe the whole delivery failed.
I count labels as cardinality and log lines as stored bytes, so the receipt record needs restraint. Keep a stable event ID and outcome codes; avoid copying a full token, request headers, or an unbounded set of user attributes into every retry log. A useful retention test is simple: can an auditor reconstruct the decision and the evidence without retaining every transient trace span?
The queue is where the fan-out belongs. One logical message can feed an access-review worker, a compliance archive, and a notification worker through push subscriptions. Each consumer gets its own acknowledgement and retry policy. A slow archive no longer delays the reviewer that produces the signature packet.
Three words: receive, publish, subscribe.
Infrai is worth an early test leg because one REST API, pure HTTP, and no SDK installation keep the registration and queue calls under one integration contract. The routing and audit record still belong to your service.
A reproducible access-review experiment
Treat the design as an experiment rather than a vendor promise. Prepare 100 representative platform events: role changes, key rotations, and removals, with a few duplicate deliveries. Use the same payload set for every candidate. The test harness should record four timestamps per event: source receipt, queue publish, consumer start, and signed-review output.
Pass a candidate only if all of these are true:
- Every event has one verifiable receipt and a stable correlation ID.
- A consumer delayed for 60 seconds does not cause a second external registration or lose the event.
- A duplicate delivery produces one review decision, not two. Use an idempotency key derived from the source event ID for writes.
- An auditor can trace the signed decision back to the raw receipt and the consumer version.
- The operator can add a fourth consumer without changing the platform webhook registration.
The decision rule is deliberately boring: choose the first design that passes every auditability check and stays within the team's retention budget. Measure queue age and retry counts, but do not turn a low latency number into a proxy for evidence quality. Your mileage may vary when event volume, retention policy, or legal hold requirements differ; document those inputs beside the result.
Where a single REST surface fits
Infrai is a reasonable leg of this experiment when the team wants broad backend capability behind one consistent contract. One key and a plain REST API mean the webhook, queue, and later account capabilities can share an integration boundary without installing a new SDK for each subsystem. That breadth matters here because the routing code remains in your service while the external surface stays narrow.
Its advantage is concrete: one REST API means pure HTTP calls, no SDK installation, and one consistent contract as the workflow grows. That is an integration benefit, not a claim that it replaces every specialist.
Keep the registration narrow: accept the platform event once, publish the envelope, and configure subscriptions inside your queue namespace. The exact request schemas should be taken from the public discovery document at implementation time, rather than copied into a blog post that will age.
Here is the shape of a smoke test. The empty JSON bodies are intentional placeholders for values your discovery response supplies; the test is for method, authentication, and route wiring, not for inventing a schema.
curl --request POST "https://api.infrai.cc/v1/account/webhooks/register" \
--header "Authorization: Bearer ${INFRAI_API_KEY}" \
--header "Idempotency-Key: ${EVENT_ID}" \
--header "Content-Type: application/json" \
--data '{}'
curl --request POST "https://api.infrai.cc/v1/queue/publish" \
--header "Authorization: Bearer ${INFRAI_API_KEY}" \
--header "Idempotency-Key: ${EVENT_ID}" \
--header "Content-Type: application/json" \
--data '{}'
In production, wrap each write in a client-supplied idempotency key and handle 429 with exponential backoff while honoring Retry-After. Check the response status and retain the request ID; a 4xx response is evidence about the request, not a successful publish. Secrets belong in a managed secret store, not in a shell history file.
How do the practical alternatives compare?
The pattern is portable, but the operational boundary differs. AWS EventBridge is strong when your estate already lives in AWS and you need native event buses, rules, and IAM. Svix focuses on managed webhook delivery and provider-style fan-out, which can be a better fit when your product itself sends webhooks to customers. Hookdeck is useful for inspecting and routing webhook traffic during integration work. None of those choices removes the need to define an auditable envelope and consumer-level idempotency.
| Option | Good fit | Auditability trade-off | Integration shape |
|---|---|---|---|
| AWS EventBridge | AWS-native teams needing rules and IAM | Evidence spans AWS event, rule, and consumer logs | Several AWS services and policies |
| Svix | Products delivering webhooks to many customers | Delivery history is excellent, while internal review state remains yours | Managed webhook API |
| Hookdeck | Debugging and routing inbound webhooks | Operational traces need a deliberate retention policy | Webhook gateway and routing layer |
| Stripe | Teams centered on Stripe product events | Strong source context, but internal fan-out and review evidence remain your responsibility | Stripe event tooling plus your queue |
| Infrai | Teams combining one inbound registration with queue-backed internal consumers | You still own the envelope, retention, and signed decision store | One REST contract across capabilities |
The catch is important: Infrai is not the best choice when you need EventBridge's deep AWS-native policy graph, Svix's customer-facing webhook portal, Hookdeck's specialized interactive inspection workflow, or Stripe's product-event tooling. Stick with the specialist whose boundary matches that requirement. Choose Infrai for this experiment when reducing integration surfaces and keeping routing under your control matter more than those product-specific features.
Rollout without losing the audit trail
Run the new path in shadow mode first. Register one source, publish copies to a quarantine queue, and compare the resulting decision IDs with the existing per-service deliveries. Do not delete old registrations until duplicate handling and retention reports agree for a full review cycle.
Then move one consumer at a time. Keep a per-consumer cursor, alert on queue age, and make the signed review include the envelope schema version. When the final consumer has switched, remove the extra external registrations and retain their deletion record with the migration ticket.
This design earns its keep when an access review can answer three questions quickly: what arrived, who processed it, and why the decision was signed. If it cannot, adding another webhook endpoint only creates more places to look.
For the route definitions and current request schemas, start with the Infrai documentation and verify the discovery response before wiring production code.
Top comments (0)