Skip to main content
Cloud DevOps Solutions
Get a quote Talk to an engineer

GitOps / Helm / ArgoCD

Designing RBAC So Developers Deploy Without kubectl Access

GitOps RBAC means developers change production by merging pull requests, while the cluster controller holds the credentials that apply changes. We configure ArgoCD projects and policies or Flux tenancy, tie them to your identity provider, and restrict direct kubectl write access to emergencies.

Key takeaways

  • In GitOps the git repository becomes the control plane, so branch protection and code owners are part of your RBAC, not an extra.
  • ArgoCD AppProjects and Flux service account impersonation limit what each team's deployments can touch.
  • Group-based access from your identity provider beats individual accounts in every tool.
  • Remove routine write access to clusters, but keep an audited break-glass path for incidents.
  • Cluster read access and log access can stay generous, since debugging does not require write rights.

The problem GitOps RBAC solves

Teams adopt GitOps and keep the old habits. Deployments come from git, but twelve engineers still hold cluster-admin “just in case”. Someone edits a Deployment by hand during an incident, the controller either reverts it or, worse, has self-heal switched off and the change lingers. The audit trail says one thing, the cluster says another.

The goal of GitOps access control is simple to state: developers can ship to production quickly and safely, and nobody needs routine write access to the cluster to do their job. This page describes how we build it within our GitOps, Helm, ArgoCD and Flux service. It works alongside a good repository structure, because folder boundaries become permission boundaries.

What good looks like

  • Production changes arrive only by merged pull request with the right reviewers.
  • Each team can deploy to its namespaces and nowhere else, enforced by the controller and not by trust.
  • People log in through your identity provider, with groups driving roles.
  • Humans have read and diagnostic access, and a break-glass route for real emergencies.
  • Every elevated action leaves a record someone can find.

The three layers

LayerQuestion it answersMechanism
GitWho can propose and approve a change?Branch protection, CODEOWNERS, required reviews
GitOps controllerWhat may this team’s apps deploy?ArgoCD AppProjects and RBAC policy, Flux tenant service accounts
KubernetesWhat can a person do directly?Roles, bindings, SSO group mapping, policy engine

Teams usually configure one layer well and forget the others. A strict ArgoCD project means little if the same engineer can push to the production folder without review, or hold an admin kubeconfig.

How it works in practice

Scoping teams in ArgoCD

An AppProject restricts repositories, destinations and resource kinds. This example gives a payments team a namespace-bound project and blocks cluster-scoped resources:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: payments
  namespace: argocd
spec:
  sourceRepos:
    - https://github.com/example-org/gitops-config.git
  destinations:
    - namespace: payments-*
      server: https://kubernetes.default.svc
  clusterResourceWhitelist: []
  namespaceResourceBlacklist:
    - group: ""
      kind: ResourceQuota
  roles:
    - name: deployer
      policies:
        - p, proj:payments:deployer, applications, sync, payments/*, allow
      groups:
        - payments-engineers

The group name comes from your identity provider through OIDC, so joining or leaving the team changes access with no ArgoCD edits. Policy lines in the global argocd-rbac-cm set the default role to read-only, so a new user starts with the least privilege.

Scoping teams in Flux

Flux applies manifests using its own service account unless told otherwise. For multi-tenant clusters we set serviceAccountName on each tenant’s Kustomization so reconciliation runs with only that tenant’s RBAC, and we enable the default service account setting on the controller so a forgotten field cannot fall back to cluster-admin. Each tenant gets a namespace, a role limited to it and a git path owned by its team.

Locking down human access

Kubernetes roles for engineers include get, list and watch on workloads, plus logs and events. Remove pods/exec, pods/portforward where policy demands, and any create, update or delete on workloads. Break-glass is a separate role, granted through your identity provider for a limited time, with API server audit logging switched on so every command is traceable. On AWS this ties to IAM and access entries, covered under EKS consulting, and on any platform to wider Kubernetes consulting work such as network policies.

Decisions and trade-offs

Strict from day one or phased. Removing write access overnight angers people who have no working alternative. We phase it: first deploy through git for everything, then reduce access in non-production, then production once confidence is real.

One ArgoCD per environment or one shared. A shared instance is cheaper and simpler to view; separate instances give a smaller blast radius for the controller itself, which holds powerful credentials. We pick based on your risk appetite and cluster count.

Policy engine or plain RBAC. RBAC cannot say “no privileged containers” or “images only from our registry”. Kyverno or OPA Gatekeeper can. Add one when you have rules RBAC cannot express, not before.

A worked example: a developer’s first week

A new engineer joins the payments team and is added to the payments-engineers group in the identity provider. That one change gives them login to ArgoCD with the deployer role for the payments project, read access to the payments namespaces in Kubernetes, and review rights on the payments folder through CODEOWNERS. They cannot see other teams’ applications in write mode, cannot create namespaces, and cannot exec into a production pod.

On day two they open a pull request changing a replica count. A teammate approves, the merge triggers a sync, and they watch it complete in ArgoCD. When something looks wrong they read logs and events, which they are permitted to do, and raise a fix through git. They never needed a kubeconfig with write rights. That path, from joining a group to shipping safely, is what we aim to make routine.

Auditing who can do what

Access models decay. We leave you a short script or query pattern for reviewing bindings, for example listing subjects bound to powerful roles and checking that group membership still matches the org chart. A quarterly review of those results, plus the break-glass log, keeps the model honest.

Common failure modes

  • The controller is the new cluster-admin. Anyone who can edit an Application without a project boundary can deploy anything. Projects and protected branches fix this.
  • Everyone is an ArgoCD admin because the default policy was never changed.
  • Unprotected production folder. Anyone with push rights bypasses review.
  • Break-glass becomes the normal way in, so we report on its use and review each activation.
  • Secrets readable by developers through kubectl get secret. See secret management in git for how to handle that.

Delivery and handover

We deliver branch rules, CODEOWNERS, AppProjects or tenant definitions, SSO group mapping, Kubernetes roles and a one-page access matrix that shows who can do what. The final step is a test: we try forbidden actions as each role and keep the results. Your platform team receives a runbook for onboarding a team, granting break-glass and reviewing its use.

How to tell it is working

Production changes all trace to a pull request. Break-glass activations are rare and reviewed. A new engineer can ship on day one with the right group membership and cannot exec into a production pod. If you want an access review of your current setup, book a consultation.

References

How we deliver it

  1. 01

    Map who needs what

    We list teams, environments and tasks, separating deploying, observing, debugging and administering the platform.

  2. 02

    Protect the git side

    Branch protection, required reviews and code owners are set on environment folders so production changes need the right approvers.

  3. 03

    Scope the controllers

    ArgoCD projects or Flux tenant service accounts restrict namespaces, clusters and resource kinds each team can deploy.

  4. 04

    Connect identity

    SSO groups from your identity provider map to roles in ArgoCD, Kubernetes and the cloud, with no shared accounts.

  5. 05

    Lock down direct access

    Kubernetes roles for humans are reduced to read and diagnostic permissions, with a time-boxed, logged break-glass role.

  6. 06

    Test the boundaries

    We attempt forbidden actions as each role and record that they fail, then document the model for your team.

Tools and technologies

ArgoCDFluxKubernetes RBACAppProjectOIDCDexOktaMicrosoft Entra IDAWS IAMGitHub CODEOWNERSKyvernoOPA Gatekeeper

Frequently asked questions

What is RBAC in GitOps?
It is the set of rules about who can change what, spread across three layers: git permissions for who can merge changes, GitOps controller policies for what each team's applications may deploy, and Kubernetes RBAC for what humans can do directly in the cluster. A secure setup configures all three consistently.
How do we stop developers using kubectl exec in production?
Remove the exec permission from their Kubernetes role, since exec is the pods/exec subresource, and grant read access to logs and events instead. Offer a break-glass role for incidents that is time-limited and audited. Policy engines can also deny exec on selected namespaces if you want a second barrier.
What is an ArgoCD AppProject?
An AppProject groups applications and defines what they may do: which source repositories, which destination clusters and namespaces, and which resource kinds. Teams get their own project, so a mistake or malicious change in one team's repository cannot deploy into another team's namespace or create cluster-wide resources.
Does Flux support multi-tenancy?
Yes. A Flux Kustomization or HelmRelease can run as a specified service account, so it applies manifests with only the permissions that account holds. Combined with one namespace and repository path per tenant, this stops teams reaching beyond their boundary. It needs deliberate setup because the defaults are permissive.
Should developers have any production access at all?
Yes, read access: logs, events, metrics and describe-level views, because they need to debug what they ship. Write access should flow through pull requests. Emergency write access is kept behind a documented, time-boxed approval, and every use is reviewed afterwards.

Talk to an engineer about gitops rbac

Book a free 30-minute call. We review your current setup and tell you honestly whether and how we can help.

Written by Saddique Khan, DevOps / SRE / Cloud Consultant Engineer. Last updated 2026-10-08.