argo-workflows: Groups are not working with okta sso integration

Summary

We’re running Argo Workflows with SSO and RBAC enabled. We’re using Okta as the OIDC provider.

Our service-account, which pointed to RoleBinding:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: argo-user
  annotations:
    workflows.argoproj.io/rbac-rule: "'admins' in groups"
    workflows.argoproj.io/rbac-rule-precedence: "1"

Our config-map:

data:
  config: |
    sso:
      clientID:
        key: clientID
        name: argo-secret
      clientSecret:
        key: clientSecret
        name: argo-secret
      issuer: https://<out_okta_url>
      name: Okta
      rbac:
        enabled: true
      redirectUrl: https://<our_argo_url>/oauth2/callback
      scopes:
      - groups
      - email

When we try to set a rule for the email email endsWith '@ourdomain.com', rbac works as expected and with groups in doesn’t work. And we have okta.groups.read granted in Okta app.

Expected behaviour that groups rules to work for okta.

Diagnostics

We are using EKS. Argo Workflows v3.0.7.


Message from the maintainers:

Impacted by this bug? Give it a 👍. We prioritise the issues with the most 👍.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 27 (12 by maintainers)

Commits related to this issue

Most upvoted comments

@prein I was able to get it working by setting Groups claim filter to .* in the Okta group settings. image

As usual, I’m pushing for the simplest and most frugal solution.

I think the following is why the groups claim is missing:

https://support.okta.com/help/s/article/Okta-Groups-or-Attribute-Missing-from-Id-Token?language=en_US

Cause

Id token when returned along with access token, is considered Thin Token. Thin id token only carries base claims and some scope dependent claims. Profile attributes (even if profile scope is passed) and groups are skipped (even if groups scope is passed in authorize request). Examples, of when id token and access token are returned together.

  • Implicit flow, where response_type=id_token+token
  • Authorization code flow, where openid scope is passed in authorize request
  • Resource owner password flow, where openid scope is passed in token request

Note: When id token is returned only (without access token), for example in implicit flow where response_type = id_token, the id token returned is considered Fat Token and should contain all profile attributes if profile scope is passed and groups, if groups scope is passed.

Resolution

Since in this case the access token is returned along with id token, the access token can be used to get all user claims (all profile attributes and groups, if profile and groups scopes are passed).

The Access token can be sent as a bearer token in the authorization header of userinfo request i.e. POST ${baseUrl}/oauth2/v1/userinfo, where base url will be https://{yoursubdomain}.okta.com or https://{yoursubdomain}.okta.com

So it seems like an additional request to fmt.Sprintf("%s/oauth2/v1/userinfo", s.baseHRef) would be needed to get the groups claim.

you can always create a free okta developer account to work with the code too: https://developer.okta.com/signup/