github.com/argoproj/argo-cd/v3@v3.2.1/docs/operator-manual/user-management/index.md (about) 1 # Overview 2 3 Once installed Argo CD has one built-in `admin` user that has full access to the system. It is recommended to use `admin` user only 4 for initial configuration and then switch to local users or configure SSO integration. 5 6 ## Local users/accounts 7 8 The local users/accounts feature serves two main use-cases: 9 10 * Auth tokens for Argo CD management automation. It is possible to configure an API account with limited permissions and generate an authentication token. 11 Such token can be used to automatically create applications, projects etc. 12 * Additional users for a very small team where use of SSO integration might be considered an overkill. The local users don't provide advanced features such as groups, 13 login history etc. So if you need such features it is strongly recommended to use SSO. 14 15 !!! note 16 When you create local users, each of those users will need additional [RBAC rules](../rbac.md) set up, otherwise they will fall back to the default policy specified by `policy.default` field of the `argocd-rbac-cm` ConfigMap. 17 18 The maximum length of a local account's username is 32. 19 20 ### Create new user 21 22 New users should be defined in `argocd-cm` ConfigMap: 23 24 ```yaml 25 apiVersion: v1 26 kind: ConfigMap 27 metadata: 28 name: argocd-cm 29 namespace: argocd 30 labels: 31 app.kubernetes.io/name: argocd-cm 32 app.kubernetes.io/part-of: argocd 33 data: 34 # add an additional local user with apiKey and login capabilities 35 # apiKey - allows generating API keys 36 # login - allows to login using UI 37 accounts.alice: apiKey, login 38 # disables user. User is enabled by default 39 accounts.alice.enabled: "false" 40 ``` 41 42 Each user might have two capabilities: 43 44 * apiKey - allows generating authentication tokens for API access 45 * login - allows to login using UI 46 47 ### Delete user 48 49 In order to delete a user, you must remove the corresponding entry defined in the `argocd-cm` ConfigMap: 50 51 Example: 52 53 ```bash 54 kubectl patch -n argocd cm argocd-cm --type='json' -p='[{"op": "remove", "path": "/data/accounts.alice"}]' 55 ``` 56 57 It is recommended to also remove the password entry in the `argocd-secret` Secret: 58 59 Example: 60 61 ```bash 62 kubectl patch -n argocd secrets argocd-secret --type='json' -p='[{"op": "remove", "path": "/data/accounts.alice.password"}]' 63 ``` 64 65 ### Disable admin user 66 67 As soon as additional users are created it is recommended to disable `admin` user: 68 69 ```yaml 70 apiVersion: v1 71 kind: ConfigMap 72 metadata: 73 name: argocd-cm 74 namespace: argocd 75 labels: 76 app.kubernetes.io/name: argocd-cm 77 app.kubernetes.io/part-of: argocd 78 data: 79 admin.enabled: "false" 80 ``` 81 82 ### Manage users 83 84 The Argo CD CLI provides set of commands to set user password and generate tokens. 85 86 * Get full users list 87 ```bash 88 argocd account list 89 ``` 90 91 * Get specific user details 92 ```bash 93 argocd account get --account <username> 94 ``` 95 96 * Set user password 97 ```bash 98 # if you are managing users as the admin user, <current-user-password> should be the current admin password. 99 argocd account update-password \ 100 --account <name> \ 101 --current-password <current-user-password> \ 102 --new-password <new-user-password> 103 ``` 104 105 * Generate auth token 106 ```bash 107 # if flag --account is omitted then Argo CD generates token for current user 108 argocd account generate-token --account <username> 109 ``` 110 111 ### Failed logins rate limiting 112 113 Argo CD rejects login attempts after too many failed in order to prevent password brute-forcing. 114 The following environments variables are available to control throttling settings: 115 116 * `ARGOCD_SESSION_FAILURE_MAX_FAIL_COUNT`: Maximum number of failed logins before Argo CD starts 117 rejecting login attempts. Default: 5. 118 119 * `ARGOCD_SESSION_FAILURE_WINDOW_SECONDS`: Number of seconds for the failure window. 120 Default: 300 (5 minutes). If this is set to 0, the failure window is 121 disabled and the login attempts gets rejected after 10 consecutive logon failures, 122 regardless of the time frame they happened. 123 124 * `ARGOCD_SESSION_MAX_CACHE_SIZE`: Maximum number of entries allowed in the 125 cache. Default: 1000 126 127 * `ARGOCD_MAX_CONCURRENT_LOGIN_REQUESTS_COUNT`: Limits max number of concurrent login requests. 128 If set to 0 then limit is disabled. Default: 50. 129 130 ## SSO 131 132 There are two ways that SSO can be configured: 133 134 * [Bundled Dex OIDC provider](#dex) - use this option if your current provider does not support OIDC (e.g. SAML, 135 LDAP) or if you wish to leverage any of Dex's connector features (e.g. the ability to map GitHub 136 organizations and teams to OIDC groups claims). Dex also supports OIDC directly and can fetch user 137 information from the identity provider when the groups cannot be included in the IDToken. 138 139 * [Existing OIDC provider](#existing-oidc-provider) - use this if you already have an OIDC provider which you are using (e.g. 140 [Okta](okta.md), [OneLogin](onelogin.md), [Auth0](auth0.md), [Microsoft](microsoft.md), [Keycloak](keycloak.md), 141 [Google (G Suite)](google.md)), where you manage your users, groups, and memberships. 142 143 ## Dex 144 145 Argo CD embeds and bundles [Dex](https://github.com/dexidp/dex) as part of its installation, for the 146 purpose of delegating authentication to an external identity provider. Multiple types of identity 147 providers are supported (OIDC, SAML, LDAP, GitHub, etc...). SSO configuration of Argo CD requires 148 editing the `argocd-cm` ConfigMap with 149 [Dex connector](https://dexidp.io/docs/connectors/) settings. 150 151 This document describes how to configure Argo CD SSO using GitHub (OAuth2) as an example, but the 152 steps should be similar for other identity providers. 153 154 ### 1. Register the application in the identity provider 155 156 In GitHub, register a new application. The callback address should be the `/api/dex/callback` 157 endpoint of your Argo CD URL (e.g. `https://argocd.example.com/api/dex/callback`). 158 159  160 161 After registering the app, you will receive an OAuth2 client ID and secret. These values will be 162 inputted into the Argo CD configmap. 163 164  165 166 ### 2. Configure Argo CD for SSO 167 168 Edit the argocd-cm configmap: 169 170 ```bash 171 kubectl edit configmap argocd-cm -n argocd 172 ``` 173 174 * In the `url` key, input the base URL of Argo CD. In this example, it is `https://argocd.example.com` 175 * (Optional): If Argo CD should be accessible via multiple base URLs you may 176 specify any additional base URLs via the `additionalUrls` key. 177 * In the `dex.config` key, add the `github` connector to the `connectors` sub field. See Dex's 178 [GitHub connector](https://github.com/dexidp/website/blob/main/content/docs/connectors/github.md) 179 documentation for explanation of the fields. A minimal config should populate the clientID, 180 clientSecret generated in Step 1. 181 * You will very likely want to restrict logins to one or more GitHub organization. In the 182 `connectors.config.orgs` list, add one or more GitHub organizations. Any member of the org will 183 then be able to login to Argo CD to perform management tasks. 184 185 ```yaml 186 data: 187 url: https://argocd.example.com 188 189 dex.config: | 190 connectors: 191 # GitHub example 192 - type: github 193 id: github 194 name: GitHub 195 config: 196 clientID: aabbccddeeff00112233 197 clientSecret: $dex.github.clientSecret # Alternatively $<some_K8S_secret>:dex.github.clientSecret 198 orgs: 199 - name: your-github-org 200 201 # GitHub enterprise example 202 - type: github 203 id: acme-github 204 name: Acme GitHub 205 config: 206 hostName: github.acme.example.com 207 clientID: abcdefghijklmnopqrst 208 clientSecret: $dex.acme.clientSecret # Alternatively $<some_K8S_secret>:dex.acme.clientSecret 209 orgs: 210 - name: your-github-org 211 ``` 212 213 After saving, the changes should take effect automatically. 214 215 NOTES: 216 217 * There is no need to set `redirectURI` in the `connectors.config` as shown in the dex documentation. 218 Argo CD will automatically use the correct `redirectURI` for any OAuth2 connectors, to match the 219 correct external callback URL (e.g. `https://argocd.example.com/api/dex/callback`) 220 * When using a custom secret (e.g., `some_K8S_secret` above,) it *must* have the label `app.kubernetes.io/part-of: argocd`. 221 222 ## OIDC Configuration with DEX 223 224 Dex can be used for OIDC authentication instead of ArgoCD directly. This provides a separate set of 225 features such as fetching information from the `UserInfo` endpoint and 226 [federated tokens](https://dexidp.io/docs/custom-scopes-claims-clients/#cross-client-trust-and-authorized-party) 227 228 ### Configuration: 229 * In the `argocd-cm` ConfigMap add the `OIDC` connector to the `connectors` sub field inside `dex.config`. 230 See Dex's [OIDC connect documentation](https://dexidp.io/docs/connectors/oidc/) to see what other 231 configuration options might be useful. We're going to be using a minimal configuration here. 232 * The issuer URL should be where Dex talks to the OIDC provider. There would normally be a 233 `.well-known/openid-configuration` under this URL which has information about what the provider supports. 234 e.g. https://accounts.google.com/.well-known/openid-configuration 235 236 237 ```yaml 238 data: 239 url: "https://argocd.example.com" 240 dex.config: | 241 connectors: 242 # OIDC 243 - type: oidc 244 id: oidc 245 name: OIDC 246 config: 247 issuer: https://example-OIDC-provider.example.com 248 clientID: aaaabbbbccccddddeee 249 clientSecret: $dex.oidc.clientSecret 250 ``` 251 252 ### Requesting additional ID token claims 253 254 By default Dex only retrieves the profile and email scopes. In order to retrieve more claims you 255 can add them under the `scopes` entry in the Dex configuration. To enable group claims through Dex, 256 `insecureEnableGroups` also needs to be enabled. Group information is currently only refreshed at authentication 257 time and support to refresh group information more dynamically can be tracked here: [dexidp/dex#1065](https://github.com/dexidp/dex/issues/1065). 258 259 ```yaml 260 data: 261 url: "https://argocd.example.com" 262 dex.config: | 263 connectors: 264 # OIDC 265 - type: oidc 266 id: oidc 267 name: OIDC 268 config: 269 issuer: https://example-OIDC-provider.example.com 270 clientID: aaaabbbbccccddddeee 271 clientSecret: $dex.oidc.clientSecret 272 insecureEnableGroups: true 273 scopes: 274 - profile 275 - email 276 - groups 277 ``` 278 279 !!! warning 280 Because group information is only refreshed at authentication time just adding or removing an account from a group will not change a user's membership until they reauthenticate. Depending on your organization's needs this could be a security risk and could be mitigated by changing the authentication token's lifetime. 281 282 ### Retrieving claims that are not in the token 283 284 When an Idp does not or cannot support certain claims in an IDToken they can be retrieved separately using 285 the UserInfo endpoint. Dex supports this functionality using the `getUserInfo` endpoint. One of the most 286 common claims that is not supported in the IDToken is the `groups` claim and both `getUserInfo` and `insecureEnableGroups` 287 must be set to true. 288 289 ```yaml 290 data: 291 url: "https://argocd.example.com" 292 dex.config: | 293 connectors: 294 # OIDC 295 - type: oidc 296 id: oidc 297 name: OIDC 298 config: 299 issuer: https://example-OIDC-provider.example.com 300 clientID: aaaabbbbccccddddeee 301 clientSecret: $dex.oidc.clientSecret 302 insecureEnableGroups: true 303 scopes: 304 - profile 305 - email 306 - groups 307 getUserInfo: true 308 ``` 309 310 ## Existing OIDC Provider 311 312 To configure Argo CD to delegate authentication to your existing OIDC provider, add the OAuth2 313 configuration to the `argocd-cm` ConfigMap under the `oidc.config` key: 314 315 ```yaml 316 data: 317 url: https://argocd.example.com 318 319 oidc.config: | 320 name: Okta 321 issuer: https://dev-123456.oktapreview.com 322 clientID: aaaabbbbccccddddeee 323 clientSecret: $oidc.okta.clientSecret 324 325 # Optional list of allowed aud claims. If omitted or empty, defaults to the clientID value above (and the 326 # cliClientID, if that is also specified). If you specify a list and want the clientID to be allowed, you must 327 # explicitly include it in the list. 328 # Token verification will pass if any of the token's audiences matches any of the audiences in this list. 329 allowedAudiences: 330 - aaaabbbbccccddddeee 331 - qqqqwwwweeeerrrrttt 332 333 # Optional. If false, tokens without an audience will always fail validation. If true, tokens without an audience 334 # will always pass validation. 335 # Defaults to true for Argo CD < 2.6.0. Defaults to false for Argo CD >= 2.6.0. 336 skipAudienceCheckWhenTokenHasNoAudience: true 337 338 # Optional set of OIDC scopes to request. If omitted, defaults to: ["openid", "profile", "email", "groups"] 339 requestedScopes: ["openid", "profile", "email", "groups"] 340 341 # Optional set of OIDC claims to request on the ID token. 342 requestedIDTokenClaims: {"groups": {"essential": true}} 343 344 # Some OIDC providers require a separate clientID for different callback URLs. 345 # For example, if configuring Argo CD with self-hosted Dex, you will need a separate client ID 346 # for the 'localhost' (CLI) client to Dex. This field is optional. If omitted, the CLI will 347 # use the same clientID as the Argo CD server 348 cliClientID: vvvvwwwwxxxxyyyyzzzz 349 350 # PKCE is an OIDC extension to prevent authorization code interception attacks. 351 # Make sure the identity provider supports it and that it is activated for Argo CD OIDC client. 352 # Default is false. 353 enablePKCEAuthentication: true 354 ``` 355 356 !!! note 357 The callback address should be the /auth/callback endpoint of your Argo CD URL 358 (e.g. https://argocd.example.com/auth/callback). 359 360 ### Requesting additional ID token claims 361 362 Not all OIDC providers support a special `groups` scope. E.g. Okta, OneLogin and Microsoft do support a special 363 `groups` scope and will return group membership with the default `requestedScopes`. 364 365 Other OIDC providers might be able to return a claim with group membership if explicitly requested to do so. 366 Individual claims can be requested with `requestedIDTokenClaims`, see 367 [OpenID Connect Claims Parameter](https://connect2id.com/products/server/docs/guides/requesting-openid-claims#claims-parameter) 368 for details. The Argo CD configuration for claims is as follows: 369 370 ```yaml 371 oidc.config: | 372 requestedIDTokenClaims: 373 email: 374 essential: true 375 groups: 376 essential: true 377 value: org:myorg 378 acr: 379 essential: true 380 values: 381 - urn:mace:incommon:iap:silver 382 - urn:mace:incommon:iap:bronze 383 ``` 384 385 For a simple case this can be: 386 387 ```yaml 388 oidc.config: | 389 requestedIDTokenClaims: {"groups": {"essential": true}} 390 ``` 391 392 ### Retrieving group claims when not in the token 393 394 Some OIDC providers don't return the group information for a user in the ID token, even if explicitly requested using the `requestedIDTokenClaims` setting (Okta for example). They instead provide the groups on the user info endpoint. With the following config, Argo CD queries the user info endpoint during login for groups information of a user: 395 396 ```yaml 397 oidc.config: | 398 enableUserInfoGroups: true 399 userInfoPath: /userinfo 400 userInfoCacheExpiration: "5m" 401 ``` 402 403 **Note: If you omit the `userInfoCacheExpiration` setting or if it's greater than the expiration of the ID token, the argocd-server will cache group information as long as the ID token is valid!** 404 405 ### Configuring a custom logout URL for your OIDC provider 406 407 Optionally, if your OIDC provider exposes a logout API and you wish to configure a custom logout URL for the purposes of invalidating 408 any active session post logout, you can do so by specifying it as follows: 409 410 ```yaml 411 oidc.config: | 412 name: example-OIDC-provider 413 issuer: https://example-OIDC-provider.example.com 414 clientID: xxxxxxxxx 415 clientSecret: xxxxxxxxx 416 requestedScopes: ["openid", "profile", "email", "groups"] 417 requestedIDTokenClaims: {"groups": {"essential": true}} 418 logoutURL: https://example-OIDC-provider.example.com/logout?id_token_hint={{token}} 419 ``` 420 By default, this would take the user to their OIDC provider's login page after logout. If you also wish to redirect the user back to Argo CD after logout, you can specify the logout URL as follows: 421 422 ```yaml 423 ... 424 logoutURL: https://example-OIDC-provider.example.com/logout?id_token_hint={{token}}&post_logout_redirect_uri={{logoutRedirectURL}} 425 ``` 426 427 You are not required to specify a logoutRedirectURL as this is automatically generated by ArgoCD as your base ArgoCD url + Rootpath 428 429 !!! note 430 The post logout redirect URI may need to be whitelisted against your OIDC provider's client settings for ArgoCD. 431 432 ### Configuring a custom root CA certificate for communicating with the OIDC provider 433 434 If your OIDC provider is setup with a certificate which is not signed by one of the well known certificate authorities 435 you can provide a custom certificate which will be used in verifying the OIDC provider's TLS certificate when 436 communicating with it. 437 Add a `rootCA` to your `oidc.config` which contains the PEM encoded root certificate: 438 439 ```yaml 440 oidc.config: | 441 ... 442 rootCA: | 443 -----BEGIN CERTIFICATE----- 444 ... encoded certificate data here ... 445 -----END CERTIFICATE----- 446 ``` 447 448 449 ## SSO Further Reading 450 451 ### Sensitive Data and SSO Client Secrets 452 453 `argocd-secret` can be used to store sensitive data which can be referenced by ArgoCD. Values starting with `$` in configmaps are interpreted as follows: 454 455 - If value has the form: `$<secret>:a.key.in.k8s.secret`, look for a k8s secret with the name `<secret>` (minus the `$`), and read its value. 456 - Otherwise, look for a key in the k8s secret named `argocd-secret`. 457 458 #### Example 459 460 SSO `clientSecret` can thus be stored as a Kubernetes secret with the following manifests 461 462 `argocd-secret`: 463 ```yaml 464 apiVersion: v1 465 kind: Secret 466 metadata: 467 name: argocd-secret 468 namespace: argocd 469 labels: 470 app.kubernetes.io/name: argocd-secret 471 app.kubernetes.io/part-of: argocd 472 type: Opaque 473 data: 474 ... 475 # The secret value must be base64 encoded **once** 476 # this value corresponds to: `printf "hello-world" | base64` 477 oidc.auth0.clientSecret: "aGVsbG8td29ybGQ=" 478 ... 479 ``` 480 481 `argocd-cm`: 482 ```yaml 483 apiVersion: v1 484 kind: ConfigMap 485 metadata: 486 name: argocd-cm 487 namespace: argocd 488 labels: 489 app.kubernetes.io/name: argocd-cm 490 app.kubernetes.io/part-of: argocd 491 data: 492 ... 493 oidc.config: | 494 name: Auth0 495 clientID: aabbccddeeff00112233 496 497 # Reference key in argocd-secret 498 clientSecret: $oidc.auth0.clientSecret 499 ... 500 ``` 501 502 #### Alternative 503 504 If you want to store sensitive data in **another** Kubernetes `Secret`, instead of `argocd-secret`. ArgoCD knows to check the keys under `data` in your Kubernetes `Secret` for a corresponding key whenever a value in a configmap or secret starts with `$`, then your Kubernetes `Secret` name and `:` (colon). 505 506 Syntax: `$<k8s_secret_name>:<a_key_in_that_k8s_secret>` 507 508 > NOTE: Secret must have label `app.kubernetes.io/part-of: argocd` 509 510 ##### Example 511 512 `another-secret`: 513 ```yaml 514 apiVersion: v1 515 kind: Secret 516 metadata: 517 name: another-secret 518 namespace: argocd 519 labels: 520 app.kubernetes.io/part-of: argocd 521 type: Opaque 522 data: 523 ... 524 # Store client secret like below. 525 # Ensure the secret is base64 encoded 526 oidc.auth0.clientSecret: <client-secret-base64-encoded> 527 ... 528 ``` 529 530 `argocd-cm`: 531 ```yaml 532 apiVersion: v1 533 kind: ConfigMap 534 metadata: 535 name: argocd-cm 536 namespace: argocd 537 labels: 538 app.kubernetes.io/name: argocd-cm 539 app.kubernetes.io/part-of: argocd 540 data: 541 ... 542 oidc.config: | 543 name: Auth0 544 clientID: aabbccddeeff00112233 545 # Reference key in another-secret (and not argocd-secret) 546 clientSecret: $another-secret:oidc.auth0.clientSecret # Mind the ':' 547 ... 548 ``` 549 550 ### Skipping certificate verification on OIDC provider connections 551 552 By default, all connections made by the API server to OIDC providers (either external providers or the bundled Dex 553 instance) must pass certificate validation. These connections occur when getting the OIDC provider's well-known 554 configuration, when getting the OIDC provider's keys, and when exchanging an authorization code or verifying an ID 555 token as part of an OIDC login flow. 556 557 Disabling certificate verification might make sense if: 558 * You are using the bundled Dex instance **and** your Argo CD instance has TLS configured with a self-signed certificate 559 **and** you understand and accept the risks of skipping OIDC provider cert verification. 560 * You are using an external OIDC provider **and** that provider uses an invalid certificate **and** you cannot solve 561 the problem by setting `oidcConfig.rootCA` **and** you understand and accept the risks of skipping OIDC provider cert 562 verification. 563 564 If either of those two applies, then you can disable OIDC provider certificate verification by setting 565 `oidc.tls.insecure.skip.verify` to `"true"` in the `argocd-cm` ConfigMap.