Crossplane turns a Kubernetes cluster into a control plane for cloud infrastructure, so whoever can create a resource in that cluster, or read the secret behind a ProviderConfig, can create or change real cloud resources. This guide covers the customer side of running Crossplane v2 securely: how provider credentials are supplied and scoped, how workload identity replaces static keys, how the RBAC manager and its ClusterRoles grant access, how namespaced composite resources and compositions limit what platform users can reach, and how to control which packages the cluster will install. It is written for platform engineering, Kubernetes and cloud security teams. For IaC controls that apply to any tool, see the Infrastructure as Code Security Guide.
This is an independent guide from NHI Mgmt Group, based on Crossplane's public documentation (v2.4) as of November 2026. It is not sponsored or reviewed by the Crossplane project. Product features change, so confirm settings against Crossplane's current documentation.
Key takeaways
- Provider credentials are the crown jewels. A ProviderConfig points a provider at credentials, often a Kubernetes Secret in
crossplane-system; prefer workload identity sources such asIRSA,WebIdentityorPodIdentitywhere the provider documents them. - Use namespaced resources by default. In Crossplane v2,
Namespacedis the default XRD scope, and namespaced composite resources can only compose resources in the same namespace; the docs recommend it for most XRDs. - Know what the built in ClusterRoles grant.
crossplane-editandcrossplane-admininclude full access to all Secrets, even ones unrelated to Crossplane; bind them sparingly and prefer namespaced roles. - Grant Crossplane only the extra kinds it composes. Composing non Crossplane resources needs a ClusterRole labelled
rbac.crossplane.io/aggregate-to-crossplane: "true"; keep those rules narrow. - Control package sources. Pin package versions, use
ImageConfigfor registry pull secrets and, where you can enable the alpha flag, Cosign signature verification.
How identity and access work in Crossplane
Crossplane has two identity planes. Inside the cluster, Kubernetes RBAC decides which users and service accounts can create composite resources (XRs), managed resources (MRs), compositions and ProviderConfigs. Outside the cluster, each provider pod authenticates to its cloud or API with credentials named by a ProviderConfig. A user who can create an MR that references a ProviderConfig is acting with that ProviderConfig's cloud permissions, which is why both planes need to be scoped together.
| Component | Identity it uses | What it can reach | Customer control |
|---|---|---|---|
crossplane pod (core) | crossplane service account in crossplane-system | XRs, MRs and any kinds aggregated to its ClusterRole | Keep aggregated rules narrow; restrict who can edit them |
crossplane-rbac-manager pod | Its own service account with escalate access | Creates and binds roles for providers and the core pod | Keep enabled unless you maintain equivalent RBAC by hand |
| Provider pods | Service account created per provider revision, or one set by serviceAccountTemplate | The external API, using ProviderConfig credentials | Workload identity on the service account; least privilege cloud role |
| Function pods | Service account in the Crossplane namespace by default | Composition pipeline inputs and outputs | Install only reviewed functions; pin versions |
| Platform users | Kubernetes users and groups | XRs and claims in namespaces they are bound to | Namespaced roles on XR kinds only |
ProviderConfig and ClusterProviderConfig
In the v2 AWS provider example, a namespaced ProviderConfig and a cluster wide ClusterProviderConfig are both available, and managed resources must name the kind as well as the name in providerConfigRef. If providerConfigRef is omitted, it defaults to a ClusterProviderConfig named default. That default matters: any namespace whose users can create MRs without a reference inherits the default credentials. Either make the default ClusterProviderConfig low privilege, or avoid creating one and give each tenant namespace its own namespaced ProviderConfig. Authentication settings differ by provider, so read each provider's own authentication documentation.
Admin roles and privileged access
The RBAC manager, enabled by default, creates roles for provider service accounts and ClusterRoles for people. The Crossplane docs describe what each includes.
| ClusterRole | Documented permissions | Suggested use (ours) |
|---|---|---|
crossplane-admin | Full access to Crossplane types and to all Secrets and namespaces, including unrelated ones; read only on cluster RBAC roles, CRDs and events; can bind RBAC roles | Small platform admin group only, ideally through just in time elevation |
crossplane-edit | Full access to Crossplane types and to all Secrets, including unrelated ones; read only on namespaces and events | Platform engineers who author compositions; avoid for application teams |
crossplane-view | Read only on Crossplane types, namespaces and events | Auditors, support and read only dashboards |
- Secrets exposure: because
crossplane-editandcrossplane-admingrant access to every Secret, binding them is close to granting every credential in the cluster, including ProviderConfig secrets. Create narrower roles for day to day authors where you can. - Composition authors: whoever can create or change a
Composition, aCompositeResourceDefinitionor an aggregated ClusterRole decides what Crossplane builds for everyone. Manage these through Git with review, and limit direct cluster write access to the GitOps controller. - Disabling the RBAC manager: possible by setting
rbacManager.deploytofalsein Helm values, but the docs state that Crossplane then needs its Kubernetes permissions defined by hand. Choose this only if you need to review every rule yourself. - Cluster admins: anyone with cluster admin can read ProviderConfig secrets and exec into provider pods. Treat the Crossplane cluster as tier zero for every cloud account it manages, and keep it separate from general application clusters. See the Kubernetes RBAC Guide.
Compositions, XRD scope and aggregation
Crossplane v2 composite resources can be Namespaced (the default), Cluster scoped, or LegacyCluster for v1 style claims. Namespaced XRs can only compose resources in their own namespace, which gives tenant isolation for free; the docs suggest cluster scope only for platform level resources such as RBAC or cluster configuration. When a composition creates kinds that are not XRs or MRs, for example a third party operator's CRD, you grant Crossplane access with a ClusterRole carrying the label rbac.crossplane.io/aggregate-to-crossplane: "true". The documented example grants "*" verbs on one resource type; scope verbs and resource types to what the composition actually needs, and review such ClusterRoles like any privilege grant. The RBAC manager uses Kubernetes escalate access to grant Crossplane permissions it does not itself hold, so restrict who can edit aggregated roles.
Integrations, API tokens and service accounts
Provider credentials are non-human identities with direct cloud reach. The table summarises the patterns documented for the Crossplane AWS provider; other providers have their own equivalents.
| Credential source | How it works | When to choose it |
|---|---|---|
source: Secret | Long term keys in a Kubernetes Secret referenced by secretRef | Only where no federated option exists; restrict Secret access and rotate |
source: IRSA | Provider service account annotated with an IAM role via a DeploymentRuntimeConfig; EKS OIDC trust | Default choice on EKS |
source: WebIdentity | Assumes a role with a web identity token; spec.credentials.webIdentity.tokenConfig lets each ProviderConfig use its own token | Non EKS clusters with an OIDC issuer, or several roles per cluster |
source: PodIdentity | Uses EKS Pod Identity association for the provider service account | EKS clusters standardised on Pod Identity |
- DeploymentRuntimeConfig: a beta API that customises provider and function Deployments, including
serviceAccountTemplate.metadata.nameand annotations. Use it to attach workload identity annotations and to pin a named service account whose trust policy you control. If you name an existing service account, Crossplane uses it without taking ownership and still binds the permissions it needs. - One identity per trust boundary: create separate ProviderConfigs, and separate cloud roles, per environment or tenant. The docs show multiple ProviderConfigs (for example
user-keysandadmin-keys) selected per managed resource; pair that with RBAC so only the right namespaces can reference the powerful one. - Trust policy conditions: for IRSA, condition the role trust on the exact
sub(system:serviceaccount:<namespace>:<name>) andaud(sts.amazonaws.com), as the Crossplane workload identity guide does for the package manager. - Package manager registry access: the
crossplaneservice account can use IRSA, Azure Workload Identity or GKE Workload Identity to pull packages from a private registry, and nodes need their own pull rights for runtime images. Give the package manager read only registry access. - Connection details: MRs and compositions can write connection details (endpoints, passwords) to Secrets. Decide where these land, who can read them and whether an external secret store should hold them. See the Kubernetes Secrets Security Guide.
Package trust
Providers, functions and configurations are OCI packages that the package manager installs and runs with cluster permissions. Control them as you would any privileged software.
- Pin versions: reference packages by exact version (the docs use tags such as
function-patch-and-transform:v0.8.2) or digest, and change them by pull request. - Use a private mirror: mirror approved packages into your own registry and use
ImageConfigwithspec.registry.authentication.pullSecretRefto inject pull secrets for a prefix. The longest matching prefix wins, so keep prefixes distinct. - Verify signatures: with the alpha flag
--enable-signature-verification, anImageConfigcan require Cosign verification (keyless or key based authorities, plus attestations) for images matching a prefix; failing images are not pulled. Trial it in non production first. See the Sigstore Guide. - Limit active resources: a
ManagedResourceActivationPolicyactivates only the managed resource kinds you use, which shrinks the CRDs and controllers running in the cluster. - Protect important resources: a
Usageblocks deletion of a resource that others depend on, which reduces the impact of a mistaken or malicious delete.
Logging and detection
| Source | What it shows | What to watch |
|---|---|---|
| Kubernetes audit log | Who created or changed XRs, MRs, Compositions, ProviderConfigs, ImageConfigs and aggregated ClusterRoles | Changes to rbac.crossplane.io/aggregate-to-crossplane roles; reads of ProviderConfig Secrets by people |
| Provider change logs (alpha) | Each change a provider makes to external resources, written by a sidecar enabled through a DeploymentRuntimeConfig and a provider flag such as --enable-changelogs | Deletions and updates outside expected pipelines; check your provider supports change logs |
| Crossplane and provider pod logs and metrics | Reconcile errors, package installs, authentication failures | New package revisions; repeated credential errors |
| Cloud audit logs | API calls made by provider roles | Provider roles used from outside the cluster, or calls to services no composition uses |
Metrics to track (our suggestions): share of ProviderConfigs using a federated source rather than Secret; number of subjects bound to crossplane-admin or crossplane-edit; number of aggregated ClusterRoles with wildcard verbs (target zero); share of packages pinned by version and pulled from your mirror (target 100 percent); time to roll a provider credential.
Hardening baseline
The steps below are NHI Mgmt Group recommendations, built on the vendor settings described above.
- Isolate the control plane: run Crossplane in a dedicated cluster or a tightly controlled one, with cluster admin limited to the platform team and writes routed through GitOps.
- Move to workload identity: switch ProviderConfigs from
source: Secretto IRSA, WebIdentity, PodIdentity or the provider's equivalent; delete old keys after cut over. Test with a non production ProviderConfig first, and keep the Secret based config available until the new one reconciles cleanly, then remove it. - Scope by namespace: use
NamespacedXRDs, give each tenant namespace its own ProviderConfig and bind tenants to roles on their XR kinds only. - Tighten RBAC: review bindings to the Crossplane ClusterRoles, narrow aggregated roles and keep the RBAC manager on.
- Control packages: mirror, pin and, where the alpha feature is acceptable, verify signatures with
ImageConfig; enable only the managed resources you use. - Observe and update: collect audit and cloud logs, trial change logs, and apply Crossplane and provider releases promptly using the project's security advisories.
Decision guidance
- Single team platform: one cluster, one ProviderConfig per environment, cluster scoped XRDs only where needed.
- Multi tenant platform: namespaced XRDs, per namespace ProviderConfigs, no broadly privileged default ClusterProviderConfig, and policy admission controls that restrict which ProviderConfig a namespace may reference.
- Regulated estate: separate control plane clusters per environment, signature verification on packages and change logs forwarded to the SIEM.
Common misconfigurations
- A powerful default ClusterProviderConfig: MRs without a reference fall back to
default, so every tenant gets its permissions. - Static admin keys in a Secret: long term cloud administrator keys in
crossplane-systemare readable by anyone bound tocrossplane-editorcrossplane-admin. - Wildcard aggregated roles: copying the documented example with
"*"verbs across many resource types gives Crossplane, and composition authors, more power than needed. - Cluster scoped XRDs by habit: cluster scope lets an XR compose resources in any namespace; use it only for platform level resources.
- Unpinned packages from public registries: a moving tag changes the code running with cloud credentials without review.
Framework mapping
| Control area | NIST SP 800-53 Rev 5 | MITRE ATT&CK risk addressed |
|---|---|---|
| Workload identity for providers, credential rotation | IA-5 Authenticator Management | T1552.007 Container API, T1078.004 Cloud Accounts |
| ClusterRole review, namespaced XRDs, scoped ProviderConfigs | AC-6 Least Privilege | T1098 Account Manipulation |
| Package pinning, mirroring and signature verification | SR-3 Supply Chain Controls and Processes | T1195.002 Compromise Software Supply Chain, T1525 Implant Internal Image |
| Compositions via GitOps review, activation policies | CM-3 Configuration Change Control, CM-7 Least Functionality | T1195.002 Compromise Software Supply Chain |
| Audit logs and provider change logs | AU-2 Event Logging | T1078.004 Cloud Accounts |
Practitioner checklist
- Inventory every ProviderConfig and ClusterProviderConfig, its credential source and the cloud role behind it.
- Replace
source: Secretwith workload identity where the provider documents it, with trust policies bound to the exact service account. - Remove or reduce the privileges of the
defaultClusterProviderConfig. - Use
NamespacedXRDs and per namespace ProviderConfigs for tenants. - Review all bindings to
crossplane-adminandcrossplane-edit, remembering they include all Secrets. - Narrow every ClusterRole labelled
rbac.crossplane.io/aggregate-to-crossplane. - Pin package versions, mirror them privately and configure
ImageConfigpull secrets. - Trial Cosign signature verification in non production with
--enable-signature-verification. - Activate only the managed resources you use and protect key resources with
Usage. - Forward Kubernetes audit, provider change logs and cloud audit logs to your SIEM.
Standards and references
- Crossplane: Providers
- Crossplane: Crossplane Pods
- Crossplane: Compositions
- Crossplane: Composite Resource Definitions
- Crossplane: Image Configs
- Crossplane: Crossplane with Workload Identity
- Crossplane provider-upjet-aws: Authentication
- Kubernetes: Role Based Access Control Good Practices
Related NHI Mgmt Group resources: Infrastructure as Code Security Guide, Kubernetes RBAC Guide, Cloud Workload Identity Guide, Kubernetes Service Account Token Guide, Kubernetes Secrets Security Guide.