Support environment variable substitution in HTTP hook url field
Problem Statement
HTTP hooks (type: "http") support environment variable substitution in headers via allowedEnvVars, but not in the url field. The URL is validated at settings load time as a literal string, so "url": "$MY_WEBHOOK_URL" fails with "Invalid URL".
This forces users to fall back to type: "command" with curl when the webhook URL varies per deployment.
Proposed Solution
Extend the existing allowedEnvVars mechanism to also resolve $VAR / ${VAR} references in the url field, with validation happening after substitution rather than before.
If the referenced env var is unset or empty, the hook should be silently skipped (consistent with optional webhook behavior).
Alternative Solutions
- Current workaround: fall back to
type: "command"with ash -c+curlone-liner. This works but reintroduces shell subprocess overhead andcurldependency — exactly what native HTTP hooks were designed to eliminate. - Proxy approach: hardcode a localhost URL that proxies to the real endpoint. Over-engineered for this use case.
Use Case Example
We distribute a managed-settings.json across multiple installations (multi-tenant). The webhook endpoint differs per deployment and is injected via environment variable.
Current workaround (working but defeats the purpose of HTTP hooks):
{
"type": "command",
"command": "sh -c 'test -n \"$WEBHOOK_URL\" && curl -sS -X POST \"$WEBHOOK_URL\" -H \"Content-Type: application/json\" -H \"Authorization: Bearer $WEBHOOK_TOKEN\" -d @- 2>/dev/null || true'"
}
What we'd like to write:
{
"type": "http",
"url": "$WEBHOOK_URL",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer $WEBHOOK_TOKEN"
},
"allowedEnvVars": ["WEBHOOK_URL", "WEBHOOK_TOKEN"]
}
Additional Context
- The
allowedEnvVars+$VARmechanism already exists and works forheaders— extending it tourlshould be consistent with the current design. - When the URL is invalid after substitution (or the env var is unset), the hook should be skipped silently rather than invalidating the entire settings file. Currently, an invalid
urlcauses the entiremanaged-settings.jsonto be skipped ("Files with errors are skipped entirely"), which disables all other settings in the file.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗