Kubernetes cookbook · Intermediate

Give a CI pipeline least-privilege deploy access

CI deploys with cluster-admin; restrict it to one namespace and the resources it manages.

Create a free account to save this page, take notes and track your progress. Sign in

Approach

Create a ServiceAccount for the pipeline, a Role with the verbs it needs on the resources it deploys, and a RoleBinding in that namespace only. Authenticate CI with short-lived tokens or OIDC.

Solution

apiVersion: v1
kind: ServiceAccount
metadata: {name: ci-deployer, namespace: shop}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata: {name: deployer, namespace: shop}
rules:
  - apiGroups: [apps]
    resources: [deployments]
    verbs: [get, list, watch, create, update, patch]
  - apiGroups: [""]
    resources: [services, configmaps]
    verbs: [get, list, watch, create, update, patch]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata: {name: ci-deployer, namespace: shop}
roleRef: {apiGroup: rbac.authorization.k8s.io, kind: Role, name: deployer}
subjects: [{kind: ServiceAccount, name: ci-deployer, namespace: shop}]

Pitfalls

  • Granting Secret read access "just in case"; the pipeline rarely needs it.
  • Long-lived tokens stored in CI secrets; prefer kubectl create token --duration or OIDC federation.

Variations

  • GitOps: the pipeline only commits to Git and Argo CD deploys, so CI needs no cluster access at all.
  • Verify with kubectl auth can-i --list --as=system:serviceaccount:shop:ci-deployer -n shop.

Further reading: RBAC good practices

Reference: https://kubernetes.io/docs/concepts/security/rbac-good-practices/

More Kubernetes recipes

Was this page helpful?