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.
- 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
andApp client secret
. We are going to use them later. - Configure an app client per correspondent Argo application.
- In
Enabled Identity Providers
selectCognito User Pool
- In
Callback URL(s)
specifyhttps://${your-ARGOCD-fqdn}/auth/callback
for ArgoCD, orhttps://${your-ARGOWORKFLOWS-fqdn}/oauth2/callback
for ArgoWorkFlows. - In
Sign out URL(s)
specifyhttps://${your-ARGOCD-fqdn}/logout
for ArgoCD, orhttps://${your-ARGOWORKFLOWS-fqdn}/logout
for ArgoWorkFlows. - In
Allowed OAuth Flows
selectAuthorization code grant
- In
Allowed OAuth Scopes
selectemail
,openid
,profile
- Save Changes
- *If you were adding both, double-check yourself, it's easy to mix them up ;)
- In
- Configure the domain name. You must have it for authentication flow to work.
- For this guide, use
Amazon Cognito domain
with a customDomain 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.
- For this guide, use
Example of the app client config:
- For this guide, use
Amazon Cognito domain
with a customDomain 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.
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 examplehttps://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:
- 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}}
- You also want to make sure that
server.config.url
is set withhttps://${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)
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.
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
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
selectCognito User Pool
- In
Callback URL(s)
specifyhttp://localhost:8085/auth/callback
- In
Allowed OAuth Flows
selectAuthorization code grant
- In
Allowed OAuth Scopes
selectemail
,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
.
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
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 examplehttps://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:
- 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
- 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)
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.
While I write, ArgoWorkflows does not support the custom Log Out URL required to log out from Cognito UserPool. argoproj/argo-workflows#8994
Find the Using Your Login With The CLI
instruction on your User Info
page in ArgoWorkflows.
- 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)
Thank you for this gist.