Skip to content

CommonEngine: allow dynamic or per-request allowedHosts for multi-tenant apps with custom domains #32910

@GabrielMJin

Description

@GabrielMJin

Which @angular/* package(s) are relevant/related to the feature request?

No response

Description

Angular SSR (CommonEngine / @angular/ssr) validates the request URL hostname against allowedHosts to reduce SSRF risk. Configuration is limited to the CommonEngine constructor, NG_ALLOWED_HOSTS at process startup, and build options in angular.json.

Many multi-tenant products (e.g. storefronts) let each tenant use their own hostname. Those hosts are often unknown at build time and grow over time. A static list is hard to maintain: it ties every new domain to a redeploy, a process restart, or a regenerated environment variable. Wildcard entries only help when all custom domains share a predictable suffix; they do not cover arbitrary customer-owned domains (e.g. customer.com, shop.otherbrand.com.br).

Today, allowedHosts is fixed for the lifetime of the CommonEngine instance, with no supported way to authorize a hostname using per-request logic (for example after resolving the tenant from Host and verifying it with a backend).

Proposed solution

Introduce a supported way to authorize hostnames for SSR in these setups, for example one or more of:

Per-render overrides — allow passing additional allowedHosts (or a merged policy) on render() / equivalent render options so a single engine instance can accept validated hosts without a full process restart.

Documented callback — e.g. (hostname, request) => boolean | Promise with clear security guidance, so the application can implement tenant resolution + backend checks while Angular keeps a safe default when the callback is not used.

Documented proxy-only pattern — if the team considers it valid when Host / X-Forwarded-Host are fully controlled by a trusted reverse proxy, official guidance (and any API hooks needed) would help teams that already terminate TLS and normalize headers at the edge.

The goal is to keep strong defaults for SSRF while not requiring an exhaustive static list of every tenant hostname.

Alternatives considered

Wildcard allowedHosts — works only for domains under a suffix the platform controls; not viable for arbitrary customer CNAMEs.

Large / generated NG_ALLOWED_HOSTS — operational overhead (restarts, deployment pipelines) and does not scale smoothly with self-service custom domains.

Static lists in angular.json or environment files — same limitation: known only at build/deploy time.

Relying on undocumented behavior (e.g. mutating internal allowlist structures) — fragile across Angular versions and not appropriate for production.

None of these fully address multi-tenant SSR where hostname authorization depends on runtime tenant resolution or a backend call.

Thanks for considering this use case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions