# Authentik forwarded identity Use this advanced profile only when the browser is authenticated by Authentik but does not obtain a native CWA session that `/ajax/emailstat` can validate. If CWA does create its own session after OIDC/login, keep the simpler and safer `BT_AUTH_PROFILE=cwa-session` profile. This profile does not disable authentication and does not put an API key or shared translator token in the browser. Authentik is the identity authority at one dedicated reverse-proxy route; the translation API trusts only the exact network peer configured by the operator. ```text browser + Authentik Cookie | v identity-aware edge (Nginx / Traefik / Caddy) / -> cwa-translate-proxy -> stock CWA /bt-api/* -> Authentik outpost authentication overwrite X-authentik-uid remove Cookie and alternate identity headers -> cwa-translate-api (no host port) ``` The injection proxy is not an identity authority. Its normal upstream path strips browser-supplied Authentik and legacy login headers before CWA. Only the separate `/bt-api/` edge route generated by `btctl` may assert the subject. ## Preconditions - Authentik and the selected reverse proxy already protect the public CWA origin and share one existing Docker network. - Reserve a stable address for the edge container on that network. Configure that one IPv4 address as `/32` or that one IPv6 address as `/128`; a subnet, hostname, and multiple speculative peers are rejected. - Use the latest patch of an Authentik branch that is still listed in the [official security policy](https://docs.goauthentik.io/security/policy/). The current validator accepts the supported release-time floors `2026.2.5+` and `2026.5.4+`; it rejects older and unknown branches. This replaces the unsafe assumption that excluding only [CVE-2026-25748](https://docs.goauthentik.io/security/cves/CVE-2026-25748/) makes an identity authority maintained. Recheck the policy before install because later Authentik patches can contain additional security fixes. - The outpost must be reachable from the edge through an exact HTTP(S) origin. - The API and injection proxy must have no host port in this topology. Authentik's official integration references describe the expected proxy contract for [Nginx](https://docs.goauthentik.io/add-secure-apps/providers/proxy/server_nginx), [Traefik](https://docs.goauthentik.io/add-secure-apps/providers/proxy/server_traefik/), and [Caddy](https://docs.goauthentik.io/add-secure-apps/providers/proxy/server_caddy/). The generated fragment is intentionally limited to CWA Translate's API route; keep the rest of the official Authentik host/outpost configuration in place. ## Configure Start with the normal private install environment and change these fields: ```dotenv BT_INGRESS_MODE=docker-edge BT_PROXY_PORT= BT_EDGE_NETWORK=authentik_backend BT_AUTH_PROFILE=authentik-forwarded BT_IDENTITY_PROXY_IP=172.30.50.9/32 BT_AUTHENTIK_VERSION=2026.5.4 BT_AUTHENTIK_OUTPOST_URL=http://authentik-outpost:9000 BT_REVERSE_PROXY=nginx ``` `BT_REVERSE_PROXY` must be exactly `nginx`, `traefik`, or `caddy`. Obtain the real edge address from its Docker network inspection and confirm it is stable; do not use the Authentik outpost address or the translator proxy address. `BT_PUBLIC_ORIGIN` remains the exact HTTPS reader origin. The current runtime uses only a non-empty `X-authentik-uid` subject. Authentik groups or roles are deliberately not authorization input in this release. ## Plan, generate, and install Validate the complete topology without mutation and inspect the generated edge fragment before installing: ```bash ./btctl plan --env /absolute/private/path/cwa-translate.env ./btctl auth-snippet --env /absolute/private/path/cwa-translate.env ``` The fragment must perform this order: 1. Remove any client-supplied `X-authentik-uid`, `X-BT-Subject`, and `X-BT-Roles` values. 2. Ask the configured Authentik outpost to authenticate the original request, including its browser `Cookie`. 3. Copy the outpost's authenticated `X-authentik-uid` response, replacing any earlier value. 4. Remove `Cookie` and alternate identity headers before proxying to the API. 5. Route directly to the private API container; never expose its port on the host and never send this identity through the injection proxy. Install the two managed roles: ```bash ./btctl install --env /absolute/private/path/cwa-translate.env --yes ``` Installation writes the reviewed fragment under `BT_STATE_DIR` as `authentik-edge.nginx.conf`, `authentik-edge.traefik.yml`, or `authentik-edge.caddy`. Merge that fragment into the existing HTTPS virtual host/dynamic configuration and reload the edge only after its own config check passes: - Nginx: paste inside the existing HTTPS `server` block. Keep the standard Authentik sign-in and outpost locations used by the rest of the host. The fragment references `@goauthentik_proxy_signin` and forwards Authentik's refreshed `Set-Cookie`, matching that standard flow. - Traefik: merge the generated routers, middleware, and service with the existing entrypoint, TLS, certificate, and outpost configuration. Do not replace the whole dynamic file blindly. - Caddy: paste the generated handler inside the existing site block and keep the rest of the Authentik routing intact. Finally run the read-only local verifier: ```bash ./btctl doctor --env /absolute/private/path/cwa-translate.env ``` ## Acceptance checklist - `doctor` reports every local ownership, auth, network, port, and artifact check as `ok`. - An unauthenticated private/incognito request to the public `/bt-api/health` route is rejected by the edge or sent to Authentik login; it never reaches a useful protected API response. - A normal authenticated browser can open CWA through `BT_PUBLIC_ORIGIN`, load the translator toolbar, and complete a translation. - Browser DevTools shows the Authentik cookie going only to the edge request. The edge-to-API request contains one overwritten `X-authentik-uid` and no `Cookie`, `X-BT-Subject`, or `X-BT-Roles` value. - A forged `X-authentik-uid` from an unauthenticated client is ignored/replaced. - The API has no published host port. A request from any peer other than the exact `BT_IDENTITY_PROXY_IP` fails authentication. ## Fail-closed recovery A `401` after recreating the edge commonly means its Docker address changed. Compare the live edge address with `BT_IDENTITY_PROXY_IP`; restore the reserved address or perform a controlled managed reconfiguration. For reconfiguration, keep the old environment long enough to run its matching `btctl uninstall`, then edit the exact peer, run `plan`, `install`, and `doctor`; translation data and the archived uninstall evidence are preserved. Never broaden the trusted CIDR and never bypass the problem by disabling authentication. For other failures, verify the outpost URL and version, run `doctor`, validate the edge's own configuration, and inspect only the relevant edge/API logs. Do not paste cookies, identity headers, or LLM credentials into an issue report.