dniel / traefik-forward-auth0

A backend for performing forward authentication with Auth0 using the Traefik reverse proxy.
GNU General Public License v3.0
85 stars 16 forks source link

Option to toggle passing AccessToken vs idToken to backend #290

Closed radicand closed 3 years ago

radicand commented 3 years ago

Currently AccessToken is passed as the Authorization header to the backend, but applications like Kubernetes Dashboard will work OOB with an idToken. Is there a way to toggle (on a per-app basis) which JWT is passed to the backend?

radicand commented 3 years ago

Closing this issue, as I've worked out how to add the necessary claims to the accessToken in Auth0. For those that follow and are interested specifically in K8s Dashboard, or making the access token have more claims:

Create a rule similar to the below:

function(user, context, callback) {
  const namespace = 'https://your.namespace/';
  context.accessToken[namespace + 'group'] = user.user_metadata.k8s_group;
  context.accessToken[namespace + 'email'] = user.email;
  callback(null, user, context);
}

This assumes you've also leveraged Auth0 user metadata to set a field called k8s_group.

Next, ensure your kube-apiserver has the right oauth parameters passed to it. In K3s, the config yaml would look like:

# ...
kube-apiserver-arg:
  - "oidc-issuer-url=https://your-tenant.auth0.com/"
  - "oidc-client-id=https://your.auth0.API.clientId"
  - "oidc-username-claim=https://your.namespace/email"
  - "oidc-username-prefix=oidc:"
  - "oidc-groups-claim=https://your.namespace/group"
  - "oidc-groups-prefix=oidc:"

If you have multiple nodes, ensure this is configured the same on all of them.

Finally, create the CRB:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: oidc-cluster-admins
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: oidc:cluster_admin

Assuming your Auth0 user has the user metadata field k8s_group: "cluster_admin" set, and you've otherwise setup the middleware for this in front of K8s Dashboard properly, it should work just fine.

dniel commented 3 years ago

:+1: Thanx for the follow up with advice! I will add it to the documentation pages for others to use.

As the official specification documents, Access token is in the oauth2 + oidc should be used to send to the resource server (in this case the kubernetes dashboard) to authenticate and possibly also authorize, as can be seen by the audience field in the token which points to the resource server that should be the receiving server. The ID Token should not be sent to remote systems, its intended for the client that requested the token, which also can be seen by the audience field in the id token.

Specifications wise its correct to add the fields needed to the access token and send it, instead of adding an option to send the id token. I know many IDPs add features beyond the oauth and oidc specifcations though so maybe in the future a feature like that needs to be added anyways for pragmatic reasons but hopefully its possible to avoid as long as possible.