runs my oauth2-proxy for Azure based auth¶
secrets
i make my secrets from my own secret store, which
only fits my setup. the docker secret create command here is plain
swarm: use it, or however you normally make secrets.
Description¶
oauth2-proxy puts an entra ID sign-in, with MFA, in front of web sites that
have no login of their own. traefik asks it about every request
to a name marked oauth: a signed-in browser goes on to the site, and anyone
else goes to entra first. one sign-in, on auth.mydomain.com, covers every
name.
State Considerations for SWARM¶
- none. it keeps no files. a sign-in lives in an encrypted cookie in the browser
- the client secret is a swarm secret, which oauth2-proxy reads through
OAUTH2_PROXY_CLIENT_SECRET_FILE, see secrets. the client ID and the cookie secret are portainer stack variables
Network Considerations¶
- it publishes 4180 on the ingress mesh, and traefik reaches it on 4180 at the VIP, the same way it reaches every other app
auth.mydomain.comis its own name, served by traefik on the lan and outside, with no sign-in in front of it. entra sends every browser back there after signing in, so the name needs a record in the internal DNS and in cloudflare- the cookie is set on
.mydomain.com, so a sign-in that started on one name covers the others
Placement Considerations¶
one replica, anywhere on the swarm.
compose.yml, 47 lines, 1 note
each in the code opens a note on that line. download compose.yml
- put your entra directory (tenant) id in place of
<tenant-id>inOAUTH2_PROXY_OIDC_ISSUER_URL, the last variable.${OAUTH2_PROXY_COOKIE_SECRET}and${OAUTH2_PROXY_CLIENT_ID}are portainer stack variables, filled in when the stack deploys.
signing in with entra¶
users sign in through oauth2-proxy's own app registration in entra.
oauth2-proxy uses the entra-id provider (upstream has deprecated azure).
entra ID lists every app registration.
-
register an app in entra (app registrations → new registration), for this directory only, with a web redirect URI of
https://auth.mydomain.com/oauth2/callback- entra always sends the browser back to this one address, whichever name the sign-in started on
-
create a client secret, and store it as a docker secret:
- paste the secret's value (not its ID), then press Ctrl-D
-
set the portainer stack variables:
OAUTH2_PROXY_CLIENT_IDto the app's client ID, andOAUTH2_PROXY_COOKIE_SECRETto 32 random bytes, base64-encoded: -
on the app's enterprise application, turn on assignment required and assign the people who may sign in
- oauth2-proxy only checks that the email ends in
mydomain.com, so who gets in is decided in entra
- oauth2-proxy only checks that the email ends in
-
require MFA for the app with a conditional access policy
- that's the MFA every name behind oauth relies on
how traefik uses it¶
- traefik asks
/on 4180 about each request. a signed-in browser gets thestatic://202upstream's 202, and traefik lets the request through. anyone else gets oauth2-proxy's redirect to entra, and an API client gets a 401 OAUTH2_PROXY_WHITELIST_DOMAINSis plural. oauth2-proxy reads a setting that takes several values from the plural name only. with the singular, a sign-in lands onauth.mydomain.cominstead of the page it started from- oauth2-proxy exits at startup without
OAUTH2_PROXY_OIDC_ISSUER_URL
checking it¶
sign in, and see who you're signed in as:
after entra, the page shows your email. /oauth2/userinfo on its own only
answers 401 when you're signed out: sign_in starts the sign-in, and rd is
where it lands afterwards.
This page started as a gist: the original, with its comments