Argo CD local users and API keys: when automation needs its own identity
Machine access to Argo CD comes from two mechanisms: local accounts with the apiKey capability, or JWT tokens issued to a project role. Both let a CI pipeline or script call the Argo CD API without anyone's SSO session. Consider a platform team whose release pipelines run argocd app sync using the login of a senior engineer who signed in through the company identity provider. When that engineer changes teams, leaves, or has their session policy tightened, the pipelines fail or, worse, keep running under an identity nobody is watching. A personal login also carries that person's full group memberships and interactive permissions, so the automation inherits more access than it needs and its actions appear in audit logs as a human's.
A local account is a named identity defined in argocd-cm with the apiKey capability, so it can generate tokens through the API but cannot sign in through the web console if you grant it only that capability. Its permissions come from RBAC rules in argocd-rbac-cm, so you should write a narrow policy for the account rather than rely on defaults. Local accounts suit a small number of long-lived integrations, such as a service that reports deployments or an admin script. A project role token suits pipelines that only touch one project: the project administrator creates a token for a role defined in that project, and the token is scoped to the permissions of that role. Confirm which option your tooling needs before choosing, because a token issued to a project role cannot do more than that role allows.
Teams need this only when automation must act on Argo CD itself, not just on Git. If pipelines only commit manifests and Argo CD syncs from Git, no API identity is required. Once a pipeline must sync, query application state, or trigger a refresh, decide the identity first and write down who owns it, which permissions it holds, and how it will be rotated and revoked. The rotation and revocation steps are covered in the sections that follow.
Choosing between a local account API key and a project role token
A local account with apiKey capability is a named identity that your platform team creates and manages in the argocd-cm ConfigMap. It exists independently of any person and any project, so the team that operates Argo CD owns its lifecycle. A project role token is different: it belongs to a project role, which is defined in the AppProject resource and usually maintained by the application team that owns that project. Ownership therefore follows the project, not a standalone identity.
- Account lifecycle: A local account is created, enabled and disabled through configuration in
argocd-cmusing keys such asaccounts.<name>.enabled. - Project lifecycle: A project role token ends when the role or project changes, so application teams can own their automation identity alongside the application.
- Naming limits: Local account names are limited to 32 characters, which affects how you name service accounts for each pipeline.
- Shared versus dedicated: Use one dedicated account per pipeline or team so that a compromised credential maps to one owner.
- Staffing change: Confirm who can edit
argocd-cmand who can edit AppProject resources in your cluster, because those two permissions determine who can change each identity.
Before choosing, confirm which team should be able to create, rotate and retire each automation identity in your own environment.
Permissions for a local account come from RBAC rules in argocd-rbac-cm that name the account directly. If a local account has no RBAC rules, it falls back to policy.default, so the default policy in your installation determines what an unmapped account can do. A project role token only carries the permissions defined for that role in the project, and the role name in policies must follow the form proj:<project-name>:<role-name>. That makes project tokens naturally bounded to one project.
- Account-level grants: A local account can be granted broad or cross-project permissions, which suits a platform-wide controller but enlarges the blast radius.
- Project-bounded grants: A project role token can only act within the project's destinations, sources and resource rules.
- Fallback risk: Review
policy.defaultbefore creating any account, because an account without explicit rules inherits it. - Role naming: Policy lines that reference project roles must use the exact
proj:naming format or they will not match. - Least privilege test: Create a test token or account, run the exact sync and read operations the pipeline needs, and confirm nothing else succeeds.
Confirm the policy syntax and default policy behavior for your installed version before writing rules.
Revoking access works differently for each mechanism. A local account can be disabled with accounts.<name>.enabled set to false, which stops it from authenticating without deleting its history or RBAC lines. A project role token is revoked individually with delete-token against the project role, using the token identifier, so one leaked token can be removed without disabling the role that issued others. Plan both paths before an incident, because a leaked credential needs a fast, tested response.
- Account disable: Disabling a local account stops all of its API keys at once, which is useful when one pipeline is compromised.
- Token-level revoke: Deleting one project role token leaves other tokens for the same role working.
- Rotation pattern: Issue a new token or key, update the pipeline secret, verify, then revoke the old one.
- Storage of credentials: Keep issued tokens in your secrets manager, not in Git or pipeline logs.
- Runbook test: Practice both revocation paths in a non-production cluster so the steps are known before they are needed.
Confirm the exact CLI commands, token identifiers and expiry handling for your Argo CD version before writing the runbook.
Both mechanisms let you attribute API activity to a non-human identity, but the audit story differs. A local account has a stable name that appears as the subject of its actions, which makes activity easy to group by pipeline. A project role token is tied to the project role, so activity is grouped by project and role, and two pipelines sharing one role share one attribution. Neither mechanism tells you which person started a pipeline, so you need your CI system's own records for that link.
- Stable subject: A dedicated local account gives each pipeline its own name in Argo CD activity.
- Role-level subject: Several pipelines using one project role are indistinguishable by identity alone.
- Pipeline linkage: Record the CI job or run identifier in your pipeline logs, since Argo CD does not identify the human who triggered the job.
- Log access: Logs access requires an explicit permission in newer versions, so decide which roles can read activity records.
- Credential redaction: Argo CD redacts cluster, Git and OAuth2 credentials from responses and logs, but confirm what your pipelines themselves write to their own logs.
Confirm what your Argo CD version records for API calls and how long those records are kept in your environment.
Configuration options and when each one fits
This table compares the Argo CD settings that govern machine access, from local account capabilities to project role tokens. Read each row as a decision: the option, the situation where it fits, and the trade-off it brings with it. The main takeaway is that project tokens are usually the narrower choice for CI, while a local account with apiKey is broader and needs more lifecycle work.
| Option | When it fits | Trade-off to plan for |
|---|---|---|
| accounts.<name>.apiKey capability in argocd-cm | A single pipeline or script needs to call the API under its own named identity, and you can scope it with RBAC rules. | The account can mint long-lived API keys, so you must own rotation, disablement and review of who holds the key. |
| accounts.<name>.login capability in argocd-cm | A human operator or break-glass path needs a password login to the UI or CLI that is separate from SSO. | Password login adds a credential you must protect and audit, and it bypasses the identity provider's controls. |
| accounts.<name>.enabled set to false | An account is retired, a pipeline is decommissioned, or you need to suspend access without deleting RBAC lines. | Disabling does not remove policy entries, so stale rules can remain and need periodic cleanup. |
| policy.default | You want a deliberate fallback for accounts with no explicit RBAC rules, such as read-only access for any authenticated user. | A permissive default grants access to every new account, so keep it empty or read-only unless you have a specific reason. |
| Project role with create-token and delete-token | A CI job must deploy only to one project and you need tokens tied to that project's permissions rather than a person. | Tokens are issued by the role, so anyone who can create tokens for that role controls its reach. Confirm the revocation process before rollout. |
| Role name format proj:<project-name>:<role-name> | You reference a project role in policy.csv or in a group binding and need the policy to target that exact role. | A typo or a renamed project silently breaks the binding, so test policy changes after any project rename. |
| 32-character limit on local account names | You are naming accounts for pipelines and want short, consistent identifiers that fit the limit. | Long descriptive names are rejected, so put detail such as owner and purpose in labels or documentation instead. |
Setting up a machine account and token step by step
This sequence creates a local Argo CD account that can only request API keys, scopes its permissions to named applications, issues a token, stores it for CI, and confirms both the allowed actions and a working revocation path.
Define the local account in argocd-cm
A platform engineer adds an entry under data in the argocd-cm ConfigMap for a name such as ci-deployer, setting accounts.ci-deployer to apiKey only so the account cannot sign in with a password. Keep the name within the 32-character limit and avoid reusing a person's name. Confirm the change with kubectl get configmap argocd-cm -n argocd -o yaml and check that the login capability does not appear for this account. Argo CD does not need a restart for the account itself to be readable, but confirm this behavior in your installed version before relying on it.
Write scoped RBAC lines in policy.csv
Next, the same engineer edits the argocd-rbac-cm ConfigMap and adds lines to policy.csv that grant the account only the actions it needs on specific applications, for example sync and get on applications in one project. Do not grant admin or wildcard access. Also confirm that the default policy (policy.default) does not give the account broader rights than you intend, since accounts without matching rules fall back to it. The output is a reviewed policy file committed to your configuration repository, not an ad hoc edit in the cluster.
Generate the token with the CLI or API
An administrator logs in with a personal admin session and runs argocd account generate-token --account ci-deployer, or calls the equivalent account token endpoint with that session. The command returns a JWT once. Record the issued token ID or note the time of issue in your change record, because you will need it for revocation. Confirm generation succeeded by checking that the account now lists a token in the account view. If the CLI rejects the account, re-check that apiKey is set for it in argocd-cm.
Store the token in the CI secret store
The pipeline owner saves the token as a masked, protected secret in the CI system's secret store, scoped to the jobs that deploy the target applications, and never in Git, a shared chat or a script body. Set the server address as a separate variable. Confirm the secret is referenced only by the intended jobs and that the log masking hides it when a test job echoes the variable. Document who can read and rotate the secret.
Verify the allowed actions succeed
From a pipeline job or a workstation with no personal credentials, the operator runs argocd app list and argocd app sync against an application the policy covers, passing the token through the CLI auth token option. The sync should complete and the app should show the expected revision. Check the audit or application events to confirm the actions are attributed to ci-deployer. A successful sync against an in-scope application is the evidence that the grant works.
Verify the denied actions fail
The same operator attempts actions the policy should block, such as deleting an application, syncing an application in another project, or creating a new application. Each request should return a permission denied error. Record each denial. If any out-of-scope action succeeds, remove the broader rule from policy.csv, reapply the ConfigMap, and repeat this check until every blocked action fails. This step produces the negative test results your reviewers will ask for.
Test revocation and disable the account
To revoke access, run argocd account delete-token --account ci-deployer with the token ID recorded at issue, then repeat the allowed sync from the earlier step and confirm it now fails with an authentication error. Revocation for a single token and disabling the whole account are separate actions: set accounts.ci-deployer.enabled to false in argocd-cm to block all tokens at once. Retest after each action and keep the results with the change record. Plan a rotation process so the token can be replaced without a gap in deployments.
How RBAC limits what a machine account can do
Before issuing any token to automation, review policy.default in argocd-cm, because a local account with no RBAC rules falls back to that default. Whatever policy.default grants to a role-less user is what a CI job inherits the moment its account exists and has an API key. Check the value in your cluster, confirm whether it is empty or set to a read-only role, and keep it at the most restrictive setting your teams can tolerate. Then write the account's own policy lines in argocd-rbac-cm so the machine account is limited to what its pipeline needs and nothing from the default is relied upon. Confirm the exact behavior of your installed version against the Argo CD user management guide before you rely on it.
Scope every automation permission to one project and its applications rather than to the whole instance. Policy lines in Argo CD name the project, the object and the action, so a deploy role for one team's project can sync and get applications in that project and nothing else. Use project roles from the Projects guide for token issuance, and bind each role to the account that will use it. Keep in mind that since Argo CD 2.14 to 3.0 the update and delete permissions apply only to the application itself, not to the resources it manages, so a sync role must be designed around that boundary. Log access is also separate: reading logs requires an explicit logs, get permission, so a pipeline that inspects failures will fail quietly until that line is added.
Test every permission before the token reaches a pipeline. Use the argocd account can-i command with the machine account to check each action it needs, such as sync, get, update and delete on a named application, and check that it is denied on applications in other projects. Run the same checks after each change to policy.csv, because a policy line that looks correct can still match the wrong object. Record the results so that a reviewer can see what the account was allowed to do at a given date. Confirm the command set and flags for your Argo CD version, since they vary between releases.
Security risks of tokens and how to control them
Every token issued for automation is a credential that can deploy to clusters, so its risks are the risks of any long-lived secret. The cards below pair each common failure with the control that limits it in an Argo CD installation you run.
Long-lived tokens copied into CI logs
A token pasted into a pipeline variable or echoed in a build step can be read by anyone with log access, and it stays valid until someone revokes it. Keep the token in a dedicated secret manager and inject it at runtime. Check that pipeline logs are masked for that variable and that no script prints the argocd command line with the token included. Argo CD redacts cluster, Git and OAuth2 credentials from API responses and logs, but that protection does not cover secrets your own scripts print.
Over-broad default policy
Local users without RBAC rules fall back to policy.default, so a misconfigured default can grant more than a pipeline needs. Keep policy.default empty or read-only, and grant each machine account explicit p lines scoped to one project and one set of actions. Review the argocd-rbac-cm ConfigMap after every change, and confirm with a test account that it cannot reach other projects.
Shared accounts across pipelines
When several pipelines share one local account, a leaked credential exposes all of them and audit logs cannot show which pipeline made a change. Create one account per pipeline or per deployment target, each with its own accounts.<name> entry and its own token. Keep account names within the 32-character limit so they remain readable in logs and reviews.
Built-in admin left enabled
The built-in admin user is meant for initial setup, and leaving it active gives a standing high-privilege login that automation tools may be tempted to reuse. After local accounts or SSO are configured, set admin.enabled to false in argocd-cm. Before doing so, confirm that a break-glass path exists in your runbook so you do not lock yourself out.
Tokens that outlive their project
A project token keeps working after the pipeline, team or project it served has been retired, unless someone removes it. Record each token's owner, purpose and project in your change inventory, and tie retirement steps to the decommissioning checklist. Revoke tokens with argocd proj role delete-token when a project is archived or a pipeline is removed, and confirm the token no longer authenticates.
Rotation and revocation discipline
Rotation replaces a token before it is exposed, and revocation removes it after exposure, so both need a defined owner and schedule. Issue a new project role token with create-token, update the secret store, verify the pipeline, and then delete the old token with delete-token. Ask your team to define a rotation interval in writing, because Argo CD does not set one for you.
Authentication limited to JWTs
Argo CD accepts API requests only with JSON Web Tokens, so every automation credential is a signed token rather than a password. Treat each token as a bearer secret: anyone holding it can act with its role. Confirm that your gateways and runners do not forward the Authorization header to logs or third-party services, and that API traffic uses TLS end to end.
Revoking and rotating tokens without breaking pipelines
Rotate a token by overlapping the old and new credentials, never by revoking first. The safe sequence has four steps: issue a new project role JWT with create-token for the same project role, update the CI secret that holds it, confirm that a pipeline run authenticates and syncs as expected, and only then revoke the old token with delete-token. Revoking first is the most common way a rotation breaks a deployment, because every job that still reads the old secret fails at its next sync. Record the token ID or issue date alongside the CI secret so the old token can be identified without guessing, and schedule the rotation so that no release window overlaps the cutover. Confirm the exact behavior of create-token and delete-token in your target Argo CD version, including how long an issued token stays valid and whether a revoked token is rejected immediately, before you rely on this sequence in production.
Revoking a single token and disabling the account behind it are different levers. Setting accounts.<name>.enabled to false in argocd-cm stops that local account from authenticating at all, which covers every token and login it holds, so it is the right response when a CI system is compromised or a service no longer exists. Revoking one token leaves the account and its other tokens in place. Decide in advance which response you will use for each scenario: rotation for routine hygiene, token revocation for a single leaked credential, and disabling the account when you need to cut off everything at once. Document the account owner and the pipelines that depend on it, because disabling an account that a production sync relies on stops deployments as well.
Test the whole procedure in a non-production Argo CD instance before the first real rotation. Rehearse issuing, updating a test pipeline, revoking and confirming the failure mode, and disabling and re-enabling an account, and record the results for your change records. Confirm the behavior against the Argo CD project documentation and the user management guide for your version, since token handling has changed across minor releases. If your team cannot run this rehearsal yourselves, ask your implementation partner to include it in the written scope and to show the results before go-live.
Limits to confirm in your environment
Local accounts and project tokens are easy to create and easy to forget. The checks below cover the settings and behaviors that decide how long a machine credential lives, how many of them a team can keep track of, and what the audit trail shows, so you confirm them against the docs for your version and your own test cluster.
Token lifetime and expiry settings
Confirm how long a project role JWT stays valid when you issue it with create-token, and whether you can set an expiry at creation time or must rely on a default. Check whether the expiry is enforced server-side for every API call and whether an expired token is rejected without a restart. Test this on the exact Argo CD version you run, because token behavior is one of the areas that changes between minor releases. Record the answer as a number you can cite in your access review.
Account and token volume per team
Ask how many local accounts and project tokens a single Argo CD instance can hold before listing, auditing or revoking them becomes slow for your operators. Count the machine identities you expect across pipelines, scripts and clusters, then decide whether each team gets its own account or shares one. Check whether issued tokens can be listed and matched to the pipeline that uses them, because an unlabeled token is hard to revoke with confidence.
CLI or raw API access for automation
Confirm whether your pipelines will call the argocd CLI or the HTTP API directly, since the authentication flow, token handling and error codes differ between them. Check that the account you create has the apiKey capability in argocd-cm and that the API token is passed the way your CI runner expects. Test a sync, a read and a denied action with the account so you know the RBAC rules behave as written before any pipeline depends on them.
Behavior when SSO is also configured
Confirm how local accounts behave once Dex or a direct OIDC provider is in place, including whether the login and apiKey capabilities still apply to the local account and whether the built-in admin account is disabled with admin.enabled set to false. Check that a local account with no RBAC rule falls back to the policy default, which may be broader than you expect. Verify that a disabled local account cannot obtain a new token while existing tokens behave as you documented.
Audit trail for machine actions
Confirm which events Argo CD records when a machine account syncs an application, creates or deletes a token, or fails authentication, and where those records go. Check whether the actor shows the account name or only a token identifier, and whether your log pipeline keeps those fields. Confirm that credentials are redacted from API responses and logs in your version, and that your retention period matches the evidence window your auditors expect.
Account name length and naming rules
Confirm that every planned local account name fits the documented limit of 32 characters, since longer names will not work and a rename later means recreating the account and its tokens. Agree on a naming pattern that shows the owning team and purpose, and check that your naming does not collide with existing human accounts. Record the list in the same place as your RBAC policy so reviewers can match each identity to an owner.
Questions teams ask before automating Argo CD access
How much effort does a secure Argo CD automation setup take?
The effort depends mostly on how many pipelines need access, how many distinct permissions each one needs, and how many Argo CD projects are involved. A single CI job that syncs one application is a small task. A setup where each team's pipeline gets its own local account, a scoped project role and a rotation routine is a larger one, because every account needs a policy, a secret store entry and a named owner. Ask any provider for a written breakdown by account, project and pipeline, and confirm whether the quote covers testing the revoke path as well as creation.
Can our team set up Argo CD automation accounts without outside help?
Yes, many teams can, provided someone already runs Argo CD and understands its RBAC model. The configuration itself is small: local accounts are defined in argocd-cm with the apiKey capability, and project roles can issue and revoke JWT tokens. The harder parts are reviewing the policy so automation cannot reach projects it does not need, wiring tokens into the CI secret store correctly, and building a rotation and revocation routine. If your team has no one who has worked with Argo CD RBAC before, an external review of the design is often the cheaper path. Confirm your own skills against this list before deciding.
What does the work need from our side?
Plan for three inputs before work starts:
- Argo CD admin access, or an admin who can apply changes to the argocd-cm ConfigMap and the RBAC policy in the cluster where Argo CD runs.
- A CI secret store, such as the one your pipelines already use, where tokens can be kept encrypted and read only by the jobs that need them.
- A named owner for every automation account, with an agreed place to record what the account does and who approves changes to it.
Also confirm who can revoke a token during an incident, because that person must be reachable outside business hours.
How long does a first automation pilot take?
No general duration is set here, because a pilot's length depends on how many pipelines are in scope, whether the identity model already exists, and how many approvals your change process requires. A reasonable pilot covers one pipeline, one project and one account, and proves four things: the account can sync what it should, it is denied everything else, the token is stored safely, and revoking the token stops access. Ask providers to state the pilot's exit criteria in writing, and check them against your own change calendar.
How do we stop token sprawl across many pipelines?
Token sprawl usually starts when every pipeline gets its own long-lived token and nobody records which token belongs to which job. Reduce it by creating one account or project role per purpose rather than per script, giving each one the narrowest project permissions, and naming tokens so an audit can match them to a pipeline. Disable local accounts you no longer use with accounts.<name>.enabled set to false, and keep a register of token issue and revoke events. Review the register on a fixed schedule, and treat any token without a known owner as a candidate for revocation.
Should automation use local accounts or SSO identities?
Use local accounts with the apiKey capability for machine access, and keep people on SSO. Local accounts are defined in argocd-cm with apiKey and login capabilities, and they fall back to policy.default when no RBAC rules exist, so every automation account needs explicit rules. Disable the built-in admin user with admin.enabled set to false once local users or SSO are configured, as the user management documentation recommends. Keep the login capability off for automation accounts so they cannot be used interactively.
What happens to automation when a token is revoked or an account is removed?
Pipelines using that token lose access immediately, so sync and deployment jobs fail until a new token is issued. Plan the cutover before revoking: issue the replacement, update the CI secret, run a test sync, then revoke the old token. Project tokens are revoked with delete-token, and disabling a local account stops every token it holds. Ask whether your provider's runbook covers emergency revocation during a suspected leak, and who approves it.
How DeployOpen scopes automation access for Argo CD
DeployOpen scopes automation access in writing before any account or token is created. The scope starts with an inventory of every pipeline, script and external system that will call the Argo CD API, including what each one needs to do (sync an application, read status, create a project token, or only fetch logs). The inventory also records where each caller runs, because a CI runner in the client's own network and a hosted build service need different credential handling. The output is a written list of machine identities, each with one owner, one purpose and one planned project, which becomes the basis for the quote and the build plan. All of this work runs inside the client's own Argo CD installation in their own clusters, and no credentials or accounts are created in a DeployOpen-hosted environment.
The design step turns that inventory into local accounts and project roles. Each machine account is defined in argocd-cm with only the apiKey capability, since it has no need to log in interactively, and the accounts.<name>.enabled setting is planned so that a retired pipeline can be switched off without deleting history. Access is granted through project roles, using the proj:<project-name>:<role-name> naming form, with create-token and delete-token kept to the few roles that truly need to issue or revoke tokens. The RBAC review then checks each policy line against the Argo CD 2.14 to 3.0 notes, where update and delete now apply only to the application itself and log access needs an explicit logs, get permission. Ask for the review to be run against the actual policy.csv before any token is issued, and confirm the policy.default value so an account without rules does not inherit more than intended.
Token storage, rotation and handover are written into the same scope. DeployOpen documents where each token is stored in the client's secret manager, who may read it, the rotation procedure for each caller, and the exact steps to revoke a token and confirm the caller has stopped working. The handover package includes the account inventory, role mappings, revocation runbook and a test checklist that the client's team can repeat. Ongoing support, including periodic RBAC reviews and token rotation, can be arranged as a retainer after handover, and the quote should state which of these items are one-time and which recur. Confirm with DeployOpen the timeline and the named owners before work starts, since those depend on the size of the pipeline inventory.

