Skip to content

Instantly share code, notes, and snippets.

@vavdoshka
Last active February 26, 2024 00:03
Show Gist options
  • Save vavdoshka/f180bc49886728d9f051d9c4db045f9e to your computer and use it in GitHub Desktop.
Save vavdoshka/f180bc49886728d9f051d9c4db045f9e to your computer and use it in GitHub Desktop.
ArgoCD and ArgoWorkflows SSO config with AWS Cognito

ArgoCD and ArgoWorkflows SSO config with AWS Cognito

So you have fantastic ArgoCD or mind-boggling ArgoWorkflows (this guide covers both), and if you want to secure the Authentication with AWS Cognito, let's dive right in.

I found many different sources unveiling some pieces of the required configuration but no resources where one can see the whole picture. I hope this guide will be one of such places. This guide will mean no DEX usage, just rely on Argo's built-in OpenID Connect flow.

Table of contents

UserPool configuration

  • You have a Cognito UserPool created (if not yet, make one right now, stick to the defaults if you do it through AWS Console). Note the Pool Id. We are going to use it later.
  • Create an app client per correspondent Argo application. Create one or two depending on whether you need to have only one ArgoCD or ArgoWrokflows or both being able to authenticate. Make sure you name them clearly and stick to the defaults if you do it through AWS Console. Note the App client id and App client secret. We are going to use them later.
  • Configure an app client per correspondent Argo application.
    • In Enabled Identity Providers select Cognito User Pool
    • In Callback URL(s) specify https://${your-ARGOCD-fqdn}/auth/callback for ArgoCD, or https://${your-ARGOWORKFLOWS-fqdn}/oauth2/callback for ArgoWorkFlows.
    • In Sign out URL(s) specify https://${your-ARGOCD-fqdn}/logout for ArgoCD, or https://${your-ARGOWORKFLOWS-fqdn}/logout for ArgoWorkFlows.
    • In Allowed OAuth Flows select Authorization code grant
    • In Allowed OAuth Scopes select email, openid, profile
    • Save Changes
    • *If you were adding both, double-check yourself, it's easy to mix them up ;)
  • Configure the domain name. You must have it for authentication flow to work.
    • For this guide, use Amazon Cognito domain with a custom Domain prefix, set any value there. Cognito will use it to redirect you to your UserPoll Sign In page. It is OK to use your own domain as well but its config is out of the scope of this guide. Take note of the domain.

Example of the app client config: CleanShot 2022-07-18 at 14 44 39@2x

  • For this guide, use Amazon Cognito domain with a custom Domain prefix, set any value there. Cognito will use it to redirect you to your UserPoll Sign In page. It is OK to use your own domain as well but its config is out of the scope of this guide. Take note of the domain.

ArgoCD SSO configuration with AWS Cognito with RBAC

Authentication

Let's make sure we have the following from the "UserPool configuration" section:

  • your UserPool IDP endpoint - it follows this schema https://cognito-idp.${aws-region}.amazonaws.com/${UserPool-ID}. For example https://cognito-idp.us-east-1.amazonaws.com/us-east-1_uTZRXY6BL
  • your ArgoCD app client ID. For example: 67dted0oitvupuubmah32ar10s
  • your ArgoCD app client Secret. For example: dp9cvv8f055pt99203aos3iota0ci7up96dgmfdi1eu03c569hj.

If you deploy ArgoCD through HelmChart, this is how you would configure it, in two pieces:

  1. In Helm Values specify:
server:
    config:
        oidc.config: |
            name: Cognito # name can be anything, it is a label on the SSO button on Login Screen
            issuer: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_uTZRXY6BL # UserPool IDP endpoint
            clientID: 67dted0oitvupuubmah32ar10s # ArgoCD app client ID
            clientSecret: dp9cvv8f055pt99203aos3iota0ci7up96dgmfdi1eu03c569hj # ArgoCD app client Secret
            requestedScopes: ["openid", "profile", "email"]
            requestedIDTokenClaims: {"groups": {"essential": true}}
  1. You also want to make sure that server.config.url is set with https://${your-ARGOCD-fqdn} so the whole redirect flow can work.
server:
    config:
        url: https://myargocd.acme.com

Deploy and check if the authentication flow works, you might need to create a user if not done yet (either sign-up from the login form or instantiate a user in AWS UserPool Console)

RBAC

When authenticated, you might see something strange - your user is not allowed to do anything in ArgoCD. Depending on your RBAC config, you will likely have a default role:readonly associated with users without any matching RBAC rule. Let's fix that quickly.

In server.rbacConfig specify scopes: '[cognito:groups]' and in server.rbacConfig.policy.csv add this line g, argocd-admin, role:admin. So it becomes something like:

server:
  rbacConfig:
      policy.csv: |
        g, argocd-admin, role:admin
      scopes: '[cognito:groups]'

Notice this argocd-admin in the policy definition? It is the name of the Cognito UserPool group, which should be associated with the user in the UserPool to assign the user the built-in ArgoCD Admin role. So we need to create that group and add our users there. You can name the group whatever makes sense to you. Just make sure the group name in ArgoCD RBAC policy config matches the group name from UserPool.

Make all the changes - new group, add your user in that group and do the ArgoCD RBAC config deployment. Now, do Log Out and Log back in. If you head to "User Info" you should see the Groups associated with your user, and you should also be able to perform administrative operations now.

Proper Log Out

But if you noticed, you weren't prompted to enter your credentials when you logged out and logged back in. If you think that that's the whole point of SSO, you can skip this section, but if you like me, I am a bit paranoid and would expect the Log Out to actually Log you Out not only from ArgoCD but from Cognito UserPool as well, then bear with me. We need to make ArgoCD aware about how actually to perform the Log Out from Cognito, for this we need to add proper logoutURL into oidc.config. logoutURL is a long endpoint string, built like this: https://${UserPool-domain}/logout?client_id=${ArgoCD-app-client-ID}&logout_uri=https://${your-ARGOCD-fqdn}/logout, so the change will be alike:

server:
    config:
        oidc.config: |
            logoutURL: https://my-user-pool.auth.us-east-1.amazoncognito.com/logout?client_id=67dted0oitvupuubmah32ar10s&logout_uri=https://myargocd.acme.com/logout

CLI authentication

We will need another secret-less app client in the Cognito user pool. Go and create one in AWS Console. Just make sure Generate client secret option is not selected. Take a note of it's client ID. Now configure this client app. Let's make sure the following is selected:

  • In Enabled Identity Providers select Cognito User Pool
  • In Callback URL(s) specify http://localhost:8085/auth/callback
  • In Allowed OAuth Flows select Authorization code grant
  • In Allowed OAuth Scopes select email, openid, profile
  • Save Changes

We need to make ArgoCD aware of how to perform the CLI authentication. For this we need to add cliClientID into oidc.config.

server:
    config:
        oidc.config: |
            cliClientID:  6isf75hfyieuk4gks29st6moq1

Deploy, and it's time to test with argocd login https://myargocd.acme.com --sso. * If you need to use different port (not default - 8085), just pass it in with argocd login https://myargocd.acme.com --sso --sso-port 3300 and make sure that app client Callback URL(s) will match http://localhost:3300/auth/callback.

Bonus

If you did not do yet, you could free up some resources by disabling the dex deployment (by default on). It is not needed in such a setup. Do it through Helm Values:

dex:
  enabled: false

ArgoWorkflows SSO configuration with AWS Cognito

Authentication

Let's make sure we have the following from the "UserPool configuration" section:

  • your UserPool IDP endpoint - it follows this schema https://cognito-idp.${aws-region}.amazonaws.com/${UserPool-ID}. For example https://cognito-idp.us-east-1.amazonaws.com/us-east-1_uTZRXY6BL
  • your ArgoWorkflows app client ID. For example: t7dted0oittopwbmah32ar2ps
  • your ArgoWorkflows app client Secret. For example: ap9cvv8f055pt99203aos3iyaa0ci7up96dgmfdi1eu03c23ihj.

If you deploy ArgoWorkflows through HelmChart, this is how you would configure it, in two pieces:

  1. In Helm Values specify:
server:
  sso:
    issuer: https://cognito-idp.us-east-1.amazonaws.com/us-east-1_uTZRXY6BL
    sessionExpiry: 8h
    clientId:
      name: argo-server-sso
      key: client-id
    clientSecret:
      name: argo-server-sso
      key: client-secret
    redirectUrl: https://myargoworkflows.acme.com/oauth2/callback # just replace myargoworkflows.acme.com
    rbac:
      enabled: false
    scopes: ["openid", "profile", "email"]
    customGroupClaimName: "cognito:groups"
    
  extraArgs:
  - --auth-mode=sso 
  1. Create a Secret in the same namespace where ArgoWorkflows is deployed:
apiVersion: v1
kind: Secret
metadata:
  name: argo-server-sso
  namespace: argoworkflows
stringData:
  client-id: t7dted0oittopwbmah32ar2ps
  client-secret: ap9cvv8f055pt99203aos3iyaa0ci7up96dgmfdi1eu03c23ihj

Deploy and check if the authentication flow works, you might need to create a user if not done yet (either sign-up from the login form or instantiate a user in AWS UserPool Console)

RBAC

Notice how we did

server:
  sso:
    rbac:
      enabled: false

You might want to change this to true to benefit from RBAC. It requires at least one ServiceAccount to be present with an annotation linked to the user group. During the authentication flow, all UserPool groups associated with the user will be passed down from Cognito UserPool to ArgoWorkflows.

Proper Log Out

While I write, ArgoWorkflows does not support the custom Log Out URL required to log out from Cognito UserPool. argoproj/argo-workflows#8994

CLI authentication

Find the Using Your Login With The CLI instruction on your User Info page in ArgoWorkflows.

Troubleshooting

  • make sure you use an "incognito" browser session when testing some changes on already configured UserPool
  • ensure the custom domain name is resolvable https://my-user-pool.auth.us-east-1.amazoncognito.com (might take minutes to propagate)
@rmalenko
Copy link

rmalenko commented Oct 4, 2022

Hi,
Could you help me understand why I got a 401 error, please?
After login, I redirect to https://my.domain/oauth2/callback with 401 Unauthorized.

@vavdoshka
Copy link
Author

Hello @rmalenko,
it's hard to say without knowing the setup.
Do you use correct oidc.config.clientSecret? I suspect the ArgoCD server log can uncover some details.

@rmalenko
Copy link

rmalenko commented Oct 6, 2022

Hello @vavdoshka

Yes, I have used the identical Client ID and Client secret in my secret argo-workflows-sso

data:
  client-id: Cognito Client ID
  client-secret: Cognito Client secret

From log of argo-workflows-server path=/oauth2/callback size=0 status=400

request https://domain/oauth2/callback?code=99e0wwc4-a51b-452a-baf9-2ab5b5b8e2b0&state=51wff3b0d6

@vavdoshka
Copy link
Author

Hello @rmalenko,

Maybe it is not relevant anymore, but I've bumped into a similar use-case recently
and the issue was due to default RBAC settings, I think they have changed them in some of the recent ArgoCD versions.

401 would mean that the auth flow worked out, but there is no role assigned to your user in ArgoCD hence nothing is allowed.
Try to test with

rbacConfig:
  policy.default: "role:readonly"

Then if you will have read access, this is the problem of RBAC.
Next, you will need to configure it properly with

rbacConfig:
  policy.default: ""
  policy.csv: |
    g, argocd-admin, role:admin
    scopes: '[cognito:groups]'

and make sure:

  • there is a argocd-admin group in Cognito user pool
  • your user is added to that group

Next you can play with RBAC and fine-tune specific roles if needed.

@mconigliaro
Copy link

mconigliaro commented Feb 28, 2023

Helm options that don't exist:

  • server.config.oidc.config
  • server.config.url

See: https://github.com/argoproj/argo-helm/blob/main/charts/argo-cd/values.yaml

@vavdoshka
Copy link
Author

yeah seems like with this commit argoproj/argo-helm@c8f7efb

server.config.oidc.config was moved to configs.cm.oidc.config
and server.config.url to configs.cm.url

I can update the references in guide if someone confirms that still works :)

@mconigliaro
Copy link

@roberto-caylent
Copy link

by any chance have you setup argocd authetnication but using an AWS SSO/Identity center SAML application?

@mconigliaro
Copy link

@millermatt
Copy link

Thank you for this gist.

@oknehcnap
Copy link

Thank you sir!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment