Header-based authentication to legacy apps with the authentik proxy

Pass the signed-in user and application identity to apps that trust HTTP headers, and make sure nothing reaches them except through the proxy. This page covers the header options, setup order and what to confirm before rollout.

On this page

Header-based authentication to legacy apps with the authentik proxy: when teams need it

Teams need header-based authentication when an application cannot speak OIDC or SAML but reads the signed-in username from an HTTP header. The authentik proxy provider answers this directly: after a user signs in to authentik, the proxy outpost sits in front of the application and passes identity to it as headers. The outpost sets user-specific headers (such as the username and email) and application-specific headers for the upstream app, so the application can trust the value it receives without running its own login. The application keeps its existing access logic, while authentik takes over sign-in, multi-factor prompts and policy decisions.

This pattern is usually the better choice when the application's login code is old, unsupported or costly to change, and the app already maps a header value to a local account or role. Rebuilding its login means changes to the application code, new test cycles and a new attack surface inside the app. A proxy approach moves that work to the edge, but it also moves trust to the edge. Before you commit, confirm that the application honors only the headers it is meant to receive, that users cannot reach it directly, and that any header the client sends is stripped or overwritten before it reaches the app. Ask your vendor or the authentik documentation which headers the outpost sets in your version, since the exact names and behavior should be verified, not assumed.

This page covers how the proxy outpost's user and application headers work, how additionalHeaders on users and groups add static values, how custom dynamic headers are built with custom scope mappings, and how to keep the application unreachable except through the proxy. It also covers the decisions and checks that matter most for a legacy app: which headers to trust, how to test header spoofing, and how to confirm that direct network paths to the app are closed. Reverse proxy specifics are covered in the sibling pages for each proxy.

Which header option fits which application

This table compares the three ways to pass identity to an upstream application: the built-in user and application headers, static values from additionalHeaders, and dynamic values from custom scope mappings. Read each row as a question you should answer before choosing, and treat the risk column as the cost you accept by picking that option.

Header optionBest fitMaintained byMain risk
Built-in user and application headersApps that only need the signed-in username, email or application name to label sessions or pre-fill a profileauthentik proxy outpost, with no extra configuration beyond the providerThe app must accept the header names authentik sends, so confirm the exact names in your environment before relying on them
Static headers via additionalHeaders on a groupA fixed flag for everyone in a group, such as a tenant or environment labelThe administrator who edits the group in authentikValues go stale when membership changes, so a user removed from a group may keep the old header until the session ends
Static headers via additionalHeaders on a userA single account needing a fixed attribute the app cannot read from its own directoryThe administrator who maintains that user recordPer-user values multiply quickly, and each one is another place for drift and manual errors
Dynamic headers via custom scope mappingsRoles, departments or entitlements computed from current group membership or user attributes at loginThe team that writes and tests the scope mapping expressionLogic errors can grant or withhold access silently, so test each mapping with representative users
Header trust in the applicationAny app that reads identity from a header instead of its own loginThe application owner, who must enforce the header only from the proxyIf the app is reachable without passing through the proxy, anyone can forge the header, so block direct access
Identity header names in the app configApps with fixed header names that cannot be changedThe application owner and the authentik administrator togetherA mismatch between header names in the app and the proxy causes silent failures or blank user fields
Session lifetime of header valuesAny header that carries access decisionsThe authentik administrator setting session and token lifetimesA header set at login stays valid for the session, so revoked access may persist until the session expires
Change testing before releaseDynamic headers and any header that drives rolesThe deploying team, before each change goes to usersChanges take effect only on new sessions in many cases, so verify with a fresh login and a previously signed-in account

How to set up header authentication step by step

This sequence takes an application that trusts HTTP headers from confirmed identity inputs, puts authentik's proxy outpost in front of it, and closes the direct path so that only the proxy can supply those headers. Each step ends with a check you can run before moving on.

  1. Confirm the app's header names and trust model

    Before touching authentik, document exactly which headers the application reads (for example, the username, email and group headers), whether it expects them on every request, and how it decides to trust them. Ask the application owner or read its configuration reference, and confirm whether the app also has a local login that would bypass the headers. The step is done when you have a written list of header names, value formats and the network source the app will accept them from. Check: a reviewer can read the list and say which request should be allowed and which should be refused.

  2. Create the proxy provider and application

    In the authentik admin interface, create a proxy provider set to the mode that matches your app (single application or domain level), enter the external hostname users will open, and then create the application that links to it. Keep the external host separate from the app's internal address, since the outpost will reach the app over the internal network. The step is done when the application appears in the library and the provider shows the expected external host. Check: the provider's external host and the application's launch URL match the hostname in your written plan.

  3. Assign policies to limit who can sign in

    Bind a policy or group binding to the application so that only the users and groups that should reach the app are authorized. Authorization happens before headers are sent, so an unauthorized user never reaches the upstream application. Test with one allowed account and one account outside the group. The step is done when the allowed user receives the application and the other user is denied. Check: a denied user gets an authentik access denial page and the application receives no request from that account.

  4. Configure user, group and dynamic headers

    Work out which values the app needs. Use the headers the proxy outpost sets for the user and the application, add static values through additionalHeaders on users or groups, and create custom scope mappings for any value that changes per user, such as a role claim formatted for the app. Confirm the header names match the list from the first step exactly, including case and any prefix. The step is done when a test account's session produces the expected header values. Check: capture the headers the app receives for the test user and compare each one to the written list.

  5. Route the app hostname through the outpost

    Configure your reverse proxy so that the application hostname sends traffic to the authentik proxy outpost, which forwards authenticated requests to the app and sets the headers. The proxy configuration differs by product, so follow the guide for your proxy and confirm the outpost path and header pass-through settings there. The step is done when a browser request to the hostname redirects to the authentik sign-in page and, after login, loads the application. Check: the application loads through the hostname and its logs show the expected user identity.

  6. Test that the app rejects spoofed headers

    Send requests directly to the application's internal address with the identity headers set to a made-up user, and also send the same headers through the public hostname while signed out. The application must refuse both, and the outpost must not pass a client-supplied header through to the app. Repeat with a header the proxy is expected to overwrite. The step is done when every spoofed request fails and every legitimate request succeeds. Check: record the status codes and the app log lines for each request so you can show the result to a security reviewer.

  7. Block direct access to the application

    Restrict the application so it accepts connections only from the proxy, using network rules, firewall policy, or a private network path, depending on your platform. Remove any public port or DNS record that points straight at the app, and disable local bypass logins if the app allows them. Confirm the proxy can still reach the app after the rule is applied. The step is done when a request from outside the proxy network cannot reach the application at all. Check: run the direct-access test again from an untrusted network segment and confirm it times out or is refused.

Where the proxy sits in front of the application

On a single Docker Compose host, the simplest layout runs the authentik server container, which includes core and the embedded outpost, alongside a worker container and PostgreSQL. The proxy can sit on the same host as the application, so no separate outpost service is needed. The Compose guide positions this setup for test environments and small-scale production and calls for at least 2 CPU cores and 2 GB of RAM.

  • Fit: suits a small number of legacy applications on one host, where all traffic already enters through one reverse proxy.
  • Components: the server, worker and PostgreSQL run together, and authentik 2025.10 removed Redis, so caching, tasks and sessions now live in PostgreSQL.
  • Sizing: the 2 CPU and 2 GB RAM figure is a minimum from the guide, so add headroom for your own login volume and proxied traffic.
  • Shared resources: proxied traffic competes with the identity service on the same host, so a busy application can slow sign-ins.
  • Hardening: the embedded outpost is served from the server itself, so decide whether you need it at all before you enable proxy routes.

Check that the reverse proxy reaches the embedded outpost on the server, and that the application cannot be contacted on its own port from outside the host.

Keeping the legacy app unreachable except through the proxy

Header-based sign-in only holds if the application trusts headers from one place. The cards below cover the controls that keep that place the proxy, and each one names something your team can test before go-live and after every change.

Block direct access to the app

If users or attackers can reach the application's port directly, they can send their own X-authentik style identity headers and skip sign-in entirely. Verify this by requesting the application's internal address and hostname from a machine outside the proxy network, and confirm the connection is refused or times out. Repeat the test after any change to load balancers, DNS or published ports.

Restrict the listening network

Bind the application to a private interface or a Docker network that only the outpost can join, instead of 0.0.0.0 on a shared host. In Kubernetes, a NetworkPolicy should allow ingress to the application pods only from the outpost pods. Ask the platform team to show the rule and test it from a pod in another namespace.

Strip client-supplied identity headers

The proxy in front of the application should remove any identity headers a client sends before it forwards the request, then set them itself from the authenticated session. Without this step, a request that reaches the proxy with a forged header may pass it through unchanged. Test by sending a request with a made-up user header while signed out and confirming the application still shows no user.

Limit trusted proxy addresses

Many applications accept identity headers from any source address or from a configurable list of trusted proxies. Set that list to the outpost's exact address or subnet, and avoid wildcard or load-balancer ranges that other clients can reach. Confirm the setting in the application's own configuration, since defaults vary by product and version.

Review group-based headers on change

Group headers are copied from directory state when a session is created, so a user removed from a group can keep the old value until the session expires or is revoked. Decide the session lifetime with the application owner, and test by removing a user from a group and confirming the application denies the old role. Keep the mapping list short and reviewed.

Keep identity values out of logs

Access logs from the proxy and the application can record full headers, which often include user names, email addresses and group lists. Set the proxy's log format to omit or hash identity fields where your policy requires it, and check a sample of log lines from a test sign-in. Route these logs to a store with the same access controls as the source system.

Trade-offs of header trust compared with OIDC or SAML

Header-based authentication is a reasonable bridge when an application has no OIDC or SAML support, cannot be changed in the time available, and can be placed where only the proxy reaches it. It is the wrong pattern when the application will stay in service for years, holds sensitive data, or has other entry points. The core trade-off is that the application stops verifying identity itself. It accepts a value such as the user header set by the proxy outpost and treats it as true. With OIDC or SAML, the application validates a signed token or assertion and can check issuer, audience and expiry. With header trust, the only evidence is the network path, so the proxy and the network design become the security boundary.

That dependence has operational consequences. Every request must pass through the proxy, so a proxy outage, a misconfigured route, or a bypass path such as a second ingress, a direct container port or a debug endpoint removes the access check entirely. Before go-live, confirm that the application's port is not published on any host or network the proxy does not sit in front of, that the application rejects requests lacking the proxy's header source, and that internal health checks and service-to-service calls are handled deliberately. Also confirm how the outpost behaves when it cannot reach the authentik server, because your availability target depends on it. Ask the application's vendor or maintainers whether they plan native OIDC or SAML support, since that answer determines whether the pattern is temporary.

Plan the exit path at the start, not when the bridge begins to fail. Record which headers the application reads, which roles or groups they map to inside the application, and who owns that mapping. Keep the authentik provider and application definitions in version control or exported configuration so the setup can be reproduced. Set a review date for the decision, and treat any new feature that depends on a header as a new trust decision that needs the same review. When native SSO becomes available, run both paths in parallel for a set of test users, compare the resulting account and role assignments, and remove the header path only after you have verified that no route still reaches the application without the new login.

Limits to confirm in your environment

Header-based authentication only works when the application, the proxy and the authentik release agree on the same contract. The cards below list the assumptions most often wrong in practice, so each one can be tested against the actual application and version before traffic is moved.

Exact header names the app reads

The proxy outpost sets user-specific and application-specific headers, and your application must read exactly those names. Header names are matched as configured, and many applications expect a particular casing or prefix. Read the application's authentication configuration or source, then compare it with the headers the outpost sends from a test request. Treat any mismatch as a blocker, not a configuration detail to patch later.

Multi-valued group headers

Group membership is often passed as one header, and some applications read only the first value, parse a comma-separated list differently, or expect repeated headers. Confirm how the application handles multiple values before relying on group-based authorization inside it. If the application cannot parse several groups, decide whether to map a single role per header or to keep authorization in the proxy policy.

WebSocket and upload behavior

Protected applications that use WebSockets, server-sent events or large file uploads may behave differently when traffic passes through the outpost and the reverse proxy in front of it. Test a real session for each feature, including reconnects after idle periods, and confirm body size limits at both the proxy and the application. Record which paths are expected to bypass authentication, if any.

Session lifetime alignment

The outpost session and the application's own session can expire at different times. If the application keeps a session longer than authentik does, users may stay signed in to the app after the proxy has ended their access. Set the authentik session length, the cookie settings and the application timeout together, and test logout from both sides so a closed session is closed everywhere.

Supported authentik version line

Confirm which authentik version line your rollout will use and whether it still receives security fixes when you go live and during support. The security policy lists the supported versions and states that security releases are announced at least 24 hours in advance, so plan a window to apply them. Check the policy again before go-live rather than relying on a version recorded in an earlier design document.

Unreachable except through the proxy

Trusted headers are only safe if clients cannot send them directly to the application. Confirm that the application listens only on a private network reachable from the proxy, that the proxy strips any incoming identity headers before setting its own, and that a direct request with forged headers is refused. Test this from outside the proxy network, because internal routing often exposes the backend by accident.

Questions teams ask before header-based authentication rollout

How much effort does header-based authentication to a legacy app take?

Effort depends mostly on how many applications sit behind the proxy, how much each one trusts its headers, and how many environments need testing. A single app with one hostname and a clear header contract is a small, contained job. A portfolio of apps with mixed routing, shared domains and different header expectations takes longer because each app needs its own check. No supplied figure sets a duration, so ask any provider for a written breakdown per application, covering design, outpost deployment, header mapping, testing and cutover. Ask which parts are one-time (design, initial configuration, cutover) and which recur (new apps, upgrades, user and group changes).

What drives the cost of a proxy rollout up or down?

The main drivers are the number of applications, the number of distinct hostnames and paths, how many groups need different header values, the reverse proxy in use, and the depth of testing required by your change process. Applications that already read a trusted header are cheaper to protect than applications that need code changes to accept one. Quotes should separate the discovery and design work, the configuration per application, the outpost deployment on Docker or Kubernetes, and the handover to your team. Ask which items are fixed in the written scope and which are priced as change requests.

Can our internal team set this up without a partner?

Yes, if your team has someone who can operate authentik, configure a proxy provider, edit reverse proxy routing and test header handling in a non-production environment. The hardest part is usually not the authentik setting but the application side: confirming which headers the app trusts, locking the app so only the proxy can reach it, and proving that a forged header from a client is rejected. Teams that lack an application owner for each legacy system often find the knowledge gap takes more time than the configuration itself. A partner is useful when you need a fixed scope, an independent review or capacity during cutover.

What do we need to provide to a partner before the work starts?

Plan to provide the following before the scope is agreed:

  • An inventory of each legacy application, its hostnames, paths and current login method
  • A named owner for each application who can confirm which headers it reads and how it maps a user to an account
  • Access to a test environment that mirrors production routing, including the reverse proxy and DNS names
  • Your change window rules, rollback expectations and who approves cutover

Without app owners and a test environment, header behavior is guessed rather than verified, which is where most rollbacks start.

Does the open-source edition of authentik include the proxy provider?

The proxy provider is listed among authentik's provider types, and authentik's repository places most of the code under the MIT license (SPDX: MIT). Code in the authentik/enterprise/ directory falls under a separate enterprise license. Confirm the exact licensing of the components you plan to use against the LICENSE file in the repository and the current provider documentation before you finalize the design. The pricing page lists Enterprise-only features such as Google Workspace and Microsoft Entra ID integrations, mTLS, privileged access management and enhanced audit logging, so check that none of those are needed for your header design. Your licensing review should be written down in the scope.

How do authentik upgrades affect the proxy configuration?

Upgrades can change how the outpost and provider behave, so the proxy configuration should be treated as part of the release, not as a separate task. The 2026.5.x and 2026.8.x lines are listed as receiving security fixes, and the project announces security releases at least 24 hours in advance, which gives you a window to test. Keep the outpost version aligned with the server version, test header output in staging after each upgrade, and confirm that additionalHeaders and custom scope mappings still produce the values your applications expect. Ask any partner how upgrades are scheduled and whether they are covered by a retainer or a separate change.

How do we confirm that applications cannot be reached without the proxy?

Confirm it with tests rather than assumptions. The application should only accept connections from the proxy's network path, for example through firewall rules, private networking or a bound interface, and any header the application trusts must be stripped or overwritten at the proxy so clients cannot inject their own values. Run direct requests to the application with forged headers and confirm they are refused, then repeat the test after every configuration change. Record the results as evidence for your security review.

How DeployOpen scopes and delivers header-based access

DeployOpen plans and implements header-based access inside your own infrastructure, under a fixed scope that is agreed in writing before work starts. The scope lists each protected legacy application, the proxy provider and outpost placement, the header set each application expects (for example, which user identifier, email, name or group values it reads), any additionalHeaders on users or groups, and any custom dynamic headers built from scope mappings. Ask for the scope to name the reverse proxy in front of each application, because the proxy is where the trusted headers are set, stripped and checked. Deliverables and timelines follow from that written list, so a quote can be compared line by line against your own team's estimate.

The verification step is what makes the design safe, and it should be a named deliverable rather than an assumption. DeployOpen tests header spoofing: a request that carries forged X- identity headers from outside the proxy must not reach the application with those values intact. It also tests direct-access blocking: the application's own network address, port and internal hostname must refuse connections that did not come through the proxy. Each test is run against every protected application in scope, and the results are recorded as evidence for your security and audit teams. Confirm with the vendor which headers your authentik version sets and how the outpost handles incoming copies of them, since that behavior determines what the tests must prove.

Ongoing work is handled through a retainer rather than a new project each time. A retainer can cover monitoring of the outpost and proxy configuration, support during authentik upgrades (authentik requires planned upgrades, and outposts must match the server version), re-running the spoofing and direct-access checks after application or proxy changes, and adding new applications under the same pattern. The scope of any retainer, its response expectations and its service levels are agreed in writing, so ask for them explicitly. Your team keeps ownership of the applications and the trust boundary, and the written handover documents how each header is produced, where it is enforced and how to test it again.

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.