Argo CD projects for team isolation: what they bound and when you need them
A platform team running one Argo CD for several product teams needs a way to say which repositories each team may deploy from, which clusters and namespaces it may deploy to, and which kinds of cluster-scoped resources it may create. An AppProject is the Argo CD object that holds those boundaries. Each Application belongs to exactly one project, and the project decides whether that Application's source repository, destination cluster and namespace, and resource kinds are allowed. Once more than one team shares an instance, this is the layer that stops a team from pointing an Application at another team's repository or namespace, or from creating a ClusterRole through its own manifests. Without projects, every team's Applications effectively inherit the permissions of the whole instance.
Projects bound what an application may do, but they do not decide who may act on it. That job belongs to Argo CD RBAC and to the identity provider behind it. A user can be allowed to sync an Application in a project and still be denied the ability to create one, and project roles can be bound to SSO groups so that the team's group receives sync rights for its own project only. Keep the two layers separate in your design: projects define the blast radius of a deployment, and RBAC and SSO define who can trigger one. Treat the project allow and deny lists as the control you review when a team asks for a new repository or cluster, and make sure your access model is written down before the first team is onboarded. The Argo CD user management documentation is the natural next read for the RBAC and SSO side.
Every Argo CD installation also ships with a built-in project named default, and by default it permits any source repository, any destination and any resource kind. Any Application created without a project lands there, so the default project quietly undoes the boundaries you set elsewhere. Before onboarding teams, empty the default project's source repositories and destinations so that every Application must belong to a deliberately scoped project. Then confirm in your own environment that a test Application created without a project is rejected. Check the exact fields in your installed version, because the behavior and the places where settings live changed across recent releases, and confirm the current minor versions receiving patches on the Argo CD release process page before you commit to a version.
Which project fields draw the boundary for each team
An AppProject sets the outer edge of what a team's applications may do. Each field below closes one part of that edge, and a project that leaves any of them open still lets a team reach something it should not. Check them together, because a tight source list does not help if the destination is wide open.
Source repositories
The sourceRepos list controls which Git repositories an application in the project may read from. Each entry is a repository URL or a wildcard pattern, and an empty list blocks everything. The risk when this field is left open is that any team can point an application at a repository it does not own, including one that holds Helm charts or Kustomize overlays that run code in the repo-server. Use exact URLs for team repositories and treat wildcards as an exception that needs a reason.
Destination clusters and namespaces
The destinations list pairs a cluster with a namespace pattern, so an application can deploy only where the pair matches. A destination entry with a wildcard namespace lets a team create workloads in another team's namespace on the same cluster. Confirm that each entry names both the cluster server or name and a namespace pattern, and check that no entry matches * for either value unless a platform team has approved it.
Cluster-scoped resource lists
The clusterResourceWhitelist and clusterResourceBlacklist fields govern cluster-wide kinds such as Namespace, ClusterRole and CustomResourceDefinition. Left open, a team can create cluster roles that grant more access than its namespace should have, or register new CRDs that change the cluster for everyone. Keep the allow list short, typically limited to the few cluster-scoped kinds the team truly needs, and confirm the deny list covers RBAC objects you do not want delegated.
Namespace-scoped resource lists
The namespaceResourceWhitelist and namespaceResourceBlacklist fields control which kinds an application may create inside its destination namespaces. Without them, a team can add Roles or RoleBindings that widen its own access, or create resources such as NetworkPolicies that other workloads depend on. Decide which kinds the team's applications need, then block the ones that alter access or networking unless a platform owner reviews them.
Project roles bound to SSO groups
Project roles set who can sync, override or roll back applications inside a project, and they can map to identity provider groups through the project's group bindings. A role left with broad actions can let a user in one team act on another team's applications, and a group mapping that matches too many people spreads that access. Map each role to one named group, grant the smallest set of actions, and review the bindings whenever team membership changes.
Project configuration options and when each one fits
This table compares the main ways to shape AppProjects, from one project per team to shared platform projects and allow lists against deny lists. Read each row for the isolation it gives, the upkeep it adds and the team shape it suits. The main takeaway is that tighter boundaries cost more to maintain, so match the number of projects to how independently teams actually ship.
| Option | Isolation it gives | Operational cost and team shape |
|---|---|---|
| One project per team | Each team's applications draw from its own repositories and namespaces, with no sharing of sources or destinations across teams | Lowest number of projects to maintain. Suits one team per product area with a single release cadence and little need for environment-level controls |
| One project per team and environment | Production and non-production deployments are separated, so a team's staging credentials or sources cannot reach production destinations | More projects and more policy to keep in step. Suits regulated teams that need change control or separate approval paths for production |
| Shared platform project | Cluster add-ons and shared infrastructure are managed under a project that application teams cannot change | Platform engineers own it and must review every addition. Suits platform teams deploying ingress, monitoring or policy controllers used by several teams |
| Allow lists for sources and destinations | Only the repositories, clusters and namespaces named in the project are permitted, so new entries are denied by default | Each new repository or namespace needs a project change first. Suits environments where repository and namespace inventory is controlled and changes are reviewed |
| Deny lists for sources and destinations | Broad access is kept, with specific repositories or namespaces blocked, so gaps depend on the blocks being complete | Lower day-to-day friction but a larger risk of unexpected reach. Suits short transitional periods rather than long-term tenant isolation |
| Allow lists for cluster-scoped resource kinds | Only named cluster-scoped kinds, such as namespaces or custom resource definitions, can be created through the project | Platform owners must approve each kind a team needs. Suits shared clusters where teams should not create cluster-wide objects |
| Deny lists for cluster-scoped resource kinds | Most cluster-scoped kinds are allowed, and only listed kinds are blocked | Easy to start with but new kinds added by a cluster's CRDs are allowed unless someone adds them to the block list. Confirm the behavior for your Argo CD version in the project documentation |
When global projects help and why the default project must be emptied
A global project in this context is an AppProject that holds policy shared across many teams, such as the repositories, clusters and namespaces that every team consumes from a platform group. Its value is that the shared rule is written once. Its risk is that it grows into a catch-all: each new exception gets added to the global project because it is the quickest place to put it, until a rule meant for common platform resources also lets an application team deploy anywhere. Keep the membership of a global project small and owned by the platform team, review every addition to its source and destination lists, and treat it as the place for platform resources only, not as a fallback for application workloads.
The default project is different because it is created automatically and, out of the box, permits any repository, any destination cluster and any resource kind. An application created without a project, or one that a user assigns to default, inherits that unrestricted scope. That makes the default project the most likely route around every boundary you set, which is why it must be emptied before team projects go live. Emptying means removing the permitted sources and destinations so that no application can sync through it, which forces each application into a deliberately scoped project. Confirm in your own instance which applications currently reference default before you change it, since those applications will stop syncing once the project is emptied.
The procedure for emptying the default project, including how to find affected applications and how to move them, is covered in Locking down the Argo CD default project. Plan that change as a separate step with the platform team, and check the current Argo CD user management documentation for how project roles and SSO groups interact with the projects you create, so the lockdown and the team projects are validated together.
Setting up Argo CD projects for each team, step by step
This sequence turns a shared Argo CD instance into a set of team boundaries, where each AppProject limits what a team can pull from Git, where it can deploy and which resource kinds it can create.
Inventory repositories, namespaces and clusters per team
The platform lead and each team lead list the Git repositories that hold each team's manifests or charts, the namespaces the team deploys into, and the clusters those namespaces live on. Include shared repositories, such as a common Helm chart library, as separate entries so they can be allowed explicitly. Write the list down per team, because every later step derives from it. The step is done when each team has a list that names every source URL, every destination server and namespace pattern, and any cluster-scoped resource kinds it expects to create, such as CRDs or namespaces. If a team cannot name a resource kind, ask them to check their existing manifests before continuing.
Empty the default project
The platform team edits the built-in default project so it no longer permits any repository, destination or resource kind. This is the project every application falls back to when no project is named, so leaving it open lets a misconfigured application bypass team boundaries. Confirm the current contents of the default project before changing it, and move any existing applications that depend on it into a team project first. The check: a new Application that names no project should be rejected by the API, and the default project should show no permitted sources or destinations in the UI or CLI output. The full procedure is covered in the sibling topic on locking down the default project.
Create one AppProject per team with explicit sources and destinations
Using a declarative AppProject manifest stored in the platform Git repository, the platform team creates one project per team. Under spec.sourceRepos, list only that team's repository URLs, and under spec.destinations, list each allowed cluster server and namespace, avoiding wildcards where the team's namespaces are known. Keep the manifests in a repository the application teams cannot write to, so a team cannot widen its own project. The check: running argocd proj get on each project should show the expected repositories and destinations, and an Application pointing at another team's repository should show as not permitted when validated against the project.
Add cluster and namespace resource allow lists
Set the project's cluster resource allow list and namespace resource allow or deny lists so the team cannot create cluster-scoped objects it does not own, such as ClusterRoles, CustomResourceDefinitions or Namespaces, unless the platform team has agreed to them. Use the namespace resource lists to limit kinds inside the team's namespaces where your policy requires it. Confirm the exact field names against the Argo CD version you run, because the project schema has changed across releases. The check: a test manifest with a disallowed cluster-scoped kind should appear in the application's sync status as blocked by the project, with an error message naming the resource kind.
Bind project roles to SSO groups
Define project roles in each AppProject and map them to identity provider groups through the Argo CD RBAC configuration, so membership in a team group grants sync or get rights only inside that project. Decide with the identity team which group claim carries the membership, and confirm how your chosen SSO path, bundled Dex or a direct OIDC provider, exposes it. Argo CD 3.0 changed Dex-based RBAC to use the federated_claims.user_id claim, so check your version's upgrade notes before writing mappings. The check: a test user from each team should be able to list and sync applications in their own project and should receive a permission error for applications in another team's project.
Create applications inside each team project
Each team creates its Application resources with spec.project set to its own project name, either by hand, through the team's Git repository, or through an ApplicationSet that is restricted to that project. Confirm that no Application in the cluster references the default project. The application should sync normally from an allowed repository into an allowed destination, which proves the boundaries accept legitimate work. The check: argocd app list should show each application under its team project, and an automated sync of a valid manifest should finish with a healthy status.
Test that disallowed sources, namespaces and kinds are rejected
Before the projects go live, the platform team runs a negative test set. Create a throwaway Application in a team project that points at a repository not on the allow list, then one that targets a namespace outside the project's destinations, then one that includes a cluster-scoped kind the allow list excludes. Run each through a sync and record the result. Delete the test applications afterward. Each attempt should be refused with a message that names the project rule it broke, and no resources should appear on the cluster. The step is complete when all three rejections are recorded and the results are kept with the project manifests as evidence of the configured boundary.
Risks that project boundaries do not cover
An AppProject limits where an application can pull from and deploy to, but it does not control what the repo-server executes, what the controller can change cluster-wide, how people sign in, or where credentials end up. Each card below names a risk that sits outside project boundaries and the control that addresses it.
Untrusted repository content
The repo-server runs Helm and Kustomize against repository content, so a chart or overlay can influence what gets rendered and whether files outside its directory are read. A project that allows a repository is still exposed if that repository is not trusted. Check which repositories are allowed, who can merge to them, and whether out-of-tree file access is restricted. Review the repo-server controls in the security hardening topic before opening new sources.
Broad controller cluster permissions
The application controller applies manifests with the privileges granted to its cluster registration. A project can restrict which cluster resource kinds an application may create, but the controller's own role determines the ceiling. Confirm that each destination cluster is registered with the narrowest role that still supports the teams' workloads, and that cluster-scoped kinds are allowed only where a platform owner has approved them. The least-privilege access topic covers this in detail.
Built-in admin user left enabled
The built-in admin account bypasses SSO group mapping and project-based RBAC, so a team that signs in with SSO can still be overridden by a shared password. The user management documentation recommends using admin only for initial setup and disabling it by setting admin.enabled to false once SSO or local users are in place. Confirm the setting after every upgrade and record who holds break-glass access. The security hardening topic describes admin and RBAC defaults.
Credentials exposed in Git
Project scopes do not stop a cluster token or repository password from being committed to a repository that a team can read. Argo CD redacts credentials from API responses and logs, but that protection does not cover files in Git. Store cluster and repository secrets as labeled Kubernetes Secrets, scope repository credentials to projects where possible, and scan commits for tokens. The secrets management and declarative secrets topics explain the patterns.
Unscoped API access
Argo CD authenticates API requests with JSON Web Tokens, so anyone holding a valid token can call the API within the permissions their role grants. Project roles limit application actions, but tokens issued to automation can outlive the person or pipeline that created them. Review which accounts can generate tokens, set expiry on automation tokens, and remove unused accounts. Confirm this in the RBAC topic for platform and application teams.
Changes to the default project
The default project permits any repository, cluster and resource kind, so an application that is not assigned to a scoped project can bypass team boundaries entirely. Project boundaries only hold if every application belongs to a scoped project. Check for applications still in default, and review who can edit the default project itself. The topic on locking down the default project shows how to empty its sources and destinations.
What to confirm for your Argo CD version and environment
Project behavior, RBAC and repository definitions changed across recent releases, so start by confirming that your running minor version still receives patch releases. The release process states that a minor release ships four times a year and that only the three most recent minor versions receive patches, so the supported lines move every quarter.
- Minor version line: Identify the exact minor version you run and check that it is one of the three most recent lines in the release process documentation.
- Patch level: Compare your patch version with the latest release in its line on the GitHub releases page. The patches published on October 12, 2026 were v3.5.5, v3.4.11 and v3.3.16.
- Upgrade path: If you run a release from 2.14 or earlier, confirm how the 2.14 to 3.0 upgrade notes change your RBAC rules and where repositories are defined before you rely on any project policy.
- Pre-release status: v3.6.0 was in release candidate at that date. Confirm whether your plan depends on it, and wait for the stable release notes before you build on it.
Check the version against the release process page and the GitHub releases page on the day you plan the change, because the supported lines change each quarter.
Whether Argo CD runs cluster-wide or inside a single namespace determines which destinations a project can reach and whether a team can see cluster-level resources. Confirm the install scope before you write AppProjects, because a project cannot grant rights that the Argo CD installation itself lacks.
- Install scope: Confirm whether the controller and API server have cluster-level permissions or only permissions within one namespace.
- CRD ownership: Confirm who installs the Application, AppProject and ApplicationSet custom resource definitions, and whether a tenant team is allowed to change them.
- Reachable destinations: Confirm which clusters a namespace-scoped instance can deploy to, and whether it can manage the cluster it runs in at all.
- Cluster-scoped features: List the features and resource kinds your teams need, such as cluster-scoped objects, and confirm in the installation documentation for your version which of them require a cluster-wide install.
- Shared projects: Confirm whether projects created by a platform team are visible to a namespace-scoped instance, and who may edit them.
Check these answers against the installation documentation for your version, then test one project on a non-production cluster before any team depends on it.
With direct cluster registrations, each managed cluster becomes a destination that a project must explicitly allow, and each registration holds credentials that Argo CD uses to reach that cluster. Confirm how every registration is created, what identity it uses and which projects may deploy to it, because a single broad destination can undo the isolation you designed.
- Registration method: Confirm whether each cluster is registered by command or by declarative Secrets, and who is allowed to create or change those Secrets.
- Credential type and lifetime: Confirm whether each registration uses a short-lived identity issued by the cloud provider or a long-lived static token, and how and when it rotates.
- Destination allow lists: Confirm that each project lists only the cluster and namespace pairs its team owns, and that no project is left with an open destination.
- Repository credentials: Confirm that repository definitions are stored as Kubernetes Secrets, as required since 3.0, and that each credential is scoped to the project that uses it.
- Group mapping: Confirm that the same SSO group claims map to the same project roles on every Argo CD instance in the fleet.
Check each registration and its credential type against your cloud provider's identity documentation and the Argo CD security documentation before you add the next cluster.
How much effort do Argo CD projects for team isolation take, and what do we provide?
What drives the effort of designing Argo CD projects for team isolation?
The main drivers are the number of teams, clusters, repositories and namespaces that need separate boundaries, plus how many existing applications must be assigned to projects. Each team adds a project to design, a set of allowed source repositories, allowed destination namespaces and clusters, and an explicit list of cluster-scoped resource kinds. Each cluster adds registration and allow list work. Each repository that holds applications must be mapped to exactly one owner. Ask for a written scope that counts these items so the quote matches your environment rather than a generic setup.
Can our own platform team set up Argo CD projects without outside help?
Yes, a platform team with Argo CD and Kubernetes experience can write AppProject manifests itself, and the work is mostly declarative YAML kept in Git. The harder part is agreeing on ownership: who decides which team gets which repository and namespace, and who approves changes to project rules. An outside partner typically adds value by reviewing the boundaries, testing that a team cannot deploy outside its scope, and documenting the result. Confirm internally whether your team has time to test deny cases and to handle the default project, since those checks are where gaps tend to appear.
How long does a project isolation engagement take, and what sets that duration?
Duration depends on the number of teams and clusters, how clean the repository structure is, how many applications already run in the default project, and whether SSO groups already exist. Work usually includes inventory, project design, SSO group mapping, migration of existing applications, negative testing and handover. Teams with many shared repositories or unclear ownership spend more time agreeing on boundaries than writing manifests. Ask any provider for a timeline tied to the written scope and to the number of teams and clusters in it, and confirm the review and sign-off steps your organization requires.
What must our organization supply before project design starts?
You need to provide a team inventory with each team's repositories, target clusters and namespaces, and the name of an accountable owner for each. You also need the identity group names used by your SSO provider, the list of people allowed to administer Argo CD, and a decision on who approves changes to project definitions. Confirm which namespaces each team owns, since namespace ownership determines the allowed destinations. If your change control process requires a formal approval record, agree on that path before work begins so the delivered configuration can be reviewed.
What happens to existing applications in the default project?
Applications in the default project keep running, but the default project is permissive by design, so it allows any source repository, destination and resource kind unless it has been restricted. Moving those applications into scoped projects is a planned change, not an automatic one. Each application must be reviewed for its repository, destination cluster and namespace, and any resource kinds it uses. Applications with cluster-scoped resources or shared repositories need extra attention. Plan the move in stages and verify each application still syncs after its project changes, so production deployments are not interrupted.
Which parts of the project design carry the most risk if they are misconfigured?
The highest-risk settings are source and destination allow lists, cluster resource allow lists, and project roles tied to SSO groups. A wide source pattern can let one team deploy from another team's repository, and a broad destination can let a team write to a namespace it does not own. Cluster-scoped resource allowances are especially sensitive because they can affect the whole cluster. Project roles bound to groups grant sync and override rights, so a mistake in group names can expose more access than intended. Test each deny rule with a non-privileged account before relying on it.
How do project boundaries support audit and change control evidence?
Project definitions, RBAC policies and sync controls are stored as Kubernetes objects and, when managed through Git, carry a change history that auditors can inspect. Clear project boundaries show which team may deploy to which namespace and from which repository, which supports change management and access review. These records are evidence that you prepared the controls. Independent auditors and certification bodies decide whether the controls meet a given requirement, so confirm the specific evidence your assessor expects before designing the review trail.
How DeployOpen scopes, delivers and supports team isolation
DeployOpen plans, builds, documents and supports Argo CD in your own infrastructure, including the AppProject boundaries that keep each team inside its repositories, namespaces and cluster resource rules. Each engagement starts from a written scope, so the project model, SSO group mapping and handover material are agreed before any configuration changes.
How we scope
- Inventory which teams, repositories, destination namespaces and clusters each AppProject must cover before writing any rules.
- Agree in writing which source and destination allow and deny rules, cluster resource allow lists and global projects are in scope.
- Map which SSO groups from your identity provider or bundled Dex will bind to each project role, and confirm the claim each group comes from.
How we build
- Lock down the default project and create scoped AppProjects in a non-production Argo CD instance first, then test each boundary.
- Test negative cases such as an out-of-scope repository, a foreign namespace and a denied cluster resource kind to confirm rules block them.
- Define repository and cluster credentials as Kubernetes Secrets and check that project scope is applied to each one.
How we hand over
- Deliver project manifests, the RBAC mapping and a test log showing which boundaries were verified and how to reproduce each check.
- Document the change process for adding a team, repository or namespace, including who approves a new project and who applies it.
- Walk platform and team leads through day-to-day project administration so changes go through Git rather than manual edits in the UI.
How we support
- Ongoing support, upgrades and continuous testing are available as retainers, so project rules can be reviewed as teams and clusters change.
- Retainer work can cover re-testing project boundaries after each Argo CD minor release, since only the three most recent minor versions receive patches.
- Ask any provider to confirm response expectations and upgrade handling in the written agreement before work begins.

