RBAC, policy & guardrails
Least privilege on the control plane.
Crossplane concentrates enormous power in one cluster: it holds cloud credentials and continuously provisions infrastructure, so its own access control is the security story. Two layers matter. Kubernetes RBAC governs who can create claims, composites, and providers — a developer should be able to file a claim in their namespace but never install a provider or edit a composition. And the cloud-side IAM the ProviderConfig assumes bounds what Crossplane can do at all.
apiVersion: rbac.authorization.k8s.io/v1kind: Rolemetadata: { namespace: team-orders, name: claim-author }rules:- apiGroups: ["acme.io"]resources: ["postgresinstances"] # claims only — not XRs, not compositionsverbs: ["get", "list", "create", "delete"]# developers get this; only platform admins can touch compositions/providers/XRDs
Guardrails beyond RBAC
Layer policy on top. An admission policy engine (Kyverno, OPA/Gatekeeper) can enforce rules on the composites and claims themselves — required labels, allowed regions, forbidden public networking — before Crossplane acts. Scope each ProviderConfig’s cloud role to least privilege so even a mistaken composition cannot exceed it, and separate environments so a dev-namespace claim cannot provision into prod accounts.
# who can install providers? that list should be tiny.$ kubectl auth can-i create providers.pkg.crossplane.io \--as=system:serviceaccount:team-orders:defaultno # good — a dev SA cannot install packages into the control plane