Skip to main content

Command Palette

Search for a command to run...

Outbound webhooks for MENA SaaS: safe delivery

A sender architecture for customer endpoints: connection-time checks, isolated egress, signed events and controlled retries.

Updated
•9 min read•View as Markdown
Outbound webhooks for MENA SaaS: safe delivery
H
I have lead the Engineering for multiple startups in UAE. I also have my own agency qualascend.com.

A customer pastes a callback URL into your SaaS dashboard. Your application now has permission to send business events somewhere new. It has also acquired an attacker-controlled network destination.

For a product connecting Saudi suppliers, UAE property operators or regional software partners, outbound webhooks deserve a separate service boundary. The sender must decide whether a destination is allowed, what data may leave, and how failed attempts recover. Adding a signature answers only one of those questions.

This guide proposes a sender architecture for customer-configured public HTTPS endpoints. Private enterprise integrations need a separately approved route. It complements SultanByte's payment webhook receiver guide, which covers incoming events and payment-state reconciliation.

Cover: original SultanByte artwork showing business events passing through an outbound policy gate to an approved customer endpoint.

Choose the destination model before the HTTP client

OWASP's SSRF prevention guidance distinguishes known, trusted destinations from arbitrary external destinations. A connector to a fixed partner service can use a narrow allowlist. A self-service webhook product cannot assume that every customer hostname is trustworthy.

Keep those models separate. Do not add a private-network exception to the public webhook worker because one enterprise customer needs an internal endpoint. That exception changes what every potentially malicious subscription can try to reach.

For the public product, define an explicit registration contract: HTTPS, supported ports, no URL credentials, a bounded URL length and a documented path/query policy. Reject fragments and ambiguous input rather than trying to repair it. Use a maintained URL parser, and ensure the component that validates the destination agrees with the component that connects.

Allow only authorised tenant administrators to create or change subscriptions. Record the endpoint version, permitted event types and the actor approving the change. A successful ownership challenge can establish control of an endpoint at that moment; it must not exempt later deliveries from network checks. Send only a synthetic challenge until activation completes.

Check the address used by the connection

A registration-time lookup is insufficient. OWASP's webhook security guidance calls for checking the resolved destination at connection time. DNS can change after an endpoint was accepted.

The practical requirement is stronger than “resolve, check, then call a normal fetch function.” If the HTTP client performs another lookup, it may connect to a different address. Use a controlled egress component or connection mechanism that binds the checked address to the actual connection, while retaining correct hostname-based TLS verification. Test the resolver and proxy behaviour of the deployed stack.

Account for both address families. IANA's IPv4 registry distinguishes private-use, loopback, link-local and other special-purpose ranges. Its IPv6 registry also includes unique-local, link-local and IPv4-mapped addresses. A check for strings starting with 10. or 192.168. is not an address policy.

Have security engineering own the classification rules, including mapped addresses, translation paths and your organisation's own networks. “Globally reachable” is a registry property, not permission to contact a service. Publicly addressed internal administration systems still belong on your prohibited-destination list.

Disable automatic redirects. Require customers to register the intended endpoint instead. Otherwise an accepted public address can direct a later request toward a destination that never passed the original check. Apply the same rules to test deliveries, retries and support-triggered replays.

Put the sender behind a real egress boundary

The Standard Webhooks specification recommends filtering outbound requests through a dedicated proxy and isolating webhook workers from internal services. That is useful separation: a defect in URL validation should not immediately grant access to the application's administration network.

For this design, the worker reads an authorised delivery envelope and submits it to the egress gate. It does not carry a general-purpose database administrator credential. Restrict the worker's access to queues, signing material and delivery records; restrict the egress component to the destinations its policy permits.

Make the route mandatory. A proxy setting in one SDK is not an enforced boundary if another library can open a direct socket. Review network rules, environment proxy behaviour and metadata-service access. Test from the deployed worker identity rather than a developer laptop with different routes.

The destination controls must also govern health checks and activation requests. A “Test endpoint” button is still a server-side request engine, even when the payload contains no customer data. Give it rate limits and the same audited delivery path.

Outbound webhook decision flow: commit the event, select an authorised subscription, validate the actual destination through an egress gate, send signed bytes over verified TLS, then acknowledge or retry through the same gate.

Original infographic: SultanByte. Proposed sender workflow informed by OWASP, AWS transactional-outbox guidance and Standard Webhooks, October 2026. The retry path repeats destination checks.

Commit the event before scheduling delivery

AWS's transactional outbox guidance addresses the gap between updating a database and sending a notification. Write the business change and its outbox record in one transaction; a relay processes committed records afterward. AWS also warns that duplicate notifications remain possible.

For a webhook service, separate the business event from delivery attempts. One event may have several authorised subscriptions, and each subscription may need retries. Use a stable event identity, a subscription identity and an attempt identity rather than making one identifier perform every job.

Bind a queued delivery to an endpoint version. If a customer edits the URL while a backlog exists, do not silently send historical payloads to the new address. Choose and document a migration policy: cancel old deliveries, retain the previously approved endpoint, or require an explicit replay decision. The right policy depends on the product, but an accidental mixture is difficult to explain to a buyer.

Recheck subscription status before sending. Disabling an integration should stop pending work according to the documented cancellation boundary. Record what happens to an already in-flight attempt so the dashboard does not promise an impossible instant recall.

Give recipients a usable verification contract

Standard Webhooks defines authentication covering the message identifier, attempt timestamp and body. Follow a documented protocol and its maintained libraries rather than inventing a new concatenation format. Keep the message identity stable across retries while recording each attempt separately.

Serialize the payload once and sign the bytes that will be sent. Publish receiver fixtures containing Arabic text and mixed-script identifiers, then verify that customers can authenticate the original bytes without parsing and reserializing them first.

GitHub's webhook recommendations warn against credentials in callback URLs and recommend HTTPS with certificate verification. Keep secrets out of query strings and customer-visible delivery logs. Do not offer a production “ignore certificate errors” switch as an integration shortcut.

For a shared-secret protocol, isolate secrets by endpoint. Document planned rotation and emergency revocation separately: an overlap window is useful during a coordinated change, but continuing to accept a known-compromised secret preserves the forgery risk. OWASP makes that distinction explicit in its rotation guidance.

Define failure handling as part of the API

The Standard Webhooks delivery guidance treats a 2xx response as success, recommends backoff with jitter and advises against following redirects. It also distinguishes a rate-limit response from 410 Gone, which signals that the endpoint should be disabled.

Turn that guidance into a published product contract. Specify request deadlines, retry duration, concurrency limits, payload limits and the conditions that pause an endpoint. These are product choices to test, not universal values to copy from another provider.

Separate a network failure from a policy rejection. A prohibited destination should not generate an endless retry storm. An allowed endpoint returning a temporary error may deserve another attempt, subject to the retry budget. Bound any Retry-After handling so an untrusted response cannot reserve work indefinitely.

A timeout leaves uncertainty: the recipient may have accepted the event before the response was lost. Tell integrators to deduplicate stable event identities. Do not advertise exactly-once business execution merely because your queue has a deduplication feature.

Provide an authorised replay tool with a clear preview of destination version and event scope. Replays must pass current subscription and egress policy. Keep a permanent distinction between the original event time and the time someone requested another delivery.

Make regional routing visible to the buyer

Consider two proposed deployments: a Saudi customer environment and a UAE customer environment. Give each an explicit configuration for queue storage, delivery workers, signing keys, diagnostics and approved recovery routes. Do not assume that approval for one environment covers the other.

Ask the customer where its receiving service and any intermediary relay process the payload. A country-specific domain suffix or endpoint IP is not sufficient evidence of the whole processing arrangement. Record the customer-approved destination and the limits of what you verified.

Prefer a minimal notification when a full document is unnecessary. An event type and opaque resource identifier can let an authorised receiver retrieve the required record through a separate API. That changes the access pattern; it does not automatically settle privacy or cross-border obligations. Have the relevant specialists assess the actual data flow. This is practical engineering information, not legal advice.

For founders, the useful sales artifact is a delivery-boundary sheet: what leaves the environment, which route it follows, who can redirect it and what happens during failure. Avoid a blanket “MENA-compliant webhooks” claim.

Test the boundary before enabling self-service

Use synthetic events and destinations you control in a non-production environment. The following is a proposed acceptance plan, not benchmark results:

  • Register an endpoint that resolves to an allowed address, then change its DNS answer to a prohibited test destination. Confirm that the delivery cannot connect there.
  • Return a redirect from an allowed endpoint. Confirm that the sender does not follow it.
  • Exercise IPv6 and mapped-address classification, not only ordinary IPv4 inputs.
  • Accept an event at the receiver but drop its response. Confirm that a retry preserves event identity and does not require a duplicate business action.
  • Disable or edit a subscription while deliveries are queued. Verify the documented endpoint-version policy.
  • Attempt a replay as an administrator from another tenant. Require rejection before payload access or network activity.
  • Remove the approved egress route. Confirm that the worker cannot bypass it through direct networking.

Retain the delivery decision and network evidence for each case. A dashboard error alone does not prove that no connection occurred. Launch only when the sender can explain both why an attempt was permitted and why a forbidden attempt could not leave.