KubernetesLIX · kubectl authkubectl auth
kubectl auth reconcile — generating bindings from files
What you'll learn
- Use `kubectl auth reconcile` to apply RBAC manifests idempotently
- Distinguish `auth reconcile` from `kubectl apply` for RBAC objects
- Detect drift between version-controlled RBAC and the live cluster
- Integrate RBAC into a GitOps workflow with `auth reconcile -f manifest.yaml`
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
kubectl auth reconcile is the kubectl subcommand for
applying RBAC manifests idempotently. It walks the
manifests, computes the desired state, applies changes
to bring the cluster into alignment, and reports drift.
This lesson covers the operational use of auth reconcile, the difference from kubectl apply, and
the GitOps patterns.
The basic syntax
kubectl auth reconcile -f FILE_OR_DIRECTORY \
[--dry-run=client|server] \
[--server-side] \
[--validate=strict|true|false]
The input is a file or a directory containing Role, ClusterRole, RoleBinding, and ClusterRoleBinding manifests. The output is a list of changes applied (or to be applied in dry-run mode).
# Apply RBAC from a file
kubectl auth reconcile -f rbac/prod-rbac.yaml
# Dry-run
kubectl auth reconcile -f rbac/prod-rbac.yaml --dry-run=client
# Server-side apply (preserves fields not in the manifest)
kubectl auth reconcile -f rbac/prod-rbac.yaml --server-side
# Sample output
rolebinding.rbac.authorization.k8s.io/prod-ci-runner unchanged
role.rbac.authorization.k8s.io/prod-readonly configured
clusterrolebinding.rbac.authorization.k8s.io/prod-admins unchanged
Reconciling from a Git repository
The GitOps pattern for RBAC:
#!/bin/bash
# sync-rbac.sh — sync RBAC from Git to the cluster
set -euo pipefail
RBAC_DIR="${RBAC_DIR:-./rbac}"
# 1. Pull the latest RBAC
git -C "$RBAC_DIR" pull --rebase
# 2. Dry-run to detect drift
DRIFT=$(kubectl auth reconcile -f "$RBAC_DIR" --dry-run=client -o yaml)
if echo "$DRIFT" | grep -q "configured\|created\|deleted"; then
echo "Drift detected:"
echo "$DRIFT"
exit 1
fi
# 3. Apply
kubectl auth reconcile -f "$RBAC_DIR"
The script pulls RBAC from Git, dry-runs against the cluster, detects drift, and applies if clean. The output is auditable.
flowchart LR
A[Git repo of RBAC manifests] --> B[Pull]
B --> C[Dry-run]
C -->|drift| D[Operator reviews]
C -->|clean| E[Apply]
E --> F[Cluster RBAC]
D --> A
Drift detection
The dry-run output reports objects that would be created, updated, or deleted. A cluster whose live RBAC differs from the Git RBAC has drift:
# Detect drift
kubectl auth reconcile -f rbac/ --dry-run=client -o yaml
# Output (annotated)
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: prod-admins
...
# Would be: configured (subjects differ)
The drift report is the audit. The operator compares the live state to the Git state and resolves the difference: either the Git state is correct (apply) or the live state is correct (commit to Git).
Server-side apply
auth reconcile --server-side uses server-side apply
(SSA), which preserves fields not in the manifest:
kubectl auth reconcile -f rbac/prod-rbac.yaml --server-side
A field that was added to the live RBAC by an operator’s manual edit is preserved; a field in the manifest is updated. The result is the union of the manifest and any manual additions, with the manifest as the source of truth for the listed fields.
Reconciling ClusterRoles and aggregation
auth reconcile handles ClusterRole aggregation
correctly: an aggregated ClusterRole’s rules are
computed from the matching ClusterRoles. A reconcile
that adds a new aggregated ClusterRole and the matching
contributors in the same manifest applies both
atomically.
kubectl auth reconcile -f rbac/monitoring/ -f rbac/ci/
# Both directories applied in one call
The order is determined by kubectl auth reconcile
internally; bindings are applied after roles, so the
roles exist when the bindings are evaluated.
Production failure modes
- Drift is not detected. The cluster’s RBAC
diverges from Git; an operator hand-edits a
binding; the next reconcile wipes the edit. The
fix is
--server-sideand a policy of “no hand-edits.” - Manifest includes non-RBAC objects. A
developer added a Service to the RBAC manifest by
mistake.
auth reconcileskips it but the operator intended to apply it. The fix is to keep RBAC and workloads in separate files. auth reconcileruns as cluster-admin. The cluster-admin token is required. The fix is to run it from a dedicated CI/CD SA with cluster-admin scoped to RBAC objects.- No Git history. A team uses
auth reconcilewithout committing to Git; the cluster is the source of truth. The fix is to enforcekubectl auth reconcileonly from Git.
Cross-course references
- The Observability course covers the audit log
entries for
auth reconcileoperations. - The Linux course covers the file permissions for the Git repository that stores the RBAC manifests.
Quiz
Knowledge check · 4 questions
Q1. What is the operational effect of `kubectl auth reconcile -f manifest.yaml --server-side`?
Q2. `kubectl auth reconcile` applies RBAC objects only; non-RBAC objects in the manifest are silently applied as well.
Q3. Your CI pipeline runs `kubectl auth reconcile -f rbac/ --dry-run=client` and the output reports `role.rbac.authorization.k8s.io/prod-readonly configured`. The manifest in Git has `configmaps: [get]`; the live cluster has `configmaps: [get, list, watch]`. The next `auth reconcile` (without `--dry-run`) will run. What happens?
An operator hand-edited the `prod-readonly` Role to add `list` and `watch` to the ConfigMap rules. The Git manifest was not updated. The next `auth reconcile` (without `--server-side`) will reset the live Role to the Git state — removing the operator's additions.
Q4. Describe a GitOps RBAC workflow using `kubectl auth reconcile`. Name three steps.
Passing score: 75%. Answers are checked in this browser.
Production discipline
kubectl auth reconcile is the operational primitive
for GitOps RBAC. A defensible RBAC programme stores
every Role, ClusterRole, RoleBinding, and
ClusterRoleBinding in Git, runs auth reconcile from
CI/CD on every change, and uses --dry-run=client to
detect drift. The source of truth is Git; the cluster
is reconciled to Git. The audit is the dry-run output.
A cluster whose RBAC is not in Git has an RBAC
programme that is not auditable; a cluster whose RBAC
is in Git and reconciled with auth reconcile has an
RBAC programme that is enforceable.