Set Up an Authentication Proxy
Why a proxy is needed
The User Service keeps a signed-in user's browser session in a secure cookie that is
HttpOnly and SameSite=Strict. Browsers only send a SameSite=Strict cookie on
requests to the same top-level domain that set it. Your application runs on your own
domain (for example https://app.example.com), while the User Service authentication
endpoints run on an Axinom domain (https://user-auth.service.eu.axinom.net). Because
these are two different domains,
the browser would refuse to send the session cookie when your application asks for a new
access token, and the user would appear signed out.
To solve this, serve the User Service authentication endpoints from a hostname on your
own domain (for example https://id.example.com) by running a reverse proxy that
forwards those requests to the User Service. The session cookie is then scoped to your
domain, so the browser sends it on every token request as required.
See How Authentication Works for the background on the session model.
What the proxy must do
- Serve over HTTPS on a hostname under your application's top-level domain, for
example
https://id.example.comfor an application athttps://app.example.com. The proxy terminates TLS using your own certificate for that hostname. - Forward requests to the User Service at
https://user-auth.service.eu.axinom.net, preserving the full request path and query string. - Pass cookies through unchanged in both directions. Forward the incoming
Cookieheader to the User Service, and return the User ServiceSet-Cookieheader to the browser without rewriting its name, path, or attributes. - Use a dedicated subdomain whose root maps to the User Service. This avoids having to strip a path prefix and keeps the cookie path intact.
Forward the entire authentication host through the proxy, which is what the nginx
example below does (location /). Always forward everything rather than selecting
individual endpoints: it keeps your client configuration to a single base URL, and it
means any endpoints added to the authentication API in the future are covered
automatically, without a change to your proxy.
The GraphQL APIs (profile management, sign-up, and password reset) are authenticated
with a Bearer access token rather than the session cookie, are served from a different
host (https://user.service.eu.axinom.net), and are not routed through this proxy.
Register the proxy with your application
In the application configuration in the Admin Portal, set:
- Allowed Origins - the base URL of your application, for example
https://app.example.com. - Allowed Proxy URLs - the base URL of your proxy, for example
https://id.example.com.
Your application must then use the proxy URL as its authentication base URL, so that the sign-in redirect and the token requests all pass through the proxy. See Set up a Managed IDP for where these fields are configured.
Example: nginx
The following is an illustrative nginx server block for a proxy at id.example.com
that forwards to the production User Service. Adapt it to your environment. The exact
directives differ across proxy products (Caddy, HAProxy, cloud load balancers, and so
on), but the requirements above are the same.
server {
listen 443 ssl;
server_name id.example.com;
# Your TLS certificate for id.example.com
ssl_certificate /etc/ssl/certs/id.example.com.pem;
ssl_certificate_key /etc/ssl/private/id.example.com.key;
location / {
# Forward to the User Service, preserving the path and query string
proxy_pass https://user-auth.service.eu.axinom.net;
# Present the correct host and SNI to the User Service
proxy_set_header Host user-auth.service.eu.axinom.net;
proxy_ssl_server_name on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Do not rewrite cookies. nginx forwards the Cookie and Set-Cookie
# headers unchanged by default, which is exactly what is required so
# that the session cookie stays scoped to id.example.com.
}
}
# Redirect plain HTTP to HTTPS
server {
listen 80;
server_name id.example.com;
return 301 https://$host$request_uri;
}
Key points in this configuration:
proxy_passwithout a trailing path preserves the original request URI, so/oauth,/token, and the other endpoints reach the User Service unchanged.proxy_set_header Hosttogether withproxy_ssl_server_name onmake the upstream TLS handshake and routing use the User Service hostname.- There is deliberately no
proxy_cookie_domainorproxy_cookie_pathrewriting. The session cookie must reach the browser exactly as the User Service set it.
Native applications
Native applications (mobile, smart TV, and similar) do not rely on the browser cookie store and therefore do not need this proxy. They receive the session in a form they store and replay themselves, or use the Device Authorization flow.