Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
:_mod-docs-content-type: ASSEMBLY
ifdef::context[:parent-context: {context}]

[id="hide-pages-and-navigation-elements-using-rbac-to-maintain-a-secure-ui_{context}"]
= Hide pages and navigation elements using RBAC to maintain a secure UI

:context: hide-pages-and-navigation-elements-using-rbac-to-maintain-a-secure-ui

[role="_abstract"]
Hide pages and navigation elements in {product} ({product-very-short}) using role-based access control (RBAC) permissions to maintain a secure UI by preventing users from seeing UI elements they cannot access.

include::../modules/shared/con-rbac-based-ui-element-visibility.adoc[leveloffset=+1]

include::../modules/shared/con-user-experience-and-security-benefits-of-rbac-ui-hiding.adoc[leveloffset=+1]

include::../modules/shared/con-permission-types-for-rbac-ui-visibility-control.adoc[leveloffset=+1]

include::../modules/shared/con-unsupported-scenarios-and-constraints-for-rbac-ui-visibility.adoc[leveloffset=+1]

include::../modules/shared/proc-configure-rbac-visibility-rules-to-hide-unauthorized-ui-elements.adoc[leveloffset=+1]

ifdef::parent-context[:context: {parent-context}]
ifndef::parent-context[:!context:]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
:_mod-docs-content-type: ASSEMBLY
ifdef::context[:parent-context: {context}]

[id="permissions-for-ui-visibility-control_{context}"]
= Permissions for UI visibility control

:context: permissions-for-ui-visibility-control

[role="_abstract"]
Reference information about permissions used to control UI element visibility in {product-very-short}.

include::../modules/shared/ref-plugin-permissions-for-ui-visibility.adoc[leveloffset=+1]

include::../modules/shared/ref-ui-elements-with-rbac-visibility-control.adoc[leveloffset=+1]

include::../modules/shared/ref-permission-evaluation-behavior-for-ui-visibility.adoc[leveloffset=+1]

ifdef::parent-context[:context: {parent-context}]
ifndef::parent-context[:!context:]
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
:_mod-docs-content-type: CONCEPT

[id="permission-types-for-rbac-ui-visibility-control_{context}"]
= Permission types for RBAC UI visibility control

[role="_abstract"]
{product-very-short} supports the following permission types for UI visibility control:

Basic permissions without attributes::
Permissions that are evaluated directly in the permission policy and return an *ALLOW* or *DENY* result.
+
[source,json]
----
{
"name": "kubernetes.proxy",
"attributes": {}
}
----

Basic permissions with attributes::
Permissions that include attributes such as action (create, read, update, delete) and are evaluated in the permission policy.
The policy logic may depend on these attributes.
+
[source,json]
----
{
"name": "catalog.entity.create",
"attributes": {
"action": "create"
}
}
----
11 changes: 11 additions & 0 deletions modules/shared/con-rbac-based-ui-element-visibility.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
:_mod-docs-content-type: CONCEPT

[id="rbac-based-ui-element-visibility_{context}"]
= RBAC-based UI element visibility

[role="_abstract"]
{product} ({product-very-short}) supports fine-grained visibility control for UI elements based on role-based access control (RBAC) permissions, enabling a cleaner user experience by hiding pages, tabs, and navigation items that users cannot access.

The RBAC UI visibility control feature extends the RBAC framework to support dynamic UI element visibility based on user permissions. By integrating RBAC policies with the frontend layout engine, {product-very-short} can automatically hide or show pages, tabs, and navigation items according to the authenticated user's roles and permissions.

This feature addresses a common user experience issue where users can see navigation links, sidebar items, and UI tabs even when they lack the permissions to view the content within them. Without UI visibility control, users encounter empty states or 403 errors that clutter the interface and create confusion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
:_mod-docs-content-type: CONCEPT

[id="unsupported-scenarios-and-constraints-for-rbac-ui-visibility_{context}"]
= Unsupported scenarios and constraints for RBAC UI visibility

[role="_abstract"]
The current implementation has the following limitations:

* *Basic permission checks only:* The `if` predicate supports only basic permission checks based on the permission name. Attributes are inferred from the permission name using a naming convention.

* *No resource context:* Evaluation happens during application initialization when no resource context is available. Therefore, resource-based permissions and conditional decisions are not supported.

* *Coarse-grained control:* The feature is designed for coarse-grained UI control, such as enabling or disabling entire features, pages, or navigation items. It is not suitable for fine-grained or resource-level authorization within a specific page or component.

* *Component-level hiding not supported:* Hiding individual buttons or fields within a specific page is not supported. This must be handled by the individual plugin's internal logic.

[NOTE]
====
Resource permissions with a `resourceType` typically depend on specific resources and return conditional decisions from the policy. These permissions cannot be used directly in the `if` predicate. Fine-grained, resource-aware authorization must be handled at the backend layer or within components after the data is available.
====

.Additional resources

* link:https://backstage.io/docs/permissions/overview[{backstage} Permissions Documentation]
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
:_mod-docs-content-type: CONCEPT

[id="user-experience-and-security-benefits-of-rbac-ui-hiding_{context}"]
= User experience and security benefits of RBAC UI hiding

[role="_abstract"]
The RBAC UI visibility control feature provides the following benefits:

* *Improved user experience:* Users are not distracted by navigation items or UI tabs that lead to empty pages or "Access Denied" messages.

* *Reduced cognitive load:* The interface dynamically adapts to the user's role, presenting a streamlined workspace focused only on authorized actions.

* *Enhanced security posture:* While UI hiding does not replace API security, it prevents the leakage of internal structure or tooling names to unauthorized users.

* *Administrative flexibility:* Platform administrators can define high-level UI visibility rules within the RBAC policy engine without needing to modify frontend code or configuration files for every change.

The UI visibility control feature uses the `if` predicate in extension blueprints to conditionally include or exclude UI elements from the application tree at runtime.
The predicate evaluates permissions during application initialization and determines whether to render specific UI elements based on the user's authorization status.

The evaluation mechanism supports:

* *Permission-based evaluation:* The system checks whether the user has the required permissions to view a UI element.
The permission API authorizes the request by checking the permission name and attributes.

* *Feature flag evaluation:* The predicate also supports feature flags, enabling gradual rollout or environment-based toggles.

The UI visibility control operates at the application tree resolution phase during frontend initialization.
This means that the evaluation happens before the UI renders, ensuring that users never see elements they cannot access.
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
:_mod-docs-content-type: PROCEDURE

[id="configure-rbac-visibility-rules-to-hide-unauthorized-ui-elements_{context}"]
= Configure RBAC visibility rules to hide unauthorized UI elements

[role="_abstract"]
Configure RBAC visibility rules in {product} to hide unauthorized UI elements by using the `if` predicate in extension blueprints, ensuring users only see pages, tabs, and navigation items they have permission to access.

.Prerequisites

* You have administrative access to {product-very-short}.
* You have enabled the RBAC feature in {product-very-short}.
* You have defined the required permissions for your plugins.

.Procedure

. Determine which UI elements you want to control with RBAC permissions.

. Identify the permission names that should get access to those UI elements.
+
[NOTE]
====
Permissions must follow the naming pattern `<resource>.<action>` where the action is one of `create`, `read`, `update`, or `delete`. The system automatically infers the action attribute from the permission name.
====

. Configure the `if` predicate in your extension blueprint to control UI visibility based on permissions:
+
. To control the visibility of entire pages, use the `if` predicate in the `PageBlueprint`:
+
[source,typescript]
----
PageBlueprint.make({
name: 'rbac',
params: {
path: '/rbac',
title: 'RBAC',
icon: <RbacIcon />,
routeRef: rootRouteRef,
noHeader: true,
loader: async () => import('../components/Router').then(m => <m.Router />),
},
if: {
permissions: { $contains: 'policy.entity.read' },
},
});
----
+
In this example, the RBAC page is only visible to users who have the `policy.entity.read` permission.

. To control the visibility of tabs on entity pages, use the `if` predicate in the `EntityContentBlueprint`:
+
[source,typescript]
----
EntityContentBlueprint.make({
name: 'tektonEntityContent',
params: {
path: '/ci-cd',
title: 'CI/CD',
filter: isTektonCIAvailable,
loader: () => import('./components/Router').then(m => <m.Router />),
},
if: {
$all: [
{
permissions: { $contains: 'kubernetes.resources.read' },
},
{
permissions: { $contains: 'kubernetes.clusters.read' },
},
],
},
});
----
+
In this example, the CI/CD tab is only visible to users who have both the `kubernetes.resources.read` and `kubernetes.clusters.read` permissions.
The `$all` operator ensures that all specified permissions are required.

. To control the visibility of cards on pages, use the `if` predicate in the `EntityCardBlueprint` or `HomePageWidgetBlueprint`:
+
[source,typescript]
----
EntityCardBlueprint.make({
name: 'labels',
params: {
type: 'info',
filter: { 'metadata.labels': { $exists: true } },
loader: async () =>
import('../components/EntityLabelsCard').then(m => (
<m.EntityLabelsCard />
)),
},
if: {
permissions: { $contains: 'catalog.entity.read' },
},
});
----
+
For homepage widgets:
+
[source,typescript]
----
HomePageWidgetBlueprint.make({
name: 'rhdh-entity-section',
params: {
name: '{product} - Software Catalog',
layout: defaultCardLayout,
components: () =>
import('../../components/EntitySection').then(m => ({
Content: () => compatWrapper(<m.EntitySection />),
})),
},
if: {
permissions: { $contains: 'catalog.entity.read' },
},
});
----

. Use permission operators to combine multiple permission checks:
+
`$contains`::
Checks if the user has a specific permission.
+
[source,typescript]
----
if: {
permissions: { $contains: 'permission.name' },
}
----

`$all`::
Requires the user to have all specified permissions.
+
[source,typescript]
----
if: {
$all: [
{ permissions: { $contains: 'permission.one' } },
{ permissions: { $contains: 'permission.two' } },
],
}
----

`$any`::
Requires the user to have at least one of the specified permissions.
+
[source,typescript]
----
if: {
$any: [
{ permissions: { $contains: 'permission.one' } },
{ permissions: { $contains: 'permission.two' } },
],
}
----

.Verification

. Log in to {product-very-short} as a user with limited permissions.
. Verify that UI elements requiring permissions you do not have are hidden from view.
. Log in as a user with the required permissions.
. Verify that the UI elements are now visible and accessible.
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
:_mod-docs-content-type: REFERENCE

[id="permission-evaluation-behavior-for-ui-visibility_{context}"]
= Permission evaluation behavior for UI visibility

[role="_abstract"]
When a UI element includes an `if` predicate with permission checks, the following evaluation behavior applies:

. The permission API is called with the permission name during application initialization.
. The action attribute is inferred from the permission name if it ends with `create`, `read`, `update`, or `delete`.
. The permission policy evaluates the permission and returns an ALLOW or DENY result.
. If the result is ALLOW, the UI element is included in the application tree and rendered.
. If the result is DENY, the UI element is excluded from the application tree and not rendered.

[NOTE]
====
Permission evaluation occurs during frontend initialization, before the UI renders.
This ensures that users never see UI elements they cannot access.
However, it also means that no resource context is available during evaluation.
====
66 changes: 66 additions & 0 deletions modules/shared/ref-plugin-permissions-for-ui-visibility.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
:_mod-docs-content-type: REFERENCE

[id="plugin-permissions-for-ui-visibility_{context}"]
= Plugin permissions for UI visibility

[role="_abstract"]
The following table lists the permissions used by various plugins to control UI element visibility. These permissions follow the naming pattern `<resource>.<action>` where the action is inferred from the permission name.

[cols="25%,25%,50%", frame="all", options="header"]
|===
|Plugin
|Permission
|Description

|Kubernetes
|`kubernetes.clusters.read`
|Controls visibility of UI elements that display Kubernetes cluster information

|Kubernetes
|`kubernetes.resources.read`
|Controls visibility of UI elements that display Kubernetes resource information

|Tekton
|`kubernetes.clusters.read`
|Controls visibility of Tekton CI/CD tabs and components

|Tekton
|`kubernetes.resources.read`
|Controls visibility of Tekton pipeline resources

|OCM
|`ocm.entity.read`
|Controls visibility of OCM (Open Cluster Management) cluster information cards and pages

|Topology
|`kubernetes.clusters.read`
|Controls visibility of topology view for Kubernetes clusters

|Topology
|`kubernetes.resources.read`
|Controls visibility of topology resource information

|Argo CD
|`argocd.view.read`
|Controls visibility of Argo CD application information

|Quay
|`quay.view.read`
|Controls visibility of Quay repository information

|Adoption Insights
|`adoption-insights.events.read`
|Controls visibility of adoption insights and analytics

|Catalog
|`catalog.entity.read`
|Controls visibility of catalog entity information

|Catalog
|`catalog.entity.create`
|Controls visibility of UI elements for creating catalog entities

|RBAC
|`policy.entity.read`
|Controls visibility of RBAC policy and role information
|===
Loading
Loading