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:
| Pattern | Matches | Does not match |
|---|---|---|
"api.example.com" | api.example.com | staging.api.example.com |
"*.example.com" | api.example.com, cdn.example.com | example.com, a.b.example.com |
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:
| Rule | Description |
|---|---|
| HTTPS only | HTTP is blocked. All requests must use https:// |
| No private IPs | RFC 1918 ranges and loopback are blocked |
| No DNS rebinding | Hostnames must resolve to public IPs |
| 30s timeout | Requests exceeding 30 seconds are cancelled |
| 10 requests/invocation | Maximum 10 ctx.fetch() calls per action run |
| 4 MB response limit | Response bodies larger than 4 MB are truncated |
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?
Overly broad allowlists (e.g., "*.com") 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.