Skip to main content

Egress

The egress field in lumio.config.json controls which external hosts your extension's server actions can make HTTP requests to via ctx.fetch().

Configuration​

{
"egress": {
"allowHosts": [
"site.api.espn.com",
"*.scdn.co",
"api.openweathermap.org"
],
"allowPorts": [8443]
}
}

Fields​

allowHosts​

An array of allowed hostnames. Only hosts listed here can be reached from ctx.fetch().

"allowHosts": [
"api.example.com",
"*.example.com",
"cdn.example.com"
]

Wildcard support: * matches any single subdomain level:

PatternMatchesDoes not match
"api.example.com"api.example.comstaging.api.example.com
"*.example.com"api.example.com, cdn.example.comexample.com, a.b.example.com

Wildcards must cover a registrable domain. The part after *. has to be longer than its public suffix in the ICANN section of the Public Suffix List. *.example.com, *.example.co.uk and *.myshopify.com are accepted; *.com, *.co.uk and *.io are not. * is only allowed as the leading *. label, so api.*.com and *example.com are rejected too. Manifest validation enforces this rule, so lumio deploy fails with Egress host '…' is not allowed instead of shipping a pattern that would open a whole top-level domain.

allowPorts​

An optional array of additional allowed ports. Port 443 (HTTPS) is always allowed and does not need to be listed. HTTP (port 80) is never allowed.

"allowPorts": [8443, 9443]

Security rules​

All ctx.fetch() calls are subject to these rules regardless of allowlist:

RuleDescription
HTTPS onlyHTTP is blocked. All requests must use https://
Public addresses onlyOnly globally routable unicast addresses can be reached — see Blocked address ranges. This applies to IP literals in the URL (https://10.0.0.1/, https://[::1]/) before any DNS lookup, and to every address a hostname resolves to
No DNS rebindingThe connection is pinned to the validated address, so the host cannot re-resolve to an internal IP
No redirectsRedirect responses are returned as-is and never followed
30s timeoutRequests exceeding 30 seconds are cancelled
10 requests/invocationMaximum 10 ctx.fetch() calls per action run
10 MiB response limitA response body larger than 10 MiB fails the call

Blocked address ranges​

FamilyBlocked
IPv40.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.0.0/24, 192.0.2.0/24, 192.88.99.0/24, 192.168.0.0/16, 198.18.0.0/15, 198.51.100.0/24, 203.0.113.0/24, 224.0.0.0/4 (multicast), 240.0.0.0/4 (reserved, incl. 255.255.255.255)
IPv6everything outside global unicast 2000::/3 (::, ::1, IPv4-compatible ::/96, 64:ff9b:1::/48, fc00::/7, fe80::/10, ff00::/8, …), plus 2001::/32 (Teredo), 2001:2::/48, 2001:10::/28, 2001:20::/28, 2001:db8::/32 and 3fff::/20
IPv6 carrying IPv4::ffff:0:0/96 (IPv4-mapped), 64:ff9b::/96 (NAT64) and 2002::/16 (6to4) are judged by the embedded IPv4 address — blocked when that address is in a blocked IPv4 range

Common patterns​

External sports API​

{
"egress": {
"allowHosts": ["site.api.espn.com", "cdn.espn.com"]
}
}

Weather service​

{
"egress": {
"allowHosts": ["api.openweathermap.org"]
}
}

Spotify album art​

{
"egress": {
"allowHosts": ["i.scdn.co", "*.scdn.co"]
}
}

Webhook delivery​

{
"egress": {
"allowHosts": ["discord.com", "hooks.slack.com"]
}
}

Review​

The egress allowlist is reviewed during extension approval. Reviewers check:

  • Do the declared hosts match the extension's stated purpose?
  • Are wildcards appropriately scoped?
  • Are the hosts known, reputable services?

Allowlists that are broader than the extension needs, or allowlists that include analytics/tracking services not needed for the extension's function will result in rejection with a request to narrow the scope.