Merge 6ec7815a21 into 65037b086c
This commit is contained in:
commit
652891fef5
|
|
@ -19,7 +19,7 @@ Modern, actively maintained Kubernetes web UI with OAuth2 Proxy integration exam
|
|||
### Architecture
|
||||
|
||||
```
|
||||
User → Ingress → OAuth2 Proxy → Authentication Provider (e.g., Azure Entra ID)
|
||||
User → Ingress → OAuth2 Proxy → Authentication Provider (e.g., Microsoft Entra ID)
|
||||
↓
|
||||
Headlamp
|
||||
```
|
||||
|
|
@ -28,7 +28,7 @@ User → Ingress → OAuth2 Proxy → Authentication Provider (e.g., Azure Entra
|
|||
|
||||
- Kubernetes cluster (e.g., AKS, EKS, GKE, or self-hosted)
|
||||
- Headlamp installed in the cluster
|
||||
- OAuth2 provider configured (Azure Entra ID, Google, GitHub, etc.)
|
||||
- OAuth2 provider configured (Microsoft Entra ID, Google, GitHub, etc.)
|
||||
- Ingress controller (Nginx, Traefik, etc.)
|
||||
|
||||
### Configuration Overview
|
||||
|
|
@ -63,18 +63,18 @@ extraArgs:
|
|||
email-domain: "*" # Or restrict to your organization
|
||||
```
|
||||
|
||||
### Example with Azure Entra ID on AKS
|
||||
### Example with Microsoft Entra ID on AKS
|
||||
|
||||
For detailed instructions on deploying Headlamp with OAuth2 Proxy on Azure Kubernetes Service using Azure Entra ID, see the official Headlamp documentation:
|
||||
For detailed instructions on deploying Headlamp with OAuth2 Proxy on Azure Kubernetes Service using Microsoft Entra ID, see the official Headlamp documentation:
|
||||
|
||||
https://headlamp.dev/docs/latest/installation/in-cluster/aks-cluster-oauth/
|
||||
|
||||
Key steps include:
|
||||
|
||||
1. **Set up AKS with OIDC**: Enable Microsoft Entra ID authentication with Kubernetes RBAC
|
||||
2. **Create Azure App Registration**: Configure redirect URI and create client secret
|
||||
2. **Create Microsoft Entra ID app registration**: Configure redirect URI and create client secret
|
||||
3. **Deploy Headlamp**: Install Headlamp via Helm in your cluster
|
||||
4. **Deploy OAuth2 Proxy**: Configure OAuth2 Proxy with Entra ID provider settings and upstream pointing to Headlamp
|
||||
4. **Deploy OAuth2 Proxy**: Configure OAuth2 Proxy with Microsoft Entra ID provider settings and upstream pointing to Headlamp
|
||||
5. **Configure Ingress**: Set up Ingress to route traffic through OAuth2 Proxy to Headlamp
|
||||
6. **Set RBAC Policies**: Apply Kubernetes RBAC bindings based on users or groups
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ OAuth2 Proxy can be integrated with popular reverse proxies and ingress controll
|
|||
|
||||
- [Nginx](nginx.md)
|
||||
- [Traefik](traefik.md)
|
||||
- [caddy](caddy.md)
|
||||
- [Caddy](caddy.md)
|
||||
|
||||
## Kubernetes Web UIs
|
||||
|
||||
|
|
@ -23,7 +23,7 @@ OAuth2 Proxy can also be used to add authentication to Kubernetes web user inter
|
|||
:::tip
|
||||
When integrating with Kubernetes web UIs, make sure to:
|
||||
1. Configure the Ingress to pass the Authorization header with the bearer token
|
||||
2. Increase buffer sizes for large OIDC tokens (especially with Azure Entra ID)
|
||||
2. Increase buffer sizes for large OIDC tokens (especially with Microsoft Entra ID)
|
||||
3. Set up appropriate Kubernetes RBAC permissions for your users or groups
|
||||
:::
|
||||
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ Kubernetes Dashboard has been deprecated and discontinued as of January 2025. Se
|
|||
You may want to consider alternative solutions such as [Headlamp](./headlamp.md).
|
||||
:::
|
||||
|
||||
## Kubernetes Dashboard on AKS with Azure Entra ID
|
||||
## Kubernetes Dashboard on AKS with Microsoft Entra ID
|
||||
|
||||
Integration guide for the deprecated Kubernetes Dashboard, including comprehensive Azure Entra ID configuration on AKS with detailed troubleshooting and RBAC setup.
|
||||
Integration guide for the deprecated Kubernetes Dashboard, including comprehensive Microsoft Entra ID configuration on AKS with detailed troubleshooting and RBAC setup.
|
||||
|
||||
### Architecture
|
||||
|
||||
```
|
||||
User → Nginx Ingress → OAuth2 Proxy → Entra ID
|
||||
User → Nginx Ingress → OAuth2 Proxy → Microsoft Entra ID
|
||||
↓
|
||||
Kubernetes Dashboard
|
||||
```
|
||||
|
|
@ -24,20 +24,21 @@ User → Nginx Ingress → OAuth2 Proxy → Entra ID
|
|||
The integration flow:
|
||||
1. Unauthenticated requests to Dashboard are intercepted by Nginx Ingress
|
||||
2. Nginx redirects to OAuth2 Proxy for authentication
|
||||
3. OAuth2 Proxy redirects to Entra ID login
|
||||
4. After successful authentication, OAuth2 Proxy receives ID token from Entra ID
|
||||
3. OAuth2 Proxy redirects to Microsoft Entra ID login
|
||||
4. After successful authentication, OAuth2 Proxy receives an ID token from Microsoft Entra ID
|
||||
5. OAuth2 Proxy sets Authorization header with the bearer token
|
||||
6. Nginx forwards the request with token to Kubernetes Dashboard
|
||||
7. Dashboard validates the token and grants access based on AKS RBAC configuration
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- AKS cluster with Entra ID integration enabled
|
||||
- AKS cluster with Microsoft Entra ID integration enabled
|
||||
- Kubernetes Dashboard installed (version 7.x or later)
|
||||
- NGINX Ingress Controller installed
|
||||
- Entra ID App Registration configured with:
|
||||
- Microsoft Entra ID app registration configured with:
|
||||
- Redirect URI: `https://your-oauth2-domain.com/oauth2/callback`
|
||||
- API Permissions: `openid`, `email`, `profile`
|
||||
- Requested OIDC scopes: `openid`, `email`, `profile`
|
||||
- Microsoft Graph delegated `User.Read` permission if group overage handling is required
|
||||
- Groups claim enabled (if using group-based RBAC)
|
||||
- Users or groups assigned appropriate Kubernetes RBAC permissions
|
||||
|
||||
|
|
@ -110,7 +111,7 @@ ingress:
|
|||
enabled: true
|
||||
className: nginx
|
||||
hosts:
|
||||
- OAuth2 Proxy.your-domain.com
|
||||
- oauth2-proxy.your-domain.com
|
||||
path: /oauth2
|
||||
pathType: Prefix
|
||||
```
|
||||
|
|
@ -130,8 +131,8 @@ metadata:
|
|||
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
|
||||
|
||||
# OAuth2 Proxy authentication
|
||||
nginx.ingress.kubernetes.io/auth-url: "https://OAuth2 Proxy.your-domain.com/oauth2/auth"
|
||||
nginx.ingress.kubernetes.io/auth-signin: "https://OAuth2 Proxy.your-domain.com/oauth2/start?rd=$scheme://$best_http_host$request_uri"
|
||||
nginx.ingress.kubernetes.io/auth-url: "https://oauth2-proxy.your-domain.com/oauth2/auth"
|
||||
nginx.ingress.kubernetes.io/auth-signin: "https://oauth2-proxy.your-domain.com/oauth2/start?rd=$scheme://$best_http_host$request_uri"
|
||||
|
||||
# Include Authorization header with bearer token
|
||||
nginx.ingress.kubernetes.io/auth-response-headers: "Authorization, X-Auth-Request-User, X-Auth-Request-Email"
|
||||
|
|
@ -161,7 +162,7 @@ spec:
|
|||
|
||||
### RBAC Configuration
|
||||
|
||||
Assign Kubernetes permissions to Entra ID users or groups.
|
||||
Assign Kubernetes permissions to Microsoft Entra ID users or groups.
|
||||
|
||||
**User-based:**
|
||||
```yaml
|
||||
|
|
@ -175,7 +176,7 @@ roleRef:
|
|||
name: cluster-admin
|
||||
subjects:
|
||||
- kind: User
|
||||
name: "user@your-domain.com" # Email from Entra ID token
|
||||
name: "user@your-domain.com" # Email from Microsoft Entra ID token
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
|
|
@ -191,7 +192,7 @@ roleRef:
|
|||
name: cluster-admin
|
||||
subjects:
|
||||
- kind: Group
|
||||
name: "YOUR_ENTRA_GROUP_OBJECT_ID" # Entra ID Group Object ID
|
||||
name: "YOUR_ENTRA_GROUP_OBJECT_ID" # Microsoft Entra ID group object ID
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
```
|
||||
|
||||
|
|
@ -205,7 +206,7 @@ Verify that:
|
|||
1. `injectResponseHeaders` in alphaConfig includes Authorization header with id_token claim
|
||||
2. Dashboard Ingress includes `Authorization` in `auth-response-headers` annotation
|
||||
3. Buffer sizes are sufficient for large tokens (set to 256k as shown above)
|
||||
4. Check OAuth2 Proxy logs for successful token generation: `kubectl logs -n OAuth2 Proxy <pod-name>`
|
||||
4. Check OAuth2 Proxy logs for successful token generation: `kubectl logs -n oauth2-proxy <pod-name>`
|
||||
|
||||
**"Unauthorized" or "Invalid token" errors**
|
||||
|
||||
|
|
@ -213,7 +214,7 @@ Common causes:
|
|||
1. User/group not configured in Kubernetes RBAC
|
||||
- Check: `kubectl get clusterrolebindings | grep <user-email>`
|
||||
2. Token validation failed
|
||||
- Verify AKS Entra ID integration is enabled
|
||||
- Verify AKS Microsoft Entra ID integration is enabled
|
||||
- Check Dashboard logs: `kubectl logs -n kubernetes-dashboard <pod-name>`
|
||||
3. Incorrect OAuth2 Proxy configuration
|
||||
- Ensure `reverse-proxy: true` is set
|
||||
|
|
@ -222,10 +223,10 @@ Common causes:
|
|||
**Groups not included in token**
|
||||
|
||||
To include groups in the token:
|
||||
1. In Entra ID App Registration, go to **Token configuration**
|
||||
1. In the Microsoft Entra ID app registration, go to **Token configuration**
|
||||
2. Add **groups claim** and select security groups
|
||||
3. Or edit the manifest and add: `"groupMembershipClaims": "SecurityGroup"`
|
||||
4. For 200+ groups, ensure scope includes `User.Read` for group overage handling
|
||||
4. For 200+ groups, ensure OAuth2 Proxy requests `User.Read` for group overage handling
|
||||
5. Verify groups appear in token: check OAuth2 Proxy logs
|
||||
|
||||
**Session expires too quickly**
|
||||
|
|
@ -267,20 +268,20 @@ alphaConfig:
|
|||
oidcConfig:
|
||||
issuerURL: https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0
|
||||
# ... other config
|
||||
entraIdConfig:
|
||||
microsoftEntraIDConfig:
|
||||
federatedTokenAuth: true
|
||||
```
|
||||
|
||||
This requires:
|
||||
- AKS with OIDC issuer and Workload Identity enabled
|
||||
- Federated identity credential configured in Entra ID App Registration
|
||||
- Federated identity credential configured in the Microsoft Entra ID app registration
|
||||
- Service account annotated with `azure.workload.identity/client-id`
|
||||
|
||||
For detailed Workload Identity setup instructions, see the [Workload Identity section](../providers/ms_entra_id.md#workload-identity) in the Microsoft Entra ID provider documentation.
|
||||
|
||||
## Integration with Other Providers
|
||||
|
||||
While this guide focuses on Azure Entra ID, Kubernetes Dashboard can be integrated with other OAuth2 providers supported by OAuth2 Proxy. The key requirements remain the same:
|
||||
While this guide focuses on Microsoft Entra ID, Kubernetes Dashboard can be integrated with other OAuth2 providers supported by OAuth2 Proxy. The key requirements remain the same:
|
||||
|
||||
1. **Authorization Header**: Pass the bearer token via the `Authorization` header
|
||||
2. **RBAC Configuration**: Configure Kubernetes RBAC for your authentication provider's users/groups
|
||||
|
|
|
|||
|
|
@ -161,10 +161,10 @@ nginx.ingress.kubernetes.io/auth-signin: "https://<oauth2-proxy-fqdn>/oauth2/sta
|
|||
|
||||
This minimal configuration works for standard authentication flows. Lua/cookie handling is only needed for advanced scenarios (e.g., multi-part cookies, custom session logic). See the official ingress-nginx example: https://kubernetes.github.io/ingress-nginx/examples/auth/oauth-external-auth/.
|
||||
|
||||
It is recommended to use `--session-store-type=redis` when expecting large sessions/OIDC tokens (_e.g._ with MS Azure).
|
||||
It is recommended to use `--session-store-type=redis` when expecting large sessions/OIDC tokens (_e.g._ with Microsoft Entra ID).
|
||||
|
||||
:::tip Kubernetes Dashboard with Azure Entra ID
|
||||
For a complete example of integrating oauth2-proxy with Kubernetes Dashboard on AKS using Azure Entra ID, including RBAC configuration and troubleshooting, see the [Kubernetes Dashboard on AKS](../providers/ms_entra_id.md#kubernetes-dashboard-on-aks) section in the Microsoft Entra ID provider documentation.
|
||||
:::tip Kubernetes Dashboard with Microsoft Entra ID
|
||||
For a complete example of integrating oauth2-proxy with Kubernetes Dashboard on AKS using Microsoft Entra ID, including RBAC configuration and troubleshooting, see the [Kubernetes Dashboard integration guide](./kubernetes-dashboard.md).
|
||||
:::
|
||||
|
||||
You have to substitute *name* with the actual cookie name you configured via --cookie-name parameter. If you don't set a custom cookie name the variable should be "$upstream_cookie__oauth2_proxy_1" instead of "$upstream_cookie_name_1" and the new cookie-name should be "_oauth2_proxy_1=" instead of "name_1=".
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ title: Gitea / Forgejo
|
|||
---
|
||||
|
||||
:::note
|
||||
This is not actually a fully serparate provider. For more details and options please refer to the [GitHub Provider Options](github.md)
|
||||
This is not actually a fully separate provider. For more details and options please refer to the [GitHub Provider Options](github.md)
|
||||
:::
|
||||
|
||||
1. Create a new application: `https://< your gitea host >/user/settings/applications`
|
||||
|
|
|
|||
|
|
@ -3,10 +3,22 @@ id: index
|
|||
title: OAuth Provider Configuration
|
||||
---
|
||||
|
||||
You will need to register an OAuth application with a Provider (Google, GitHub or another provider), and configure it
|
||||
You will need to register an OAuth application with a Provider (Google, GitHub or another provider), and configure it
|
||||
with Redirect URI(s) for the domain you intend to run `oauth2-proxy` on.
|
||||
|
||||
Valid providers are :
|
||||
## Choosing a provider
|
||||
|
||||
For new deployments, prefer the current OIDC-based providers over legacy provider implementations:
|
||||
|
||||
| Identity provider | Recommended provider | Use legacy provider only when |
|
||||
| ----------------- | -------------------- | ----------------------------- |
|
||||
| Keycloak | [`keycloak-oidc`](keycloak_oidc.md) | You already run [`keycloak`](keycloak.md) and cannot migrate yet |
|
||||
| Microsoft Entra ID | [`entra-id`](ms_entra_id.md) | You already run [`azure`](ms_azure_ad.md) and cannot migrate yet |
|
||||
| Other OIDC-compatible providers | [`oidc`](openid_connect.md) | A dedicated provider below covers a feature you need |
|
||||
|
||||
The deprecated providers remain documented for existing installations, but their setup examples should not be copied for new deployments.
|
||||
|
||||
Valid providers are:
|
||||
|
||||
- [ADFS](adfs.md)
|
||||
- [Bitbucket](bitbucket.md)
|
||||
|
|
@ -18,24 +30,24 @@ Valid providers are :
|
|||
- [GitHub](github.md)
|
||||
- [GitLab](gitlab.md)
|
||||
- [Google](google.md) _default_
|
||||
- [Keycloak](keycloak.md) (Deprecated)
|
||||
- [Keycloak OIDC](keycloak_oidc.md)
|
||||
- [Keycloak](keycloak.md) (Deprecated)
|
||||
- [LinkedIn](linkedin.md)
|
||||
- [login.gov](login_gov.md)
|
||||
- [Microsoft Azure](ms_azure_ad.md) (Deprecated)
|
||||
- [Microsoft Entra ID](ms_entra_id.md)
|
||||
- [Microsoft Azure](ms_azure_ad.md) (Deprecated)
|
||||
- [Nextcloud](nextcloud.md)
|
||||
- [OpenID Connect](openid_connect.md)
|
||||
- [SourceHut](sourcehut.md)
|
||||
|
||||
The provider can be selected using the `provider` configuration value, or set in the [`providers` array using AlphaConfig](https://oauth2-proxy.github.io/oauth2-proxy/configuration/alpha-config#providers). However, [**the feature to implement multiple providers is not complete**](https://github.com/oauth2-proxy/oauth2-proxy/issues/926).
|
||||
|
||||
Please note that not all providers support all claims. The `preferred_username` claim is currently only supported by the
|
||||
Please note that not all providers support all claims. The `preferred_username` claim is currently only supported by the
|
||||
OpenID Connect provider.
|
||||
|
||||
## Email Authentication
|
||||
|
||||
To authorize a specific email-domain use `--email-domain=yourcompany.com`. To authorize individual email addresses use
|
||||
To authorize a specific email-domain use `--email-domain=yourcompany.com`. To authorize individual email addresses use
|
||||
`--authenticated-emails-file=/path/to/file` with one email per line. To authorize all email addresses use `--email-domain=*`.
|
||||
|
||||
## Adding a new Provider
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ title: Keycloak (Deprecated)
|
|||
---
|
||||
|
||||
:::note
|
||||
This is the legacy and deprecated provider for Keycloak, use [Keycloak OIDC Auth Provider](keycloak_oidc.md) if possible.
|
||||
This is the legacy and deprecated provider for Keycloak. Use [Keycloak OIDC Auth Provider](keycloak_oidc.md) for new deployments. Keep this provider only for existing installations that cannot migrate yet.
|
||||
:::
|
||||
|
||||
1. Create new client in your Keycloak realm with **Access Type** 'confidential' and **Valid Redirect URIs** 'https://internal.yourcompany.com/oauth2/callback'
|
||||
|
|
|
|||
|
|
@ -3,149 +3,156 @@ id: keycloak_oidc
|
|||
title: Keycloak OIDC
|
||||
---
|
||||
|
||||
Use the Keycloak OIDC provider for new Keycloak deployments. The legacy [`keycloak`](keycloak.md) provider is deprecated and should only be used for existing installations that cannot migrate yet.
|
||||
|
||||
## Config Options
|
||||
|
||||
| Flag | Toml Field | Type | Description | Default |
|
||||
| ---------------- | --------------- | -------------- | ------------------------------------------------------------------------------------------------------------------ | ------- |
|
||||
| `--allowed-role` | `allowed_roles` | string \| list | restrict logins to users with this role (may be given multiple times). Only works with the keycloak-oidc provider. | |
|
||||
| `--allowed-role` | `allowed_roles` | string \| list | Restrict logins to users with this role (may be given multiple times). Only works with the `keycloak-oidc` provider. | |
|
||||
|
||||
## Usage
|
||||
## Quick start
|
||||
|
||||
```
|
||||
--provider=keycloak-oidc
|
||||
--client-id=<your client's id>
|
||||
--client-secret=<your client's secret>
|
||||
--redirect-url=https://internal.yourcompany.com/oauth2/callback
|
||||
--oidc-issuer-url=https://<keycloak host>/realms/<your realm> // For Keycloak versions <17: --oidc-issuer-url=https://<keycloak host>/auth/realms/<your realm>
|
||||
--email-domain=<yourcompany.com> // Validate email domain for users, see option documentation
|
||||
--allowed-role=<realm role name> // Optional, required realm role
|
||||
--allowed-role=<client id>:<client role name> // Optional, required client role
|
||||
--allowed-group=</group name> // Optional, requires group client scope
|
||||
--code-challenge-method=S256 // PKCE
|
||||
Create a confidential OpenID Connect client in the Keycloak realm you want to protect and configure OAuth2 Proxy with the issuer URL for that realm.
|
||||
|
||||
```shell
|
||||
--provider=keycloak-oidc
|
||||
--client-id=<client-id>
|
||||
--client-secret=<client-secret>
|
||||
--redirect-url=https://oauth2-proxy.example.com/oauth2/callback
|
||||
--oidc-issuer-url=https://<keycloak-host>/realms/<realm>
|
||||
--email-domain=example.com
|
||||
--code-challenge-method=S256
|
||||
```
|
||||
|
||||
:::note
|
||||
Keycloak has updated its admin console and as of version 19.0.0, the new admin console is enabled by default. The
|
||||
legacy admin console has been announced for removal with the release of version 21.0.0.
|
||||
For Keycloak versions earlier than 17, include the legacy `/auth` path in the issuer URL:
|
||||
|
||||
```shell
|
||||
--oidc-issuer-url=https://<keycloak-host>/auth/realms/<realm>
|
||||
```
|
||||
|
||||
Optional authorization examples:
|
||||
|
||||
```shell
|
||||
--allowed-role=<realm-role-name>
|
||||
--allowed-role=<client-id>:<client-role-name>
|
||||
--allowed-group=/engineering/platform
|
||||
```
|
||||
|
||||
:::tip
|
||||
If Keycloak is behind a reverse proxy, make sure Keycloak's configured hostname and proxy headers produce the same issuer URL that OAuth2 Proxy uses in `--oidc-issuer-url`. Issuer mismatches commonly happen when Keycloak advertises an internal host, the wrong scheme, or the wrong context path in its OIDC discovery document.
|
||||
:::
|
||||
|
||||
**Keycloak legacy admin console**
|
||||
## Keycloak client setup
|
||||
|
||||
1. Create new client in your Keycloak realm with **Access Type** 'confidential', **Client protocol** 'openid-connect'
|
||||
and **Valid Redirect URIs** 'https://internal.yourcompany.com/oauth2/callback'
|
||||
2. Take note of the Secret in the credential tab of the client
|
||||
3. Create a mapper with **Mapper Type** 'Group Membership' and **Token Claim Name** 'groups'.
|
||||
4. Create a mapper with **Mapper Type** 'Audience' and **Included Client Audience** and **Included Custom Audience** set
|
||||
to your client name.
|
||||
In the Keycloak admin console:
|
||||
|
||||
**Keycloak new admin console (default as of v19.0.0)**
|
||||
1. Go to **Clients** -> **Create client**.
|
||||
2. Set **Client type** to **OpenID Connect**.
|
||||
3. Set **Client ID** to the value you will use as `--client-id`.
|
||||
4. Enable **Client authentication**.
|
||||
5. Enable **Standard flow**.
|
||||
6. Disable **Direct access grants** unless another integration requires them.
|
||||
7. Add the OAuth2 Proxy callback as a valid redirect URI, for example `https://oauth2-proxy.example.com/oauth2/callback`.
|
||||
8. Save the client and copy the client secret from the **Credentials** tab.
|
||||
|
||||
The following example shows how to create a simple OIDC client using the new Keycloak admin2 console. However, for best
|
||||
practices, it is recommended to consult the Keycloak documentation.
|
||||
### Audience mapper
|
||||
|
||||
The OIDC client must be configured with an _audience mapper_ to include the client's name in the `aud` claim of the JWT token.
|
||||
The `aud` claim specifies the intended recipient of the token, and OAuth2 Proxy expects a match against the values of
|
||||
either `--client-id` or `--oidc-extra-audience`.
|
||||
OAuth2 Proxy validates the token audience. Configure Keycloak to include the OAuth2 Proxy client ID in the token audience:
|
||||
|
||||
_In Keycloak, claims are added to JWT tokens through the use of mappers at either the realm level using "client scopes" or
|
||||
through "dedicated" client mappers._
|
||||
1. Go to **Clients** -> `<client-id>` -> **Client scopes**.
|
||||
2. Open `<client-id>-dedicated`.
|
||||
3. Click **Configure a new mapper** and choose **Audience**.
|
||||
4. Set **Name** to `aud-mapper-<client-id>`.
|
||||
5. Set **Included Client Audience** to `<client-id>`.
|
||||
6. Enable **Add to ID token**.
|
||||
7. Enable **Add to access token**.
|
||||
8. Save the mapper.
|
||||
|
||||
**Creating the client**
|
||||
If your upstream services require additional audiences, add them deliberately. Keep the `aud` claim limited to intended token recipients.
|
||||
|
||||
1. Create a new OIDC client in your Keycloak realm by navigating to:
|
||||
**Clients** -> **Create client**
|
||||
* **Client Type** 'OpenID Connect'
|
||||
* **Client ID** `<your client's id>`, please complete the remaining fields as appropriate and click **Next**.
|
||||
* **Client authentication** 'On'
|
||||
* **Authentication flow**
|
||||
* **Standard flow** 'selected'
|
||||
* **Direct access grants** 'deselect'
|
||||
* _Save the configuration._
|
||||
* **Settings / Access settings**:
|
||||
* **Valid redirect URIs** `https://internal.yourcompany.com/oauth2/callback`
|
||||
* _Save the configuration._
|
||||
* Under the **Credentials** tab you will now be able to locate `<your client's secret>`.
|
||||
2. Configure a dedicated *audience mapper* for your client by navigating to **Clients** -> **\<your client's id\>** -> **Client scopes**.
|
||||
* Access the dedicated mappers pane by clicking **\<your client's id\>-dedicated**, located under *Assigned client scope*.
|
||||
_(It should have a description of "Dedicated scope and mappers for this client")_
|
||||
* Click **Configure a new mapper** and select **Audience**
|
||||
* **Name** 'aud-mapper-\<your client's id\>'
|
||||
* **Included Client Audience** select `<your client's id>` from the dropdown.
|
||||
* _OAuth2 proxy can be set up to pass both the access and ID JWT tokens to your upstream services.
|
||||
If you require additional audience entries, you can use the **Included Custom Audience** field in addition
|
||||
to the "Included Client Audience" dropdown. Note that the "aud" claim of a JWT token should be limited and
|
||||
only specify its intended recipients._
|
||||
* **Add to ID token** 'On'
|
||||
* **Add to access token** 'On' - [#1916](https://github.com/oauth2-proxy/oauth2-proxy/pull/1916)
|
||||
* _Save the configuration._
|
||||
* Any subsequent dedicated client mappers can be defined by clicking **Dedicated scopes** -> **Add mapper** ->
|
||||
**By configuration** -> *Select mapper*
|
||||
### Test user
|
||||
|
||||
You should now be able to create a test user in Keycloak and get access to the OAuth2 Proxy instance, make sure to set
|
||||
an email address matching `<yourcompany.com>` and select _Email verified_.
|
||||
Create or update a test user and ensure:
|
||||
|
||||
**Authorization**
|
||||
- the user has an email address matching your `--email-domain` setting,
|
||||
- the email is marked as verified, unless you intentionally configure OAuth2 Proxy to allow unverified email addresses,
|
||||
- any required roles or groups are assigned to the user.
|
||||
|
||||
_OAuth2 Proxy will perform authorization by requiring a valid user, this authorization can be extended to take into
|
||||
account a user's membership in Keycloak `groups`, `realm roles`, and `client roles` using the keycloak-oidc provider options
|
||||
`--allowed-role` or `--allowed-group`_
|
||||
## Authorization
|
||||
|
||||
**Roles**
|
||||
OAuth2 Proxy always requires a valid Keycloak login. You can further restrict access with Keycloak groups, realm roles, or client roles.
|
||||
|
||||
_A standard Keycloak installation comes with the required mappers for **realm roles** and **client roles** through the
|
||||
pre-defined client scope "roles". This ensures that any roles assigned to a user are included in the `JWT` tokens when
|
||||
using an OIDC client that has the "Full scope allowed" feature activated, the feature is enabled by default._
|
||||
### Roles
|
||||
|
||||
_Creating a realm role_
|
||||
* Navigate to **Realm roles** -> **Create role**
|
||||
* **Role name**, *`<realm role name>`* -> **save**
|
||||
A standard Keycloak installation includes mappers for realm roles and client roles through the predefined `roles` client scope. These roles are included when the client has **Full scope allowed** enabled, which is the Keycloak default.
|
||||
|
||||
_Creating a client role_
|
||||
* Navigate to **Clients** -> `<your client's id>` -> **Roles** -> **Create role**
|
||||
* **Role name**, *`<client role name>`* -> **save**
|
||||
Create roles as needed:
|
||||
|
||||
- Realm role: **Realm roles** -> **Create role**.
|
||||
- Client role: **Clients** -> `<client-id>` -> **Roles** -> **Create role**.
|
||||
|
||||
_Assign a role to a user_
|
||||
Assign roles to a user from **Users** -> `<username>` -> **Role mapping** -> **Assign role**.
|
||||
|
||||
**Users** -> _Username_ -> **Role mapping** -> **Assign role** -> _filter by roles or clients and select_ -> **Assign**.
|
||||
Authorize realm roles with:
|
||||
|
||||
Keycloak "realm roles" can be authorized using the `--allowed-role=<realm role name>` option, while "client roles" can be
|
||||
evaluated using `--allowed-role=<your client's id>:<client role name>`.
|
||||
```shell
|
||||
--allowed-role=<realm-role-name>
|
||||
```
|
||||
|
||||
You may limit the _realm roles_ included in the JWT tokens for any given client by navigating to:
|
||||
**Clients** -> `<your client's id>` -> **Client scopes** -> _\<your client's id\>-dedicated_ -> **Scope**
|
||||
Disabling **Full scope allowed** activates the **Assign role** option, allowing you to select which roles, if assigned
|
||||
to a user, will be included in the user's JWT tokens. This can be useful when a user has many associated roles, and you
|
||||
want to reduce the size and impact of the JWT token.
|
||||
Authorize client roles with:
|
||||
|
||||
```shell
|
||||
--allowed-role=<client-id>:<client-role-name>
|
||||
```
|
||||
|
||||
**Groups**
|
||||
To reduce token size, you can limit which realm roles are included for a client: **Clients** -> `<client-id>` -> **Client scopes** -> `<client-id>-dedicated` -> **Scope**. Disable **Full scope allowed**, then assign only the roles that should be emitted in tokens for this client.
|
||||
|
||||
You may also do authorization on group memberships by using the OAuth2 Proxy option `--allowed-group`.
|
||||
We will only do a brief description of creating the required _client scope_ **groups** and refer you to read the Keycloak
|
||||
documentation.
|
||||
### Groups
|
||||
|
||||
To summarize, the steps required to authorize Keycloak group membership with OAuth2 Proxy are as follows:
|
||||
Authorize group membership with OAuth2 Proxy's standard `--allowed-group` option.
|
||||
|
||||
* Create a new Client Scope with the name **groups** in Keycloak.
|
||||
* Include a mapper of type **Group Membership**.
|
||||
* Set the "Token Claim Name" to **groups** or customize by matching it to the `--oidc-groups-claim` option of OAuth2 Proxy.
|
||||
* If the "Full group path" option is selected, you need to include a "/" separator in the group names defined in the
|
||||
`--allowed-group` option of OAuth2 Proxy. Example: "/groupname" or "/groupname/child_group".
|
||||
To emit Keycloak groups in tokens:
|
||||
|
||||
After creating the _Client Scope_ named _groups_ you will need to attach it to your client.
|
||||
**Clients** -> `<your client's id>` -> **Client scopes** -> **Add client scope** -> Select **groups** and choose Optional
|
||||
and you should now have a client that maps group memberships into the JWT tokens so that Oauth2 Proxy may evaluate them.
|
||||
1. Create a client scope named `groups`.
|
||||
2. Add a mapper of type **Group Membership**.
|
||||
3. Set **Token Claim Name** to `groups`, or set it to another claim name and configure OAuth2 Proxy with `--oidc-groups-claim=<claim-name>`.
|
||||
4. Decide whether to enable **Full group path**.
|
||||
5. Attach the `groups` client scope to your OAuth2 Proxy client.
|
||||
|
||||
Create a group by navigating to **Groups** -> **Create group** and _add_ your test user as a member.
|
||||
If **Full group path** is enabled, include the leading `/` and full path in OAuth2 Proxy:
|
||||
|
||||
The OAuth2 Proxy option `--allowed-group=/groupname` will now allow you to filter on group membership
|
||||
```shell
|
||||
--allowed-group=/groupname
|
||||
--allowed-group=/groupname/child-group
|
||||
```
|
||||
|
||||
Keycloak also has the option of attaching roles to groups, please refer to the Keycloak documentation for more information.
|
||||
If **Full group path** is disabled, use the group name as it appears in the token.
|
||||
|
||||
**Tip**
|
||||
## Verifying token contents
|
||||
|
||||
To check if roles or groups are added to JWT tokens, you can preview a users token in the Keycloak console by following
|
||||
these steps: **Clients** -> `<your client's id>` -> **Client scopes** -> **Evaluate**.
|
||||
Select a _realm user_ and optional _scope parameters_ such as groups, and generate the JSON representation of an access
|
||||
or id token to examine its contents.
|
||||
Use the Keycloak console to preview tokens before debugging OAuth2 Proxy:
|
||||
|
||||
1. Go to **Clients** -> `<client-id>` -> **Client scopes** -> **Evaluate**.
|
||||
2. Select a realm user.
|
||||
3. Generate an ID token or access token.
|
||||
4. Confirm the token contains the expected `aud`, `groups`, `realm_access`, and `resource_access` claims.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Likely cause | Fix |
|
||||
| ------- | ------------ | --- |
|
||||
| `invalid audience` or failed audience validation | The OAuth2 Proxy client ID is not in the token `aud` claim | Add an audience mapper for the OAuth2 Proxy client and include it in the ID token. Also include it in the access token if upstreams use that token. |
|
||||
| `issuer did not match` | `--oidc-issuer-url` does not match Keycloak discovery or token issuer | Use `/realms/<realm>` for Keycloak 17+ and `/auth/realms/<realm>` only for older Keycloak. Fix Keycloak hostname/proxy settings so discovery advertises the public URL. |
|
||||
| `--allowed-role` does not allow the user | The role is missing from the access token | Ensure the `roles` client scope or equivalent mappers are assigned and the user actually has the realm/client role. |
|
||||
| `--allowed-group` does not allow the user | Groups claim is missing, uses another claim name, or group path does not match | Add the groups client scope, configure `--oidc-groups-claim` if needed, and match the full path format used in the token. |
|
||||
| Browser receives very large cookies or NGINX returns header/buffer errors | Tokens contain many groups or roles | Reduce mapped claims or use Redis session storage instead of cookie-only sessions. |
|
||||
|
||||
## Legacy admin console notes
|
||||
|
||||
Older Keycloak versions used the legacy admin console and the pre-17 `/auth` context path. If you still operate those versions:
|
||||
|
||||
1. Create a client with **Access Type** `confidential`, **Client protocol** `openid-connect`, and **Valid Redirect URIs** set to the OAuth2 Proxy callback URL.
|
||||
2. Copy the secret from the client credentials tab.
|
||||
3. Create a **Group Membership** mapper with **Token Claim Name** `groups` if you use group authorization.
|
||||
4. Create an **Audience** mapper with **Included Client Audience** set to your OAuth2 Proxy client ID.
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ title: Azure (Deprecated)
|
|||
---
|
||||
|
||||
:::note
|
||||
This is the legacy and deprecated provider for Azure, use [Microsoft Entra ID](ms_entra_id.md) if possible.
|
||||
This is the legacy and deprecated provider for Azure. Use [Microsoft Entra ID](ms_entra_id.md) for new deployments. Keep this provider only for existing installations that cannot migrate yet.
|
||||
:::
|
||||
|
||||
## Config Options
|
||||
|
|
@ -20,7 +20,7 @@ This is the legacy and deprecated provider for Azure, use [Microsoft Entra ID](m
|
|||
**App registrations** and then click on **New registration**.
|
||||
2. Pick a name, check the supported account type(single-tenant, multi-tenant, etc). In the **Redirect URI** section create a new
|
||||
**Web** platform entry for each app that you want to protect by the oauth2 proxy(e.g.
|
||||
https://internal.yourcompanycom/oauth2/callback). Click **Register**.
|
||||
https://internal.yourcompany.com/oauth2/callback). Click **Register**.
|
||||
3. Next we need to add group read permissions for the app registration, on the **API Permissions** page of the app, click on
|
||||
**Add a permission**, select **Microsoft Graph**, then select **Application permissions**, then click on **Group** and select
|
||||
**Group.Read.All**. Hit **Add permissions** and then on **Grant admin consent** (you might need an admin to do this).
|
||||
|
|
|
|||
|
|
@ -3,199 +3,290 @@ id: ms_entra_id
|
|||
title: Microsoft Entra ID
|
||||
---
|
||||
|
||||
Provider for Microsoft Entra ID. Fully compliant with OIDC, with support for group overage and multi-tenant apps.
|
||||
Provider for Microsoft Entra ID. It uses the Microsoft identity platform OIDC endpoints and adds OAuth2 Proxy support for Entra-specific features such as group overage, multi-tenant allow-listing, and Workload Identity client authentication.
|
||||
|
||||
Use this provider for new Microsoft Entra ID deployments. The legacy [`azure`](ms_azure_ad.md) provider is deprecated and should only be used for existing installations that cannot migrate yet.
|
||||
|
||||
## Choosing the right configuration
|
||||
|
||||
| Scenario | Recommended configuration |
|
||||
| -------- | ------------------------- |
|
||||
| Single tenant, no group authorization | `provider="entra-id"` or the generic [`oidc`](openid_connect.md) provider with tenant-specific issuer |
|
||||
| Single tenant, group authorization with up to 200 groups in the token | `provider="entra-id"`, enable groups claim in the app registration, use `allowed_groups` with Entra group object IDs |
|
||||
| Users may have more than 200 groups | `provider="entra-id"`, enable groups claim, request Microsoft Graph delegated `User.Read`, and grant consent so OAuth2 Proxy can resolve group overage through Microsoft Graph |
|
||||
| Multi-tenant application | `provider="entra-id"`, use the `common` issuer, set `insecure_oidc_skip_issuer_verification=true`, and restrict tenants with `entra_id_allowed_tenants` |
|
||||
| AKS or Kubernetes without client secrets | `provider="entra-id"` with `entra_id_federated_token_auth=true` and Azure Workload Identity |
|
||||
|
||||
## Config Options
|
||||
|
||||
The provider is OIDC-compliant, so all the OIDC parameters are honored. Additional provider-specific configuration parameters are:
|
||||
|
||||
| Flag | Toml Field | Type | Description | Default |
|
||||
| --------------------------- | -------------------------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `--entra-id-allowed-tenant` | `entra_id_allowed_tenants` | string \| list | List of allowed tenants. In case of multi-tenant apps, incoming tokens are issued by different issuers and OIDC issuer verification needs to be disabled. When not specified, all tenants are allowed. Redundant for single-tenant apps (regular ID token validation matches the issuer). | |
|
||||
| `--entra-id-federated-token-auth` | `entra_id_federated_token_auth` | boolean | Enable oAuth2 client authentication with federated token projected by Entra Workload Identity plugin, instead of client secret. | false |
|
||||
| Flag | Toml Field | Type | Description | Default |
|
||||
| ---- | ---------- | ---- | ----------- | ------- |
|
||||
| `--entra-id-allowed-tenant` | `entra_id_allowed_tenants` | string \| list | List of allowed tenant IDs for multi-tenant applications. When not specified, all tenants that pass token validation are allowed. Redundant for single-tenant apps because regular ID token validation already matches the tenant-specific issuer. | |
|
||||
| `--entra-id-federated-token-auth` | `entra_id_federated_token_auth` | boolean | Enable OAuth2 client authentication with a federated token projected by Azure Workload Identity instead of a client secret. | false |
|
||||
|
||||
## Configure App registration
|
||||
To begin, create an App registration, set a redirect URI, and generate a secret. All account types are supported, including single-tenant, multi-tenant, multi-tenant with Microsoft accounts, and Microsoft accounts only.
|
||||
## Configure an app registration
|
||||
|
||||
Create an app registration in Microsoft Entra ID, set an OAuth2 Proxy callback URL, and choose either a client secret or federated credential for client authentication.
|
||||
|
||||
### Microsoft Entra admin center
|
||||
|
||||
1. Open the [Microsoft Entra admin center](https://entra.microsoft.com).
|
||||
2. Go to **Identity** -> **Applications** -> **app registrations** -> **New registration**.
|
||||
3. Choose the supported account type for your deployment:
|
||||
- single tenant for one organization,
|
||||
- multi-tenant for multiple organizations,
|
||||
- multi-tenant plus personal Microsoft accounts if you need both Entra tenants and personal accounts.
|
||||
4. Add a **Web** redirect URI for OAuth2 Proxy, for example `https://oauth2-proxy.example.com/oauth2/callback`.
|
||||
5. After registration, copy the **Application (client) ID** and **Directory (tenant) ID**.
|
||||
6. For secret-based auth, go to **Certificates & secrets** -> **Client secrets** and create a secret. Copy the secret value immediately.
|
||||
7. For group authorization, go to **Token configuration** -> **Add groups claim** and include the group types you want in ID tokens.
|
||||
8. For group overage handling, add Microsoft Graph delegated `User.Read` to the app registration and grant consent according to your tenant policy.
|
||||
9. For Workload Identity, configure a federated identity credential instead of creating a client secret. See [Workload Identity](#workload-identity).
|
||||
|
||||
OIDC scopes such as `openid`, `profile`, and `email` are requested by OAuth2 Proxy in the `scope` setting. Microsoft Graph permissions are API permissions on the app registration and may require user or admin consent.
|
||||
|
||||
<details>
|
||||
<summary>See Azure Portal example</summary>
|
||||
<div class="videoBlock">
|
||||
<iframe src="https://www.youtube.com/embed/IUNfxhOzr4E"></iframe>
|
||||
</div>
|
||||
</details>
|
||||
<summary>See Terraform example with client secret</summary>
|
||||
|
||||
<details>
|
||||
<summary>See Terraform example</summary>
|
||||
```
|
||||
resource "azuread_application" "auth" {
|
||||
display_name = "oauth2-proxy"
|
||||
sign_in_audience = "AzureADMyOrg" # Others are also supported
|
||||
```hcl
|
||||
resource "azuread_application" "auth" {
|
||||
display_name = "oauth2-proxy"
|
||||
sign_in_audience = "AzureADMyOrg"
|
||||
|
||||
web {
|
||||
redirect_uris = [
|
||||
"https://podinfo.lakis.tech/oauth2/callback",
|
||||
]
|
||||
}
|
||||
// We don't specify any required API permissions - we allow user consent only
|
||||
}
|
||||
web {
|
||||
redirect_uris = [
|
||||
"https://oauth2-proxy.example.com/oauth2/callback",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "azuread_service_principal" "sp" {
|
||||
client_id = azuread_application.auth.client_id
|
||||
app_role_assignment_required = false
|
||||
}
|
||||
|
||||
resource "azuread_service_principal_password" "pass" {
|
||||
service_principal_id = azuread_service_principal.sp.id
|
||||
}
|
||||
resource "azuread_service_principal" "sp" {
|
||||
client_id = azuread_application.auth.client_id
|
||||
app_role_assignment_required = false
|
||||
}
|
||||
|
||||
resource "azuread_service_principal_password" "pass" {
|
||||
service_principal_id = azuread_service_principal.sp.id
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
### Configure groups
|
||||
If you want to make use of groups, you can configure *groups claim* to be present in ID Tokens issued by the App registration.
|
||||
<details>
|
||||
<summary>See Azure Portal example</summary>
|
||||
<div class="videoBlock">
|
||||
<div class="videoBlock">
|
||||
<iframe src="https://www.youtube.com/embed/QZmP5MKEJis"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
<details>
|
||||
<summary>See Terraform example</summary>
|
||||
## Groups and authorization
|
||||
|
||||
To authorize with `allowed_groups` or pass groups to an upstream application, enable the groups claim in the app registration. Use Entra group **object IDs** in `allowed_groups`; display names are not stable identifiers and are not what Entra emits in the `groups` claim.
|
||||
|
||||
```toml
|
||||
allowed_groups = ["ac51800c-2679-4ecb-8130-636380a3b491"]
|
||||
```
|
||||
resource "azuread_application" "auth" {
|
||||
display_name = "oauth2-proxy"
|
||||
sign_in_audience = "AzureADMyOrg"
|
||||
|
||||
group_membership_claims = [
|
||||
"SecurityGroup"
|
||||
]
|
||||
<details>
|
||||
<summary>See Terraform example with groups claim</summary>
|
||||
|
||||
web {
|
||||
redirect_uris = [
|
||||
"https://podinfo.lakis.tech/oauth2/callback",
|
||||
]
|
||||
}
|
||||
}
|
||||
```hcl
|
||||
resource "azuread_application" "auth" {
|
||||
display_name = "oauth2-proxy"
|
||||
sign_in_audience = "AzureADMyOrg"
|
||||
|
||||
resource "azuread_service_principal" "sp" {
|
||||
client_id = azuread_application.auth.client_id
|
||||
app_role_assignment_required = false
|
||||
}
|
||||
|
||||
resource "azuread_service_principal_password" "pass" {
|
||||
service_principal_id = azuread_service_principal.sp.id
|
||||
}
|
||||
group_membership_claims = [
|
||||
"SecurityGroup"
|
||||
]
|
||||
|
||||
web {
|
||||
redirect_uris = [
|
||||
"https://oauth2-proxy.example.com/oauth2/callback",
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
### Scopes and claims
|
||||
For single-tenant and multi-tenant apps without groups, the only required scope is `openid` (See: [Scopes and permissions](https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#the-openid-scope)).
|
||||
### Group overage
|
||||
|
||||
To make use of groups - for example use `allowed_groups` setting or authorize based on groups inside your service - you need to enable *groups claims* in the App Registration. When enabled, list of groups is present in the issued ID token. No additional scopes are required besides `openid`. This works up to 200 groups.
|
||||
Microsoft Entra ID includes up to 200 groups in a JWT. If the user is a member of more groups, Entra emits an overage indicator instead of the full group list. OAuth2 Proxy detects that indicator and calls Microsoft Graph `/me/transitiveMemberOf` to add the user's groups to the session.
|
||||
|
||||
When user has more than 200 group memberships, OAuth2-Proxy attempts to retrieve the complete list from Microsoft Graph API's [`transitiveMemberOf`](https://learn.microsoft.com/en-us/graph/api/user-list-transitivememberof). Endpoint requires `User.Read` scope (delegated permission). This permission can be by default consented by user during first login. Set scope to `openid User.Read` to request user consent. Without proper scope, user with 200+ groups will authenticate with 0 groups. See: [group overages](https://learn.microsoft.com/en-us/security/zero-trust/develop/configure-tokens-group-claims-app-roles#group-overages).
|
||||
For group overage to work:
|
||||
|
||||
Alternatively to user consent, both `openid` and `User.Read` permissions can be consented by admistrator. Then, user is not asked for consent on the first login, and group overage works with `openid` scope only. Admin consent can also be required for some tenants. It can be granted with [azuread_service_principal_delegated_permission_grant](https://registry.terraform.io/providers/hashicorp/azuread/latest/docs/resources/service_principal_delegated_permission_grant) terraform resource.
|
||||
- add Microsoft Graph delegated `User.Read` to the app registration,
|
||||
- include `User.Read` in OAuth2 Proxy's `scope` when it needs to be requested during sign-in,
|
||||
- ensure the user or an administrator can consent to that permission.
|
||||
|
||||
For personal microsoft accounts, required scope is `openid profile email`.
|
||||
Without the required permission and consent, users with group overage may authenticate successfully but have no groups in the OAuth2 Proxy session, causing `allowed_groups` checks to fail.
|
||||
|
||||
See: [Overview of permissions and consent in the Microsoft identity platform](https://learn.microsoft.com/en-us/entra/identity-platform/permissions-consent-overview).
|
||||
Personal Microsoft accounts do not support the same Entra group model. Use group authorization and group overage handling for work or school accounts in Entra tenants.
|
||||
|
||||
See:
|
||||
|
||||
- [Microsoft identity platform group overage claims](https://learn.microsoft.com/en-us/security/zero-trust/develop/configure-tokens-group-claims-app-roles#group-overages)
|
||||
- [Microsoft Graph transitiveMemberOf](https://learn.microsoft.com/en-us/graph/api/user-list-transitivememberof)
|
||||
- [Overview of permissions and consent](https://learn.microsoft.com/en-us/entra/identity-platform/permissions-consent-overview)
|
||||
|
||||
## Scopes and claims
|
||||
|
||||
For single-tenant and multi-tenant apps without groups, the only required OIDC scope is `openid` (see [Scopes and permissions](https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#the-openid-scope)).
|
||||
|
||||
Common scope choices:
|
||||
|
||||
| Scenario | Scope |
|
||||
| -------- | ----- |
|
||||
| Work or school account, no groups | `openid` |
|
||||
| Work or school account with group overage support | `openid User.Read` |
|
||||
| Personal Microsoft accounts | `openid profile email` |
|
||||
| Multi-tenant including personal accounts and group overage for Entra tenants | `openid profile email User.Read` |
|
||||
|
||||
Use `oidc_email_claim`, `oidc_groups_claim`, and `oidc_audience_claims` only when you need to override OAuth2 Proxy defaults. For Kubernetes RBAC and other systems that need stable user identifiers, consider using the Entra `oid` claim via `userIDClaim` in AlphaConfig.
|
||||
|
||||
## Multi-tenant apps
|
||||
|
||||
To authenticate users from multiple tenants, including personal Microsoft accounts, use the common issuer and disable strict issuer verification:
|
||||
|
||||
### Multi-tenant apps
|
||||
To authenticate apps from multiple tenants (including personal Microsoft accounts), set the common OIDC issuer url and disable verification:
|
||||
```toml
|
||||
oidc_issuer_url=https://login.microsoftonline.com/common/v2.0
|
||||
insecure_oidc_skip_issuer_verification=true
|
||||
provider = "entra-id"
|
||||
oidc_issuer_url = "https://login.microsoftonline.com/common/v2.0"
|
||||
insecure_oidc_skip_issuer_verification = true
|
||||
```
|
||||
`insecure_oidc_skip_issuer_verification` setting is required to disable following checks:
|
||||
* Startup check for matching issuer URL returned from [discovery document](https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration) with `oidc_issuer_url` setting. Required, as document's `issuer` field doesn't equal to `https://login.microsoftonline.com/common/v2.0`. See [OIDC Discovery 4.3](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderConfigurationValidation).
|
||||
* Matching ID token's `issuer` claim with `oidc_issuer_url` setting during ID token validation. Required to support tokens issued by different tenants. See [OIDC Core 3.1.3.7](https://openid.net/specs/openid-connect-core-1_0.html#IDTokenValidation).
|
||||
|
||||
To provide additional security, Entra ID provider performs check on the ID token's `issuer` claim to match the `https://login.microsoftonline.com/{tenant-id}/v2.0` template.
|
||||
`insecure_oidc_skip_issuer_verification` is required because tokens are issued by tenant-specific issuers such as `https://login.microsoftonline.com/<tenant-id>/v2.0`, while the configured discovery URL is `common`.
|
||||
|
||||
### Workload Identity
|
||||
Provider supports authentication with federated token, without need of using client secret. Following conditions have to be met:
|
||||
:::warning
|
||||
When issuer verification is disabled for a multi-tenant app, set `entra_id_allowed_tenants` unless you intentionally allow users from any tenant. Treat the allowed tenant list as the trust boundary for multi-tenant deployments.
|
||||
:::
|
||||
|
||||
OAuth2 Proxy still validates that the token issuer follows the expected Microsoft Entra issuer format. `entra_id_allowed_tenants` then restricts which tenant IDs are accepted. Use tenant IDs rather than tenant domains. The tenant ID for personal Microsoft accounts is `9188040d-6c67-4c5b-b112-36a304b66dad`.
|
||||
|
||||
```toml
|
||||
entra_id_allowed_tenants = [
|
||||
"9188040d-6c67-4c5b-b112-36a304b66dad",
|
||||
"<your-tenant-id>"
|
||||
]
|
||||
```
|
||||
|
||||
## Workload Identity
|
||||
|
||||
OAuth2 Proxy can authenticate to Entra ID with a federated token instead of a client secret. This is commonly used with [Azure Workload Identity](https://azure.github.io/azure-workload-identity/docs/) on AKS or other Kubernetes clusters.
|
||||
|
||||
Checklist:
|
||||
|
||||
- The cluster has a public OIDC issuer URL.
|
||||
- The Azure Workload Identity admission webhook is installed or enabled.
|
||||
- The app registration has a federated identity credential whose subject exactly matches the OAuth2 Proxy service account: `system:serviceaccount:<namespace>:<service-account>`.
|
||||
- The OAuth2 Proxy Kubernetes service account is annotated with `azure.workload.identity/client-id: <app-registration-client-id>`.
|
||||
- On AKS, also set `azure.workload.identity/tenant-id: <tenant-id>` when your setup requires it.
|
||||
- The OAuth2 Proxy pod is labeled with `azure.workload.identity/use: "true"`.
|
||||
- OAuth2 Proxy is configured with `entra_id_federated_token_auth=true`.
|
||||
- `client_secret` is omitted.
|
||||
- The admission webhook injects `AZURE_FEDERATED_TOKEN_FILE`; OAuth2 Proxy validates this variable at startup when federated token auth is enabled.
|
||||
|
||||
* Cluster has public OIDC provider URL. For major cloud providers, it can be enabled with a single flag, for example for [Azure Kubernetes Service deployed with Terraform](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/kubernetes_cluster), it's `oidc_issuer_enabled`.
|
||||
* Workload Identity admission webhook is deployed on the cluster. For AKS, it can be enabled with a flag (`workload_identity_enabled` in Terraform resource), for clusters outside of Azure, it can be installed from [helm chart](https://github.com/Azure/azure-workload-identity).
|
||||
* Appropriate federated credential is added to application registration.
|
||||
<details>
|
||||
<summary>See federated credential terraform example</summary>
|
||||
```
|
||||
resource "azuread_application_federated_identity_credential" "fedcred" {
|
||||
application_id = azuread_application.application.id # ID of your application
|
||||
display_name = "federation-cred"
|
||||
description = "Workload identity for oauth2-proxy"
|
||||
audiences = ["api://AzureADTokenExchange"] # Fixed value
|
||||
issuer = "https://cluster-oidc-issuer-url..."
|
||||
subject = "system:serviceaccount:oauth2-proxy-namespace-name:oauth2-proxy-sa-name" # set proper NS and SA name
|
||||
}
|
||||
<summary>See federated credential Terraform example</summary>
|
||||
|
||||
```hcl
|
||||
resource "azuread_application_federated_identity_credential" "fedcred" {
|
||||
application_id = azuread_application.auth.id
|
||||
display_name = "oauth2-proxy"
|
||||
description = "Workload identity for oauth2-proxy"
|
||||
audiences = ["api://AzureADTokenExchange"]
|
||||
issuer = "https://cluster-oidc-issuer-url.example.com"
|
||||
subject = "system:serviceaccount:oauth2-proxy:oauth2-proxy"
|
||||
}
|
||||
```
|
||||
</details>
|
||||
|
||||
* Kubernetes service account associated with oauth2-proxy deployment, is annotated with `azure.workload.identity/client-id: <app-registration-client-id>`
|
||||
* oauth2-proxy pod is labeled with `azure.workload.identity/use: "true"`
|
||||
* oauth2-proxy is configured with `entra_id_federated_token_auth` set to `true`.
|
||||
## Example configurations
|
||||
|
||||
`client_secret` setting can be omitted when using federated token authentication.
|
||||
### Single tenant without groups
|
||||
|
||||
See: [Azure Workload Identity documentation](https://azure.github.io/azure-workload-identity/docs/).
|
||||
|
||||
### Example configurations
|
||||
Single-tenant app without groups (*groups claim* not enabled). Consider using generic OIDC provider:
|
||||
```toml
|
||||
provider="entra-id"
|
||||
oidc_issuer_url="https://login.microsoftonline.com/<tenant-id>/v2.0"
|
||||
client_id="<client-id>"
|
||||
client_secret="<client-secret>"
|
||||
scope="openid"
|
||||
provider = "entra-id"
|
||||
oidc_issuer_url = "https://login.microsoftonline.com/<tenant-id>/v2.0"
|
||||
client_id = "<client-id>"
|
||||
client_secret = "<client-secret>"
|
||||
scope = "openid"
|
||||
```
|
||||
|
||||
Single-tenant app with up to 200 groups (*groups claim* enabled). Consider using generic OIDC provider:
|
||||
### Single tenant with groups in the token
|
||||
|
||||
Enable groups claim in the app registration first.
|
||||
|
||||
```toml
|
||||
provider="entra-id"
|
||||
oidc_issuer_url="https://login.microsoftonline.com/<tenant-id>/v2.0"
|
||||
client_id="<client-id>"
|
||||
client_secret="<client-secret>"
|
||||
scope="openid"
|
||||
allowed_groups=["ac51800c-2679-4ecb-8130-636380a3b491"]
|
||||
provider = "entra-id"
|
||||
oidc_issuer_url = "https://login.microsoftonline.com/<tenant-id>/v2.0"
|
||||
client_id = "<client-id>"
|
||||
client_secret = "<client-secret>"
|
||||
scope = "openid"
|
||||
allowed_groups = ["ac51800c-2679-4ecb-8130-636380a3b491"]
|
||||
```
|
||||
|
||||
Single-tenant app with more than 200 groups:
|
||||
### Single tenant with group overage support
|
||||
|
||||
```toml
|
||||
provider="entra-id"
|
||||
oidc_issuer_url="https://login.microsoftonline.com/<tenant-id>/v2.0"
|
||||
client_id="<client-id>"
|
||||
client_secret="<client-secret>"
|
||||
scope="openid User.Read"
|
||||
allowed_groups=["968b4844-d5e7-4e18-a834-59927959369f"]
|
||||
provider = "entra-id"
|
||||
oidc_issuer_url = "https://login.microsoftonline.com/<tenant-id>/v2.0"
|
||||
client_id = "<client-id>"
|
||||
client_secret = "<client-secret>"
|
||||
scope = "openid User.Read"
|
||||
allowed_groups = ["968b4844-d5e7-4e18-a834-59927959369f"]
|
||||
```
|
||||
|
||||
Single-tenant app with more than 200 groups and workload identity enabled:
|
||||
### Single tenant with group overage and Workload Identity
|
||||
|
||||
```toml
|
||||
provider="entra-id"
|
||||
oidc_issuer_url="https://login.microsoftonline.com/<tenant-id>/v2.0"
|
||||
client_id="<client-id>"
|
||||
scope="openid User.Read"
|
||||
allowed_groups=["968b4844-d5e7-4e18-a834-59927959369f"]
|
||||
entra_id_federated_token_auth=true
|
||||
provider = "entra-id"
|
||||
oidc_issuer_url = "https://login.microsoftonline.com/<tenant-id>/v2.0"
|
||||
client_id = "<client-id>"
|
||||
scope = "openid User.Read"
|
||||
allowed_groups = ["968b4844-d5e7-4e18-a834-59927959369f"]
|
||||
entra_id_federated_token_auth = true
|
||||
```
|
||||
|
||||
Multi-tenant app with Microsoft personal accounts & one Entra tenant allowed, with group overage considered:
|
||||
### Multi-tenant with one Entra tenant and personal Microsoft accounts allowed
|
||||
|
||||
```toml
|
||||
provider="entra-id"
|
||||
oidc_issuer_url="https://login.microsoftonline.com/common/v2.0"
|
||||
client_id="<client-id>"
|
||||
client_secret="<client-secret>"
|
||||
insecure_oidc_skip_issuer_verification=true
|
||||
scope="openid profile email User.Read"
|
||||
entra_id_allowed_tenants=["9188040d-6c67-4c5b-b112-36a304b66dad","<my-tenant-id>"] # Allow only <my-tenant-id> and Personal MS Accounts tenant
|
||||
email_domains="*"
|
||||
provider = "entra-id"
|
||||
oidc_issuer_url = "https://login.microsoftonline.com/common/v2.0"
|
||||
client_id = "<client-id>"
|
||||
client_secret = "<client-secret>"
|
||||
insecure_oidc_skip_issuer_verification = true
|
||||
scope = "openid profile email User.Read"
|
||||
entra_id_allowed_tenants = [
|
||||
"9188040d-6c67-4c5b-b112-36a304b66dad",
|
||||
"<your-tenant-id>"
|
||||
]
|
||||
email_domains = ["*"]
|
||||
```
|
||||
|
||||
## Kubernetes Dashboard Integration
|
||||
### AlphaConfig provider example
|
||||
|
||||
For a complete guide on integrating oauth2-proxy with Kubernetes Dashboard on AKS using Azure Entra ID authentication, including detailed configuration examples, RBAC setup, troubleshooting, and Workload Identity setup, see the [Kubernetes Dashboard integration guide](../integrations/kubernetes-dashboard.md).
|
||||
```yaml
|
||||
providers:
|
||||
- id: entra
|
||||
provider: entra-id
|
||||
clientID: <client-id>
|
||||
clientSecret: <client-secret>
|
||||
oidcConfig:
|
||||
issuerURL: https://login.microsoftonline.com/<tenant-id>/v2.0
|
||||
emailClaim: email
|
||||
groupsClaim: groups
|
||||
userIDClaim: oid
|
||||
scope: openid
|
||||
allowedGroups:
|
||||
- ac51800c-2679-4ecb-8130-636380a3b491
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Likely cause | Fix |
|
||||
| ------- | ------------ | --- |
|
||||
| Users from unexpected tenants can sign in | Multi-tenant issuer is configured without `entra_id_allowed_tenants` | Add an allowed tenant list or use a tenant-specific issuer for single-tenant apps. |
|
||||
| Users with many groups fail `allowed_groups` | Group overage occurred but Graph permission or consent is missing | Add Microsoft Graph delegated `User.Read`, include it in `scope` if it must be requested during sign-in, and grant consent as required. |
|
||||
| `allowed_groups` never matches | Display names were used instead of object IDs, or groups claim is not enabled | Enable groups claim and configure `allowed_groups` with Entra group object IDs. |
|
||||
| Cookie or header size errors | ID token contains many groups or claims | Use Redis session storage and limit emitted claims where possible. |
|
||||
| Workload Identity startup validation fails | `AZURE_FEDERATED_TOKEN_FILE` was not injected or is unreadable | Verify service account annotations, pod label, webhook installation, and federated credential subject. |
|
||||
|
||||
## Kubernetes integrations
|
||||
|
||||
For Kubernetes web UI examples with Microsoft Entra ID, see:
|
||||
|
||||
- [Headlamp](../integrations/headlamp.md), the recommended actively maintained Kubernetes UI.
|
||||
- [Kubernetes Dashboard](../integrations/kubernetes-dashboard.md), retained for users of the deprecated Kubernetes Dashboard project.
|
||||
|
|
|
|||
|
|
@ -61,6 +61,42 @@ To configure the OIDC provider for Dex, perform the following steps:
|
|||
|
||||
See also [our local testing environment](https://github.com/oauth2-proxy/oauth2-proxy/blob/master/contrib/local-environment) for a self-contained example using Docker and etcd as storage for Dex.
|
||||
|
||||
#### Amazon Cognito user pools
|
||||
|
||||
Amazon Cognito user pools are OIDC-compatible and can be configured with the generic `oidc` provider.
|
||||
|
||||
Create a Cognito user pool app client for a server-side web application:
|
||||
|
||||
- Enable the authorization code grant.
|
||||
- Configure the OAuth2 Proxy callback URL, for example `https://oauth2-proxy.example.com/oauth2/callback`.
|
||||
- Use a confidential app client with a client secret; OAuth2 Proxy requires `client_secret` or `client_secret_file` for the generic OIDC provider.
|
||||
- Request the scopes your app needs, commonly `openid`, `email`, and `profile`.
|
||||
|
||||
Example configuration:
|
||||
|
||||
```toml
|
||||
provider = "oidc"
|
||||
provider_display_name = "Amazon Cognito"
|
||||
oidc_issuer_url = "https://cognito-idp.<region>.amazonaws.com/<user-pool-id>"
|
||||
redirect_url = "https://oauth2-proxy.example.com/oauth2/callback"
|
||||
client_id = "<app-client-id>"
|
||||
client_secret = "<app-client-secret>"
|
||||
scope = "openid email profile"
|
||||
email_domains = ["*"]
|
||||
```
|
||||
|
||||
##### EKS workload identity and Cognito client secrets
|
||||
|
||||
AWS has workload identity features for Kubernetes, including [IAM roles for service accounts (IRSA)](https://docs.aws.amazon.com/eks/latest/userguide/iam-roles-for-service-accounts.html) and [EKS Pod Identity](https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html). They let a pod obtain AWS IAM credentials for AWS API calls without storing AWS access keys.
|
||||
|
||||
These features are not the same as Microsoft Entra ID Workload Identity client authentication. OAuth2 Proxy's `entra-id` provider can exchange the authorization code at the token endpoint with a projected Kubernetes service account token instead of a client secret. Amazon Cognito user pool app clients do not provide an equivalent OAuth2 token endpoint flow for OAuth2 Proxy to replace `client_secret` with IRSA or EKS Pod Identity credentials.
|
||||
|
||||
For Cognito-backed OAuth2 Proxy deployments on EKS:
|
||||
|
||||
- use `client_secret_file` with a Kubernetes Secret or an external secret sync mechanism if you need secret rotation,
|
||||
- use IRSA or EKS Pod Identity only for separate AWS API access by the pod,
|
||||
- do not expect IRSA or EKS Pod Identity to authenticate OAuth2 Proxy as a Cognito app client.
|
||||
|
||||
#### Okta
|
||||
|
||||
To configure the OIDC provider for Okta, perform the following steps:
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ It can be configured using the following query parameters:
|
|||
### Proxy (/)
|
||||
|
||||
This endpoint returns the upstream response if authenticated.
|
||||
If unauthenticated it returns a 401 Unauthorized. If the authenticatd user
|
||||
If unauthenticated it returns a 401 Unauthorized. If the authenticated user
|
||||
is not in one of the allowed groups, or emails then it returns a 403 forbidden
|
||||
|
||||
It can be configured using the following query parameters:
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ const sidebars = {
|
|||
},
|
||||
items: [
|
||||
"configuration/providers/adfs",
|
||||
"configuration/providers/azure",
|
||||
"configuration/providers/bitbucket",
|
||||
"configuration/providers/cidaas",
|
||||
"configuration/providers/cisco_duo",
|
||||
|
|
@ -56,11 +55,12 @@ const sidebars = {
|
|||
"configuration/providers/github",
|
||||
"configuration/providers/gitlab",
|
||||
"configuration/providers/google",
|
||||
"configuration/providers/keycloak",
|
||||
"configuration/providers/keycloak_oidc",
|
||||
"configuration/providers/keycloak",
|
||||
"configuration/providers/linkedin",
|
||||
"configuration/providers/login_gov",
|
||||
"configuration/providers/ms_entra_id",
|
||||
"configuration/providers/azure",
|
||||
"configuration/providers/nextcloud",
|
||||
"configuration/providers/openid_connect",
|
||||
"configuration/providers/sourcehut"
|
||||
|
|
|
|||
Loading…
Reference in New Issue