Skip to main content
Egress is an origin-only HTTPS allowlist. ctx.fetch refuses anything outside the list synchronously, before it opens a socket — including redirect targets. It is a security boundary, not a convenience filter.

Declaring egress

List only the origins you call:
Scheme, host, and optional port only. No path, query, fragment, credentials, or http:. Wildcards are a single leading *..

Validation

defineIntegration() rejects invalid entries with the offending entry quoted — the message begins Egress entry "<entry>" is invalid. Entries are https origins only:

Runtime behavior

Denied calls throw EgressDeniedError (from @ekanos/sdk/context) synchronously:
Redirect targets are checked too. If https://api.acme.example/v1/data redirects to https://evil.example, the fetch is denied. EgressDeniedError carries code: 'EGRESS_DENIED', the refused origin, and an optional reason. The host also refuses an allowlisted name that resolves into a private, loopback, link-local, or other non-public range, on the first request or any redirect hop. Those denials are found after DNS, so they reject the returned promise instead of throwing synchronously, and reason names the category (never the address).

Common patterns

Single provider

Most integrations call one API:

Multi-region

If you need multiple regions:

Wildcard for CDN

If assets come from a wildcard subdomain:

Explicit ports

If the API uses a non-standard port:
But https://api.acme.example:443 is redundant — 443 is the HTTPS default.

Promotion review

Widening this list is a security-posture change that a human reviewer looks at during promotion. The reviewer reads your declaration against what your handlers actually do, so: Declare only origins you call. Do not add https://*.example “just in case” — the reviewer will question it, and it weakens your security posture. If you call a new origin, add it to the declaration. ctx.fetch denies anything not listed.

Error handling

Special case: OAuth

Both OAuth endpoints must be in your egress list. defineIntegration() rejects the definition otherwise and tells you which origin to add:
The code exchange runs through your declared egress, so an origin the reviewer never saw is an origin the exchange must not reach.

Next steps

  • Secrets — credential management
  • Tools — use ctx.fetch in a tool
  • OAuth — declare and handle OAuth