You run one Argo CD instance for a dozen teams. How do you decide what each team may self-serve through projects and RBAC, and when would you give a team its own Argo CD instance instead?
answer
- the project is the tenant, and it is platform-owned
- rights inside a project versus rights over projects
- tokens scoped to a project role, never admin
- instances split trust, projects split authorization
basics
~20 sDelegate inside the AppProject and keep the project itself privileged: teams get project roles, tokens and sync rights over their own applications, while the platform owns project definitions and cluster registrations. A separate instance is warranted when the isolation or upgrade coupling of a shared control plane is unacceptable.
solid answer
~50 sThe design rule is that the AppProject is the tenant unit and its definition is a platform artifact. Teams get rights *inside* a project: `applications` actions scoped to `<project>/*` in `argocd-rbac-cm`, or roles declared in the project's own `spec.roles` with `proj:<project>:<role>` subjects, plus project-scoped tokens for their CI. What stays with the platform is `projects, update`, `clusters` and `repositories` — anything that could widen a fence or reach another tenant. Beyond that, decide two things deliberately: whether teams may author Applications at all or only receive them from a generated set, and how project definitions are reviewed, since they are the real security boundary. A separate Argo CD instance is worth its operational cost when a tenant must not share the control plane's credentials or blast radius — a regulated environment, an untrusted tenant, or a team whose upgrade and outage schedule cannot be coupled to everyone else's. The cost is real: more instances mean more upgrades, more SSO wiring and a fragmented view of the fleet.
go deeper
Know that a shared Argo CD instance separates teams with AppProjects and RBAC roles, not with separate installations, and that admin rights are not the normal grant.
Be able to describe the delegated set concretely — application actions scoped to the project, project roles, project-scoped tokens — and name what stays privileged, starting with editing projects themselves.
Show you have operated this: token issuance and revocation, disabling the local admin account after SSO, deciding on exec access, and keeping project definitions reviewed rather than hand-edited.
Own the split decision with named triggers — credential blast radius, upgrade coupling, scale — state the operational cost of each additional instance, and design how tenant projects are generated so policy changes land uniformly.
## The thing you are actually dividing An Argo CD instance holds credentials for every cluster it manages and applies whatever its repositories say. In tenancy terms it is a shared privileged actor. Multi-team design is the question of how much of that actor each team gets to steer, and the answer is expressed almost entirely through AppProjects and the RBAC policy. ## What is safe to delegate Self-service is worth designing for, because a platform team that hand-edits YAML for every tenant becomes the bottleneck GitOps was supposed to remove. Three things delegate cleanly: **Operating their own applications.** Grant `applications` actions — `get`, `sync`, `action/*`, `logs` — scoped to `<project>/*`. This is the daily work: see the diff, trigger a sync, restart a workload, read logs. **Defining their own sub-roles.** An AppProject's `spec.roles` lets the tenant express finer structure — an on-call role that may sync production, a read role for everyone else — and the mechanism is safe because a project role's policies can only reference objects inside that project. Bind those roles to identity-provider groups with the role's `groups` list rather than issuing credentials. **Automating from CI.** `argocd proj role create-token` issues a JWT bound to a project role, so a pipeline can trigger a sync without holding an admin credential. Give the token an expiry, record it in the project's `jwtTokens`, and know that deleting the entry revokes it — a project token is far better than the alternative you will otherwise find in a pipeline, which is the local `admin` password. ## What must not be delegated The complements of the above are exactly the things that let a tenant escape: - **`projects, update`** — the fence editor. A tenant who can widen `destinations`, `sourceRepos` or `clusterResourceWhitelist` has no fence. - **`clusters` and `repositories`** — registering a new cluster or a credentialed repository adds reach and secrets to the shared instance. - **`accounts` and the local `admin`** — disable `admin` once SSO works so every action is attributable. - **`exec`** — the ability to open a shell into a workload pod from the UI, which is genuinely useful and a genuine bypass of the deployment path; grant it deliberately, per project, or not at all. A related decision is `policy.default`. Leaving it empty denies unmatched users, which is right for a shared instance; setting `role:readonly` gives every employee a view of every tenant's applications, which some organisations want for transparency and others consider a leak. ## Making the fences maintainable A dozen hand-written AppProjects drift. Two habits keep them honest. First, keep project definitions in a repository with review rules of their own and apply them declaratively — they are control-plane configuration and deserve at least the review discipline of production code. Second, template them: projects for tenants that look alike should be generated from a small tenant record rather than copied, so that a policy change lands everywhere at once and an accidental `'*'` is visible as a diff. ## When one instance stops being right Projects give you authorization isolation, not failure or credential isolation. Split when: - **Credential blast radius is unacceptable.** A compromise of the shared instance reaches every registered cluster. If one tenant is regulated, externally operated, or genuinely untrusted, its clusters should not be registered next to everyone else's. - **Upgrade and outage coupling is unacceptable.** One instance means one upgrade window and one incident affecting every team's ability to deploy. Some organisations can absorb that; a tenant with a hard release calendar may not. - **Scale hurts.** A single instance reconciling many thousands of applications becomes an operational object in its own right, with its own tuning and its own noisy-neighbour effects between tenants. The cost is honest and should be stated: every extra instance is another SSO integration, another RBAC policy to keep consistent, another upgrade, and the loss of a single place to answer "what is deployed where". The usual landing point is few instances rather than one or many — commonly split along a trust or environment boundary, with projects doing the tenancy work inside each one. ## What a strong answer sounds like Name the AppProject as the tenancy unit and the split between rights inside a project and rights over projects. Give the concrete delegated set and the withheld set. Then treat the separate-instance question as a tradeoff with named triggers — credential blast radius, upgrade coupling, scale — rather than a preference, and admit the operational cost of the split you are proposing.
- How would you give a team's CI pipeline the ability to sync its own applications without an admin credential?Define a role in the team's AppProject whose policies cover only `<project>/*`, then issue a token for it with `argocd proj role create-token`, with an expiry. The token's subject is `proj:<project>:<role>`, so its reach is bounded by the project definition rather than by trust in the pipeline. Revocation is deleting the token entry from the project's `jwtTokens`.
- A team asks for permission to edit its own AppProject so it can stop filing tickets. How do you respond?Say no to `projects, update` and fix the underlying friction instead. Most requests are for a new namespace or repository, so template the projects from a tenant record the team can raise a pull request against, with the platform reviewing. They get self-service through review rather than through a permission that erases their fence, and the change is auditable as a diff.
saying these in an interview costs you the question
- Grants role:admin because per-project rules felt tedious
- Lets tenants edit their own AppProjects to avoid tickets
- Puts the local admin password into team CI pipelines
- Treats one instance per team as free isolation with no cost
- Assumes projects isolate failure and credentials, not just authorization