Argo CD RBAC for platform teams and application teams: what it controls
A platform team running one Argo CD for several application teams needs two things at once: enough access to administer the instance, and a way to keep each application team confined to the applications it owns. Argo CD RBAC answers the second need. The policy.csv file, usually held in the argocd-rbac-cm ConfigMap, governs which roles and SSO groups can act on which Argo CD resources. The resources it covers include applications, applicationsets, clusters, projects, repositories, accounts, logs, exec and extensions, and the actions include get, create, update, delete, sync, action and override. Group mappings from your identity provider are also bound to roles here, so a team's sign-in group can be tied to a role that only touches its own work.
Application permissions are written against the object's path, which takes the form <project>/<app>. That is why a rule can grant sync on team-a/* without granting anything on team-b. The project segment is the handle that ties RBAC to the AppProject boundary, so the two controls are designed to be used together. Note the 2.14 to 3.0 change: update and delete now apply only to the Application object itself, and access to pod logs needs an explicit logs, get permission. A policy written for 2.14 that relied on broader update or delete semantics should be reviewed before the upgrade, and teams should confirm their actual rule behavior in a non-production instance.
AppProjects alone restrict where an application can deploy from and to, but they do not decide which people can sync, roll back or view a given application. Add RBAC when different teams need different actions inside the same project, when platform engineers need administrative rights that application teams must not have, or when access to logs or exec must be granted or withheld separately. If every team has its own project and nobody needs more than the project's default rights, AppProjects may be enough. Before writing rules, confirm which SSO groups exist, which accounts are automation accounts, and which teams need rollback rights. The RBAC guide at the linked Argo CD documentation is the reference for exact resource names and action syntax.
Which RBAC rules fit which team role
This table compares five common Argo CD role patterns, showing the resources and actions each one grants, the project and application scope it should use, and when it fits or should be avoided. Read each row as a starting point, then test it against your own project layout and SSO groups before applying it. The main takeaway is that broad wildcards on applications or logs are the usual source of over-permission, so narrow the scope first and widen only when a team has a documented need.
| Role pattern | Resources and actions | Scope and when it fits or should be avoided |
|---|---|---|
| Platform administrator | Broad access to clusters, projects, repositories, accounts and applicationsets with get, create, update and delete | Global scope for a small platform group. Fits owners of Argo CD itself. Avoid granting it to application teams, since it can change projects and repositories for every tenant. |
| Application team with sync and rollback | Applications with get, sync and action, plus update or delete on the Application object only | Scope to one project and its applications, for example proj/team-a-*. Fits teams that deploy their own workloads. Avoid adding wildcard update or delete on child resources unless the team needs to fix drifted objects directly. |
| Team with read-only access | Applications and projects with get only, no sync, action or override | Scope to the team project. Fits auditors, support staff and other teams that need visibility without changing state. Avoid granting logs or exec here, since read access to the application tree is not the same as log or shell access. |
| CI or automation account | Applications with get and sync, scoped to a specific pipeline target, and no delete | Scope to one application or a narrow project pattern. Fits pipelines that trigger syncs after an image or chart update. Avoid sharing one account across teams, and confirm how its token is issued and rotated in your environment. |
| Team allowed to view logs or exec | Applications with get, plus logs with get, and exec with create when shell access is required | Scope logs and exec to a single project and namespace. Fits on-call engineers who need diagnostics. Avoid exec in production unless your change and audit process allows interactive access, and confirm the logs and exec rules against the RBAC guide for your Argo CD version. |
How to write and test policy.csv step by step
This sequence moves Argo CD from a bootstrap admin login to scoped team roles, with a check after each change so platform engineers can confirm that application teams sync and roll back only their own applications.
Confirm SSO or local users before touching admin
Before any policy change, the platform team confirms that every platform engineer and each application team can sign in through SSO or through a local account. Argo CD's user management guidance treats the built-in admin user as a setup tool, so this step is complete only when a named test user per team has logged in successfully. Then set admin.enabled to false in argocd-cm, and confirm that the admin login is refused while the named accounts still work. Keep a break-glass path documented and stored outside the cluster before you disable it.
Map SSO groups to platform and team roles
Platform engineers decide which identity provider groups map to Argo CD roles, and they add those mappings to policy.csv using group bindings such as g, followed by the group name and the role. Keep one group per team and one group for platform administrators so access can be reviewed in the identity provider. If you use bundled Dex, confirm the claim that Argo CD reads for RBAC, since the 3.0 upgrade notes say Dex-based RBAC uses the federated_claims.user_id claim. The check is a test login from one user in each group, followed by argocd account get-user-info showing the expected roles.
Define one role per team scoped to project apps
For each team, write a role that grants actions on applications using the object form <project>/<app>, so the rule covers only that team's project and its applications. Start with get and sync, and add rollback-related rights only where the team needs them. Plain update or delete on an application covers only the Application object, so do not grant wildcard application rights across projects. Bind the team's group to this role in policy.csv. The check is that the team's test user can sync an application in its project and is refused on an application in another project.
Add child-resource rules with the full resource path
Where a team needs to delete or update a Pod or other child resource, add a rule that uses the form <action>/<group>/<kind>/<ns>/<name>, for example a delete rule for Pods in the team's namespace. Keep the group, kind, namespace and name as narrow as the team's work allows, and use wildcards only where they are needed. Argo CD's RBAC guide explains that these rules are separate from the application-level rule. The check is that the test user can delete a Pod in the team's namespace and is refused the same action on a Pod in a namespace outside the team's scope.
Add deny rules for logs, exec and destructive actions
Add explicit deny rules for capabilities that a team should not hold, such as exec into containers or deletion of Application objects that belong to another team. Argo CD's RBAC guide states that deny always wins over allow, so a deny rule can override a broader grant elsewhere in the file. Logs access needs an explicit logs and get permission, so decide deliberately whether each team receives it. Confirm each deny with argocd account can-i and with a direct attempt from the test user, because a grant added later can still be overridden by the deny.
Verify each team with argocd account can-i
Run argocd account can-i against each test user for a matrix of actions and resources: sync and rollback on the team's applications, refused access to other projects, the allowed child-resource action, and the denied exec and logs requests. Record the output in your change record, and mark the step complete only when every expected result matches. Platform engineers should also confirm that a platform administrator can still manage projects and repositories, because a overly narrow policy can lock the platform team out of its own tooling.
Roll back a bad policy from version control
Keep policy.csv in Git and apply it through the same change flow as other Argo CD configuration, so every edit has a reviewed previous version. If a change blocks a team or grants too much, revert the commit and let the configuration reconcile, then rerun the can-i matrix against the reverted policy. If no one can sign in because of the change, use the break-glass path you documented in the first step to restore access, then fix the policy in Git. Confirm the rollback by repeating the verification step with all test users before closing the change.
Why plain update and delete do not cover child resources
A plain update or delete permission on an application covers only the Application object itself. It does not let a team delete the Pods, Deployments or other resources that Argo CD manages on its behalf. This matters most for the common day-two task of restarting a workload: a team that can sync its app but cannot delete a Pod will find that the restart fails with a permission error. To allow it, the platform team must add an explicit child-resource rule in policy.csv using the form <action>/<group>/<kind>/<ns>/<name>, for example delete/*/Pod/*/*. Deny rules always take precedence over allow rules, so a broader deny added later will override this grant.
The main design choice is how wide to make that rule. A wildcard such as delete/*/Pod/*/* is easy to write and keeps the policy short, but it lets the team delete any Pod that Argo CD tracks in any namespace the application's project allows, including Pods that belong to other workloads in the same destination. Narrowing the rule by kind, namespace and name reduces that exposure, for example by granting delete on Pod only in the application's own namespace, or by limiting the name pattern to the workload's label prefix. The trade-off is maintenance: narrower rules must be updated when workloads are renamed or move namespaces, and a rule that is too narrow will look like a broken sync to the team.
Before granting any child action, confirm with each application team which operations its workloads actually need, such as restarting Pods, deleting Jobs, or patching Deployments, and grant only those. The list is specific to each workload and is easy to get wrong from the outside, so ask the team to name the commands it runs and test each one against a non-production copy of the policy. Review the child rules whenever a team changes its deployment pattern, because permissions that were once needed can remain in place long after the workload stops using them.
Deny rules, exec and logs access: the controls that need extra care
Most Argo CD RBAC mistakes come from a few permissions that look harmless in a policy file. Deny rules, exec, logs and broad wildcards each reach further into running workloads than a reader might expect. Check each one against your own clusters before granting it to an application team.
Deny rules override every allow
In Argo CD, a deny entry always wins over an allow entry that matches the same subject and object. Use deny lines to carve exceptions out of a broad team grant, such as blocking deletion of Pods in a namespace an application team otherwise controls. Confirm in a staging instance that each deny line matches the object you intended, because a wildcard in an allow line can be narrowed only by a deny written with the same pattern.
Exec grants interactive shell reach
The exec resource lets a user open an interactive shell in a container that runs under an application's workload identity. That reach can expose secrets mounted into the pod, service account tokens and network paths the team did not design. Grant exec only to a named platform or on-call group, and confirm which namespaces and service accounts those workloads use before any application team receives the permission.
Logs access needs explicit get
Since the 2.14 to 3.0 upgrade, reading pod logs requires an explicit logs permission paired with get, so a team that can sync an app cannot automatically read its output. Logs often contain tokens, request bodies or stack traces with customer data. Ask your security team which teams need log access, and confirm that the policy grants logs with get only on the applications those teams own.
Applications, overrides and sync scope
Sync, action and override permissions change live state, and update or delete on an application affects only the Application object itself. Override lets a user change manifest values in place, which can drift from Git and bypass review. Decide which teams may sync and roll back, which may run resource actions, and which may override, and confirm that each grant names the project and application pattern it applies to.
Broad wildcards widen every grant
A wildcard in the project or application position, or a resource pattern like */*/*/*/*, can match far more objects than a team owns, including future applications nobody has reviewed. Replace wildcards with the project name and the application prefix, then test the result as the team's SSO user. Ask platform engineering to review any policy line that uses * in the object field before it reaches production.
Test each grant as the affected user
Policy text reads correctly far more often than it behaves correctly. Before a team goes live, sign in as a test user from that team's SSO group and attempt each allowed action and one denied action per resource type. Record the results alongside the policy version in Git so an auditor or an incident responder can see which grant allowed which action on which date.
Security and operational considerations for team RBAC
A policy.csv is only as safe as the accounts, grants and change path around it. The cards below cover the operational risks that sit alongside team RBAC in Argo CD, from the admin account and token model to wildcard grants, policy changes made through Git and the repo-server exposure that RBAC does not contain.
Admin account lifecycle
The built-in admin user is meant for initial setup. Once local users or SSO are configured, the Argo CD user management documentation recommends disabling it by setting admin.enabled to false. Before doing so, confirm that at least one platform engineer can sign in through SSO with an administrator role, and record who holds break-glass access and how it is audited. Review this setting after every upgrade and whenever the admin password is rotated, so a forgotten local login does not become a standing privileged path.
Wildcard grants on delete and exec
A wildcard in the object field, such as delete/*/Pod/*/* or an exec rule granted to a broad role, lets a team act on every matching resource in every application it can reach. Because exec and logs reach into running workloads, they deserve narrower grants than sync or get. Write each grant against a specific project and application, and review every line that uses * for action, object or resource. Confirm with a test account that a team role cannot exec into another team's pods before you rely on the policy.
Policy changes through Git
Argo CD stores RBAC rules in the argocd-rbac-cm ConfigMap, so a change to policy.csv is a change to cluster state. Keep the file in a Git repository with branch protection, required reviews by the platform team and a pull request history that answers who changed which grant and when. Apply the file through Argo CD itself only if the team has confirmed that a bad change cannot lock out administrators. Ask your auditors which evidence they expect from this trail before the first review.
JSON Web Tokens for API access
The security documentation states that Argo CD authenticates API requests only with JSON Web Tokens. Tokens issued to CI jobs and automation accounts therefore carry the same authority as the account behind them, and RBAC decides what they can do. Define which accounts may generate tokens, keep automation accounts in their own roles, and confirm how token expiry and revocation are handled in your environment. Test that a token issued to one team's pipeline cannot read another team's applications.
Repo-server exposure to untrusted repositories
The repo-server runs Helm and Kustomize against repository content, and the security documentation identifies untrusted repositories and out-of-tree file access as a risk to control. RBAC limits who can sync an application, but it does not stop a manifest from a permitted repository from running build tooling against the repo-server. Restrict which repositories each project can use, review Helm and Kustomize configuration for out-of-tree references, and treat the repo-server as a component that needs its own network and hardening controls.
Limits to confirm in your environment before rollout
Which resource and action names apply to my Argo CD minor version?
Confirm the exact resource and action names against the RBAC configuration documentation for the minor version you run before you write any rule. The documented resources include applications, applicationsets, clusters, projects, repositories, accounts, certificates, gpgkeys, logs, exec and extensions, and application objects are written as <project>/<app>. Names and behavior can change between minor releases, so a rule that worked in a test cluster on one version may silently match nothing on another. Keep a short test matrix per version and run it each time you upgrade. Read the RBAC configuration documentation for the version in use, not a copy from memory or an older blog post.
How do I test Dex claim mapping on my identity provider?
Test the mapping with real accounts from each group before you rely on it. Since Argo CD 3.0, Dex-based RBAC uses the federated_claims.user_id claim, so the value your identity provider sends must match the subject you reference in policy.csv. Log in as one user per team, check the claims Argo CD receives, and confirm that each user gets only the roles you intended. Also test a user who belongs to no group and a user who belongs to two groups, because those cases often expose gaps. Review the SSO and user management documentation for the connector you use, and confirm the claim names with your identity team.
Which patch line should my Argo CD environment run?
Pick the patch line that your current minor version belongs to and confirm it is still receiving patches. The project publishes patch releases for only the three most recent minor versions, and the published releases on October 12, 2026 were v3.5.5 (marked latest), v3.4.11 and v3.3.16, with v3.6.0 in release candidate. Check the release process and cadence for the current support window, and check the GitHub releases page before you schedule a change. Plan the upgrade to a supported minor version before the line you run drops out of the window, and retest your RBAC rules on the new version.
How are ApplicationSets and cluster-scoped resources governed by RBAC?
Treat ApplicationSets and cluster-scoped resources as separate permission surfaces that need their own rules. ApplicationSets are a distinct resource in the RBAC model, so a team allowed to sync applications is not automatically allowed to create or change ApplicationSets that generate many applications. Cluster-scoped resources are governed through the clusters resource and through the project allow lists for cluster resources, so check both. Confirm with a test that an application team cannot create an ApplicationSet that targets namespaces or clusters outside its project. Ask your platform team which roles may create ApplicationSets, because a single generator can produce applications across several teams.
Could AppProject roles and policy.csv conflict with each other?
Yes, they can. Project roles and global RBAC rules both grant permissions, and deny rules always win over allow rules, so a broad global allow can be overridden by a project-level or specific deny, and a forgotten global allow can grant more than the project intended. Before rollout, list every role defined in each AppProject, list every group mapping in policy.csv, and check each team's effective permissions with a test account. Confirm that the team role granted through a project does not also get platform actions through a global group. Keep both files in the same Git repository so changes are reviewed together.
Does the team rollback permission include child resources like pods?
No. Plain update or delete on an application covers only the Application object itself, so a team that can sync and roll back does not automatically gain the right to delete a pod or other managed resource. Child resources use the form <action>/<group>/<kind>/<ns>/<name>, for example delete/*/Pod/*/*, and you must grant those explicitly if teams need them. Logs access requires an explicit logs and get permission. Test each child action you grant, because a wildcard that is too broad or a name pattern that is too narrow will not behave the way the label suggests.
Who should confirm these limits before a rollout starts?
The platform team that owns the Argo CD installation, the identity team that owns the provider, and a security reviewer should confirm them together before rollout. DeployOpen can plan and implement RBAC design, test the rules against your identity provider and clusters, and document the result as part of a fixed-scope engagement, with scope and deliverables agreed in writing first. Your team keeps ownership of the identity provider, the groups and the production clusters. Ask any partner to show the test cases for each rule, the version they tested against, and how changes will be reviewed after handover.
How DeployOpen scopes an Argo CD RBAC engagement
An Argo CD RBAC engagement starts with a written scope agreed before any policy changes. That scope names the teams, the clusters and AppProjects in play, the SSO groups that will map to roles, and the actions each team must perform, such as syncing and rolling back their own applications. It also states what stays with platform engineers, including the admin account and the policy.csv file itself. Because most engagements are fixed-scope, the deliverables and the acceptance checks are written down at this stage so both sides know when the work is finished. Before writing any rule, DeployOpen reviews the current policy.csv, the policyDefault setting, the existing SSO group names, and whether the built-in admin user is still enabled, since the user management documentation recommends disabling it once SSO or local users are configured.
The core of the work is a role model per team, drafted from the scoped actions and then translated into p and g lines. Platform roles receive administrative resources such as clusters, repositories and projects. Application team roles receive applications permissions limited to <project>/<app> objects, and child resource rules such as delete/*/Pod/*/* only where the team needs them. Deny rules and logs and exec access are decided explicitly, because deny always wins over allow and the 2.14 to 3.0 upgrade notes changed how update and delete apply to child resources. Each rule is then tested with dedicated test accounts, one per role, that confirm both what is allowed and what is refused. The reader should confirm which Argo CD version is in use before drafting, because these semantics differ between releases.
The engagement ends with handover documentation covering the role model, the rule rationale, the test cases with expected results, and the procedure for adding a team or changing a group mapping. Ongoing changes, such as onboarding new teams, adjusting roles after an Argo CD upgrade, or re-running verification after a release, can be covered by a retainer rather than a new project. Teams evaluating a partner should ask for the scope document, the list of test cases, and how each change is reviewed before it reaches argocd-rbac-cm. The Argo CD RBAC configuration guide is the reference to check each planned rule against.
How DeployOpen delivers Argo CD RBAC for your teams
DeployOpen plans, implements, tests and documents Argo CD RBAC inside your own clusters and identity setup, so platform engineers keep administrative control while application teams sync and roll back only their own applications. Each engagement starts from a written scope that names the teams, roles, projects and clusters involved.
How we scope
- Map each platform and application team to the Argo CD actions and resources it needs, such as sync, action and logs access.
- Agree in writing which SSO groups or Dex claims map to each role before any policy.csv is written.
- Confirm the Argo CD version in use, since RBAC behavior changed in the 2.14 to 3.0 upgrade.
How we build
- Write policy.csv and scopes.csv entries per team, with explicit deny rules where a team must not act.
- Test update, delete and child-resource permissions with test accounts against sample applications before rollout.
- Verify that exec and logs access are granted only where the scope calls for them and nowhere else.
How we hand over
- Deliver the policy files, role mapping, test cases and results, and a change procedure for adding teams.
- Document which permissions cover only the Application object and which cover child resources, with examples.
- Walk platform engineers through the review steps they will repeat when a team asks for new access.
How we support
- Engagements are fixed-scope, with scope, deliverables and timelines agreed in writing before work starts.
- Ongoing support, upgrades and continuous testing are available as a retainer for RBAC changes after handover.
- A quote follows from the written scope, so your team can compare DeployOpen against building the policy in-house.

