Move manual RBAC documentation to compositions page

Add refs from other pages where it might come up.

I also added a bit of detail and rephrased to address some Vale linter
warnings.

Signed-off-by: Nic Cope <nicc@rk0n.org>
This commit is contained in:
Nic Cope 2025-04-10 18:27:14 -07:00
parent b0585a0002
commit 80f9dbd72c
3 changed files with 74 additions and 29 deletions

View File

@ -269,6 +269,64 @@ spec:
# Removed for brevity # Removed for brevity
``` ```
### Grant access to composed resources
Crossplane uses its [service account](https://kubernetes.io/docs/concepts/security/service-accounts/)
to create the composed resources that a function pipeline returns.
Crossplane's service account has access to create, update, and delete any
resource installed by a [provider]({{<ref "../packages/providers">}}), or
defined by an XRD. This includes all
[MRs]({{<ref "../managed-resources/managed-resources">}}) and
[XRs]({{<ref "composite-resources">}}). It also has access to some types of
Kubernetes resources that it needs to function - for example it can create
deployments.
You must grant Crossplane access to compose any other kind of resource. You do
this by creating an [RBAC ClusterRole](https://kubernetes.io/docs/reference/access-authn-authz/rbac/).
<!-- vale write-good.TooWordy = NO -->
<!-- TooWordy thinks "aggregate" is too wordy, but it's the name of the concept. -->
The ClusterRole must aggregate to Crossplane's primary ClusterRole using
[ClusterRole aggregation](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles).
<!-- vale write-good.TooWordy = YES -->
Here's a ClusterRole that grants Crossplane access to manage
[CloudNativePG](https://cloudnative-pg.io) PostgreSQL clusters.
``` yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cnpg:aggregate-to-crossplane
labels:
rbac.crossplane.io/aggregate-to-crossplane: "true"
rules:
- apiGroups:
- postgresql.cnpg.io
resources:
- clusters
verbs:
- "*"
```
<!-- vale write-good.TooWordy = NO -->
<!-- TooWordy thinks "aggregate" is too wordy, but it's the name of the concept. -->
The `rbac.crossplane.io/aggregate-to-crossplane: "true"` label is critical. It
configures the role to aggregate to Crossplane's primary cluster role.
<!-- vale write-good.TooWordy = YES -->
{{<hint "note" >}}
The [RBAC manager]({{<ref "../guides/pods#rbac-manager-pod">}}) automatically
grants Crossplane access to MRs and XRs. The RBAC manager uses
[escalate access](https://kubernetes.io/docs/concepts/security/rbac-good-practices/#escalate-verb)
to grant Crossplane access that the RBAC manager doesn't have.
The RBAC manager is an optional Crossplane component that's enabled by default.
**If you disable the RBAC manager, you must manually grant Crossplane access to
_any_ kind of resource you wish to compose - including XRs and MRs.**
{{< /hint >}}
## Test a composition ## Test a composition
You can preview the output of any composition using the Crossplane CLI. You You can preview the output of any composition using the Crossplane CLI. You
@ -545,8 +603,8 @@ which composed resources it should create or update.
If the function needs __extra resources__ to determine the desired state it can If the function needs __extra resources__ to determine the desired state it can
request any cluster-scoped resource Crossplane already has access to, either by request any cluster-scoped resource Crossplane already has access to, either by
by name or labels through the returned RunFunctionResponse. Crossplane then name or labels through the returned RunFunctionResponse. Crossplane then calls
calls the function again including the requested __extra resources__ and the the function again including the requested __extra resources__ and the
__context__ returned by the Function itself alongside the same __input__, __context__ returned by the Function itself alongside the same __input__,
__observed__ and __desired state__ of the previous RunFunctionRequest. Functions __observed__ and __desired state__ of the previous RunFunctionRequest. Functions
can iteratively request __extra resources__ if needed, but to avoid endlessly can iteratively request __extra resources__ if needed, but to avoid endlessly

View File

@ -660,6 +660,13 @@ Functions can change the results of earlier functions in the pipeline.
Crossplane uses the result returned by the last function. Crossplane uses the result returned by the last function.
{{</hint>}} {{</hint>}}
{{<hint "tip">}}
If you edit this composition to include a different kind of resource you might
need to grant Crossplane access to compose it. Read
[the composition documentation]({{<ref "../composition/compositions#grant-access-to-composed-resources">}})
to learn how to grant Crossplane access.
{{</hint>}}
## Use the custom resource ## Use the custom resource
Crossplane now understands `App` custom resources. Crossplane now understands `App` custom resources.

View File

@ -207,32 +207,12 @@ compose-pg@{animate: true}
This opens composition to exciting new use cases - for example building custom This opens composition to exciting new use cases - for example building custom
app models with Crossplane. app models with Crossplane.
### Beware Crossplane's default access {{<hint "tip">}}
You must grant Crossplane access to compose resources that aren't Crossplane
Crossplane by default can only access a limited set of kubernetes resources beyond what gets configured by any providers. resources like MRs or XRs. Read
[the composition documentation]({{<ref "../composition/compositions#grant-access-to-composed-resources">}})
To grant access to additional resource resource types, create additional `ClusterRoles` and include them in the default Crossplane `ClusterRole` through [aggregation](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#aggregated-clusterroles). Crossplane's default ClusterRole aggregates using a selector for the label `rbac.crossplane.io/aggregate-to-crossplane: "true"` to learn how to grant Crossplane access.
{{</hint>}}
If you don't include this you may experience RBAC issues composing third party custom resources.
Here is an example of allowing Crossplane handle the lifecycle of CloudNativePG PostgreSQL `Cluster`.
``` yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cnpg:aggregate-to-crossplane
labels:
app: crossplane
rbac.crossplane.io/aggregate-to-crossplane: "true"
rules:
- apiGroups:
- postgresql.cnpg.io
resources:
- clusters
verbs:
- "*"
```
## Backward compatibility ## Backward compatibility