Skip to main content

RBAC Scaffolder Action

The RBAC Scaffolder Action, simply called RBAC Action, enables the integration of RBAC inside template wizards. This way, a template can be configured to, not only scaffold a brand new entity inside the catalog, but also create users permissions for that entity.

Overview

By leveraging RBAC Scaffolder Action, the Platform Team can delegate the creation of Role-Subject assignations to the user of a template (e.g. assigning the Data Product Owner role and the Data Product Developer role for a new Data Product). In the example image below, the Data Product template delegates the creation of Roles-Subjects to users:

preview feature

Users of this template will be able to create a Data Product and assign roles to other users that will work on it, in a self-service fashion.

If everything is well-configured in the template, at scaffolding time, the RBAC Action will effectively contact the RBAC system with a set of Role-Subject bindings requests to be created.

The example above also gives a preview of advanced functionality, that is the Rbac Role Picker. This picker gives even more flexibility to template users by allowing them to select the role to be granted from a list. The list of assignable roles can be configured by the Platform Team so that nobody can assign privileged roles without explicit consent.

If you are not familiar on how to create your template, or what a template action is, head to the explanation here, before continuing.

Configuring an RBAC Action in a template

To configure RBAC Action in a new template, add the following snippet into your template.yaml at the steps key level:

- id: <unique identifier of the action e.g. `rbacAction`>
name: <display name for this action e.g. `RBAC Grant`>
action: rbac:action
input:
rolesSubjects: [
{ subject: <string>, roleId: <id of the role> },
# ...a list of roles-subjects requests
]

As you can notice Role-Subject requests passed as input to the RBAC Action is missing the entity_ref and enabled fields. As you know, entity_ref is mandatory when granting permissions with scopes ( see Granting permissions to a subject), while enabled is set to false by default.

However, when a Role-Subject is created by RBAC Action, the entity_ref will always be filled with the URN of the entity being scaffolded and the enabled will be set to true. entity_ref value cannot be changed nor configured. This means that RBAC Action can only grant permissions for a new entity, thus not for already existing entities.

caution

RBAC Action depends on the action fetch:template. Make sure it is there in the template.yaml's configured actions and that RBAC Action is, in order, invoked after fetch:template

tip

As a best practice, RBAC Action should be configured as the very last step in the list of actions, to prevent unwanted authorizations on scaffolding failures.

Configuring RBAC Action to take values from existing fields

As you may already know, templates leverage Nunjucks' capabilities to resolve placeholders found inside the template. We can leverage this mechanism, to pass to RBAC Action the value inserted by the user in any field from the UI.

To do so, let's suppose we have the following steps, fields and actions:

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: dataproduct-rbac-template
# ... other metadata
spec:
owner: datameshplatform
type: dataproduct

parameters:
- title: Data Product details
properties:
dataProductOwner:
title: Data Product Owner
type: string
description: User who owns the Data Product
ui:field: EntityPicker
ui:options:
allowArbitraryValues: false
defaultNamespace: false
allowedKinds:
- User

# ... a list of all other fields of a data product ...

- title: Choose a location
properties:
# ... all fields required for the publish action

Now, let's configure RBAC Action to create a grant to assign the role of Data Product Owner to the user inserted in the Data Product Owner field (configured at properties.dataProductOwner) of the wizard UI:

  steps:
- id: template
name: Fetch Skeleton + Template
action: fetch:template
# ... other action's fields

- id: publish
name: Publish
action: witboostMeshComponent:publish:gitlab
input
# ... other action's fields

- id: register
name: Register
action: catalog:register
# ... other action's fields

- id: granter
name: RBAC Grant
action: rbac:action
input:
rolesSubjects:
- subject: ${{ parameters.dataProductOwner }} # `properties` is renamed to `parameters`
roleId: DP_OWNER # this is the ID of the role to be assigned. must have `visibility` set to `user`

output:
# output fields
warning

Make sure all roles that you define in each roleId field (in this case DP_OWNER) has visibility set to user. See Roles configuration for more details.

Integrating RBAC Role Picker with RBAC Action

If you want to delegate the creation of permissions to users, but also the selection of roles to be assigned, you can combine RBAC Action with the RBAC Role Picker.

First of all, let's define a step in the wizard that asks the user to fill out some Role-Subject requests:

apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
name: dataproduct-rbac-template
# ... other metadata
spec:
owner: datameshplatform
type: dataproduct

parameters:
- title: Data Product details
properties:
# ... a list of all required fields of a data product ...

- title: Role-Based Access Control
properties:
bindings:
title: RBAC Roles Assignations
description: A list of users or groups and their RBAC role assignation
type: array
default: []
items:
type: object
title: Role-Subject association
required:
- roleId
- subject
properties:
subject:
type: string
title: Subject
ui:field: EntityPicker
ui:options:
allowArbitraryValues: false
defaultNamespace: false
allowedKinds:
- User
- Group
roleId:
type: string
title: Role
ui:field: RbacRolePicker
default: DP_OWNER # here we use a default value but it is not mandatory.
ui:options:
allowArbitraryValues: false

- title: Choose a location
properties:
# ... all fields required for the publish action
tip

For advanced customizations of the RbacRolePicker head to the Template Steps Customization section.

Now let's tweak the steps section of the template.yaml to also include the RBAC Action step:

  steps:
- id: template
name: Fetch Skeleton + Template
action: fetch:template
# ... other action's fields

- id: publish
name: Publish
action: witboostMeshComponent:publish:gitlab
input
# ... other action's fields

- id: register
name: Register
action: catalog:register
# ... other action's fields

- id: granter
name: RBAC Grant
action: rbac:action
input:
rolesSubjects: ${{ parameters.bindings }}

output:
# output fields

As you can notice, in the input property of the rbac:action we are passing the values taken from the bindings field, that is the list of Role-Subject created by the user from the UI.