A short, reproducible guide to wiring ArgoCD login to AWS Identity Center using ArgoCD's bundled Dex as a SAML service provider. Works whether IdC's identity source is its own directory or an external IdP (e.g. Google), with a couple of non-obvious gotchas that will cost you hours if you miss them (see Gotchas).
Why this approach
- Access governed in IdC: grant/revoke ArgoCD like AWS account access; one plane to on/offboard.
- No client secret: SAML trust is cert-based (IdC's public signing cert). Nothing to store or rotate.
- No cluster egress: the browser brokers the redirect; Dex only verifies the assertion with the embedded cert. No outbound calls to the IdP.
Prerequisites
- ArgoCD reachable over HTTPS at a stable hostname (e.g.
https://argocd.example.com). It can be private/internal, SAML is browser-mediated, so IdC never connects to it; only the user's browser does. - Admin on IdC (the delegated-admin account is fine).
Steps
1.0 Create the IdC application
IdC > Applications > Add application > Add custom SAML 2.0 application. Under Application metadata > "type manually", set both:
- ACS URL:
https://argocd.example.com/api/dex/callback - SAML audience:
https://argocd.example.com/api/dex/callback
2.0 Attribute mappings
exactly these two (see Gotchas for why only two, and why the format matters):
| App attribute | Maps to | Format |
|---|---|---|
| Subject | ${user:subject} | persistent |
| ${user:email} | unspecified |
3.0 Assign users: to the app — this is your access gate (only assigned users can sign in).
4.0 Grab IdC metadata: (app > IAM Identity Center metadata):
- sign-in URL > your ssoURL
- certificate > download and base64 it single-line > your caData
5.0 Configure ArgoCD: (argocd-cm / Helm values):
configs:
cm:
url: https://argocd.example.com
dex.config: |
connectors:
- type: saml
id: aws-idc
name: Identity Center
config:
ssoURL: <IdC sign-in URL>
caData: <base64 of IdC cert>
entityIssuer: https://argocd.example.com/api/dex/callback # MUST == SAML audience
redirectURI: https://argocd.example.com/api/dex/callback # MUST == ACS URL
usernameAttr: email
emailAttr: email
rbac:
policy.default: role:readonly
scopes: '[email]'
policy.csv: |
g, you@example.com, role:admin
6.0 Log in: go to https://argocd.example.com and click Log in via Identity Center.
Gotchas
- Set the Subject NameID
Formattopersistent, notemailAddress. WithemailAddress, IdC can't emit a valid NameID in this setup and returns a genericForbiddenException: "No access" at sign-in, which looks exactly like an assignment/identity problem. - Don't map
groups > ${user:groups}. IdC custom SAML apps cannot emit group membership, saving it errors withBad input, and it's unnecessary since RBAC matches on email. (The official ArgoCD doc suggests it, but that assumes IdC's own directory, not an external IdP.) - Dex is SP-initiated only; Clicking the app tile in the AWS access portal (IdP-initiated) gives Dex
Bad Request: User session error. (Set the app's "Application start URL" in the IdC application to your ArgoCD URL so the tile just redirects there.) -
audiencemust equalentityIssuer. The IdC sign-in URL is instance-level (shared by all apps), so SP-initiated requests are resolved to the app by SAML audience. A mismatch givesResource not found. - HTTPS end-to-end. If ArgoCD sits behind an SSL-terminating proxy, make sure
configs.cm.urlishttps://…so Dex doesn't emit an http:// ACS in the AuthnRequest (IdC rejects that withForbiddenException).
Hardening (after SSO is confirmed for your admins)
configs:
cm:
admin.enabled: "false" # disable the built-in local admin - SSO only
Then remove the bootstrap secret:
kubectl -n argocd delete secret argocd-initial-admin-secret
Break-glass: this doesn't lock you out, anyone with cluster-admin can re-enable it.

Top comments (0)