Middleware chain
Every request passes through a middleware chain before reaching the proxy handler. The chain executes top-to-bottom on the request path and bottom-to-top on the response path. The order is set insvc/frontline/routes/register.go:
- PanicRecovery. Catches panics in downstream handlers so a single request cannot crash the process.
- Reserved header strip. Removes reserved headers, including
X-Unkey-Principal, so a client cannot forge an identity. It removes everyX-Unkey-*trailer. It preserves theX-Unkey-Frontline-Metarequest header for verification in the proxy handler. - Logging. Structured request logging. Skips internal paths (
/_unkey/internal/). - ClickHouseLogging. Creates a tracking context with a start timestamp and, on completion, writes the full request and response to ClickHouse. It wraps observability so it reads the final status code after observability has written the response.
- Observability. Starts an OpenTelemetry span (
frontline.proxy), records Prometheus metrics (unkey_frontline_requests_total), maps fault codes to HTTP status codes, and renders an HTML error page when the client prefers HTML. - Timeout. Enforces the configured request timeout.
Proxy handler
After the middleware chain, the proxy handler runs. Its inputs are the router service, the proxy service, and the policy engine.1. Verify peer metadata
The handler checks forX-Unkey-Frontline-Meta. If the header is present, the
handler removes it and verifies the PASETO v4.public token. A request without
valid metadata starts with an empty hop history. Frontline treats empty,
duplicate, invalid, expired, or oversized metadata as absent. Invalid metadata
never blocks a request.
2. Route the hostname
The handler callsRoute(hostname) on the router. The router resolves the hostname to a frontline_route (deployment ID, sentinel_config, upstream protocol), parses the sentinel_config bytes into a policy list, and selects a destination. For a local destination the decision carries the running instances in shuffled order plus the parsed policies. If the hostname has no configured route, or the deployment has no running instance in any reachable region, the router returns a Frontline.Routing error (for example NoRunningInstances, surfaced as 503).
3. Evaluate policies
When the deployment has policies and the engine is configured, the engine evaluates each policy in order against the request. A policy that rejects the request (invalid key, rate limited, insufficient permissions) produces an error response before any byte is proxied. On success, the first authentication policy yields aPrincipal, which the handler serializes to the X-Unkey-Principal header. When the deployment has no policies, the request is forwarded without policy evaluation.
4. Forward the request
The handler proxies to a running instance of the deployment in the same region, attempting the shuffled candidates in order and advancing on dial failures. When every local instance fails and a peer region has a healthy instance, the request falls through to a peer Frontline. The following headers are set on the proxied request:
Before a cross-region forward, Frontline sets
exp to 1 minute in the future
and appends a signed hop entry. The entry contains the region, request ID,
Frontline ID, and forward time as Unix milliseconds. The hop history length is
the hop count. Frontline rejects the forward when the length reaches max_hops.
5. Stream and record the response
The handler streams the instance response back to the client. The ClickHouse logging middleware records the request and response (status, headers, and a size-capped body) and the timing breakdown for analytics.Headers reference
Set on cross-region forwards
X-Unkey-Frontline-Meta contains a PASETO v4.public token. Frontline accepts the
metadata only when the request has one non-empty header value, the signature is
valid, and the token has not expired. Each forwarding Frontline appends one hop,
replaces the metadata, and sets exp to 1 minute in the future. Each hop records
the region, request ID, Frontline ID, and forward time. Frontline removes the
metadata before it forwards a request to a deployment instance. The complete
header value cannot exceed 4,096 bytes.
Frontline removes invalid metadata and treats it as absent for all requests.
This behavior prevents a client-controlled header from blocking service.