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
2 changes: 2 additions & 0 deletions _topic_maps/_topic_map.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ Topics:
File: rhcl-ocp-web-console
- Name: Sharing and consuming APIs across teams
File: rhcl-api-management
- Name: RBAC and permissions for the developer hub plugin
File: devhub-plugin-rbac-ref
---
Name: Observability
Dir: observe
Expand Down
44 changes: 44 additions & 0 deletions develop/devhub-plugin-rbac-ref.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
:_mod-docs-content-type: ASSEMBLY
include::_attributes/attributes.adoc[]
[id="devhub-plugin-rbac-ref"]
= RBAC reference for the developer hub plugin
:context: devhub-plugin-rbac-ref

toc::[]

[role="_abstract"]
To control who can publish APIs, request API access, and approve requests in the {prodname} {rhdh} plugin, configure role-based access control (RBAC). The {prodname} plugin uses the {rhdh} RBAC system with a consistent ownership-based permission model.

include::modules/con-devhub-rbac-overview.adoc[leveloffset=+1]

include::modules/con-devhub-rbac-design-principles.adoc[leveloffset=+1]

include::modules/ref-devhub-rbac-permission-structure.adoc[leveloffset=+1]

include::modules/ref-devhub-rbac-permission-list.adoc[leveloffset=+1]

include::modules/ref-devhub-rbac-role-definitions.adoc[leveloffset=+1]

include::modules/ref-devhub-rbac-permissions-matrix.adoc[leveloffset=+1]

include::modules/con-devhub-rbac-ownership-model.adoc[leveloffset=+1]

include::modules/con-devhub-rbac-approval-workflow.adoc[leveloffset=+1]

include::modules/ref-devhub-rbac-per-apiproduct-access.adoc[leveloffset=+1]

include::modules/con-devhub-rbac-catalog-integration.adoc[leveloffset=+1]

include::modules/ref-devhub-rbac-configuration.adoc[leveloffset=+1]

include::modules/con-devhub-rbac-security.adoc[leveloffset=+1]

include::modules/ref-devhub-rbac-frontend-permissions.adoc[leveloffset=+1]

include::modules/con-devhub-rbac-two-layer-model.adoc[leveloffset=+1]

[id="additional-resources_devhub-pligin-rbac-ref"]
[role="_additional-resources"]
== Additional resources

* link:https://docs.redhat.com/en/documentation/red_hat_developer_hub/1.10/html/authorization_in_red_hat_developer_hub/role-based-access-control-in-rhdh_authorization-in-rhdh[Role-based access control in Developer Hub]
26 changes: 26 additions & 0 deletions modules/con-devhub-rbac-approval-workflow.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: CONCEPT
[id="con-devhub-rbac-approval-workflow_{context}"]
= Approval workflow

[role="_abstract"]
The {prodname} {rhdh} plugin controls access to the approval queue and enforces ownership checks when users approve or reject API key requests.

[id="con-devhub-rbac-approval-queue-visibility_{context}"]
== Approval queue visibility

The approval queue card is visible only to users who have the `kuadrant.apikey.approve` permission. This permission determines whether a user can see the approval interface in the {rhdh} UI.

API consumers:: Do not see the approval queue because they do not have the `approve` permission.
API owners:: See the approval queue and can approve requests for their own APIs.
API administrators:: See the approval queue and can approve any request.

[id="con-devhub-rbac-backend-approval-enforcement_{context}"]
== Backend approval enforcement

The backend uses tiered permission checks for approve and reject actions independently from the frontend UI. The backend first checks if the user has the `kuadrant.apikey.update.all` permission for administrator-level access. If the user does not have that permission, the backend verifies that the user owns the `APIProduct` resource associated with the request.

The `kuadrant.apikey.approve` permission controls UI visibility of the approval queue. The backend enforces ownership separately to ensure that API owners can only approve requests for their own APIs.
12 changes: 12 additions & 0 deletions modules/con-devhub-rbac-catalog-integration.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: CONCEPT
[id="con-devhub-rbac-catalog-integration_{context}"]
= Catalog integration

[role="_abstract"]
The `APIProduct` entity provider syncs only products that have ownership annotations to the {rhdh} catalog. If an `APIProduct` resource does not have a `backstage.io/owner` annotation, it is not synced and does not appear in the catalog.

This behavior ensures clean separation between resources managed through the {rhdh} plugin and resources managed directly by using `oc` or `kubectl` commands.
20 changes: 20 additions & 0 deletions modules/con-devhub-rbac-design-principles.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: CONCEPT
[id="con-devhub-rbac-design-principles_{context}"]
= RBAC design principles

[role="_abstract"]
The {prodname} {rhdh} plugin follows a set of design principles for authorization decisions. Understanding these principles helps you configure and troubleshoot RBAC policies.

Pure RBAC only:: All authorization decisions use {rhdh} RBAC permissions. If you need to control access to a feature, create a permission for it. The plugin does not use group membership checks, data-based ownership checks for UI visibility, or role flags derived from user identity.

One permission per distinct capability:: Each permission represents a single, well-defined capability. Permissions are not overloaded with meanings. For example, `kuadrant.apikey.approve` is a separate permission specifically for approval queue access. This is instead of reusing `kuadrant.apikey.update.own` for both editing and approving.

UI visibility matches permission checks:: If a UI element is hidden from certain users, that element is gated by a permission check rather than a data query. The plugin does not use data queries to allow a user to see a resource or action.

Backend enforces, front-end hints:: Permissions in the front-end control the user experience by hiding buttons and displaying the appropriate UI. The backend enforces permissions independently and does not rely on front-end permission checks.

Scope permissions appropriately:: Permissions use `.own` scope for resources the user created, `.all` scope for any resource regardless of ownership, and no scope for actions that apply globally. For actions that do not fit the ownership model, such as viewing an approval queue, the plugin uses an unscoped permission.
12 changes: 12 additions & 0 deletions modules/con-devhub-rbac-overview.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: CONCEPT
[id="con-devhub-rbac-overview_{context}"]
= The RBAC permission model

[role="_abstract"]
The {prodname} {rhdh} plugin uses the {rhdh} role-based-access-system (RBAC) system for access control across API products, API keys, and plan policies. Permissions follow a consistent `.own` and `.all` pattern for resource-level access control.

With `.own` permissions, a user can act on resources that they created or own. With `.all` permissions, a user can act on any resource regardless of ownership. Permissions without a scope, such as `list` and `create`, apply globally.
36 changes: 36 additions & 0 deletions modules/con-devhub-rbac-ownership-model.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: CONCEPT
[id="con-devhub-rbac-ownership-model_{context}"]
= Ownership model

[role="_abstract"]
The {prodname} {rhdh} plugin tracks ownership of `APIProduct` resources and uses ownership information to enforce `.own` scoped permissions.

[id="con-devhub-rbac-ownership-tracking_{context}"]
== Ownership tracking

`APIProduct` resources track ownership by using a standard annotation:

[source,yaml]
----
metadata:
annotations:
backstage.io/owner: "user:default/jmadigan"
----

The owner reference uses the entity reference format: `_<kind>_:_<namespace>_/_<name>_`.

The ownership annotation is set when the resource is created and cannot be modified. This prevents ownership hijacking and maintains clear accountability. Kubernetes automatically sets `metadata.creationTimestamp` for audit purposes.

[id="con-devhub-rbac-backend-enforcement_{context}"]
== Backend enforcement

All sensitive endpoints use tiered permission checks. The backend first checks if the user has the `.all` permission, which grants administrator-level access to any resource. If the user does not have the `.all` permission, the backend checks the `.own` permission and verifies that the user owns the resource. If neither permission check passes, the backend denies access.

[id="con-devhub-rbac-list-filtering_{context}"]
== List endpoint filtering

List endpoints return different results based on the user's permissions. A user with the `.read.all` permission sees all resources. A user with the `.read.own` permission sees only resources that they own. A user without either permission is denied access.
25 changes: 25 additions & 0 deletions modules/con-devhub-rbac-security.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: CONCEPT
[id="con-devhub-rbac-security_{context}"]
= Security considerations

[role="_abstract"]
The {prodname} {rhdh} plugin enforces several security measures to protect API resources and user data.

[id="con-devhub-rbac-input-validation_{context}"]
== Input validation

All mutating endpoints validate request bodies against explicit schemas with field-level allowlists. Only permitted fields are accepted, and any unrecognized fields are rejected. This prevents users from modifying fields that they are not authorized to change.

[id="con-devhub-rbac-ownership-immutability_{context}"]
== Ownership immutability

PATCH endpoints explicitly prevent modification of the ownership annotation. If a request body includes a change to the `backstage.io/owner` annotation, the backend removes that change before processing the request. This prevents ownership hijacking.

[id="con-devhub-rbac-authentication-required_{context}"]
== Authentication requirement

All endpoints require valid authentication. The plugin does not support guest access or anonymous requests. If a request does not include valid credentials, the backend denies access.
18 changes: 18 additions & 0 deletions modules/con-devhub-rbac-two-layer-model.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: CONCEPT
[id="con-devhub-rbac-two-layer-model_{context}"]
= Two-layer RBAC model

[role="_abstract"]
The {prodname} {rhdh} plugin uses two separate RBAC layers with clear separation and no overlap.

Layer 1: {rhdh} RBAC (portal access control)::
Controls who can interact with API management through the {rhdh} UI. This layer governs catalog visibility, which determines who can see API entities. It also governs request creation, which determines who can request API keys. Approval permissions control who can approve or reject requests. Management permissions control who can create and delete `APIProduct` resources.

Layer 2: {prodname} and gateway RBAC (runtime access control)::
Controls how APIs behave at runtime. API key validation through `AuthPolicy` resources determines whether a key is valid. Rate limiting through `PlanPolicy` predicate checks determines what limits apply. Authentication through `AuthPolicy` resources determines whether a request has valid credentials.

The two layers do not overlap. The {rhdh} layer controls who gets API keys, while the {prodname} and gateway layer enforces runtime limits.
31 changes: 31 additions & 0 deletions modules/ref-devhub-rbac-configuration.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: REFERENCE
[id="ref-devhub-rbac-configuration_{context}"]
= RBAC configuration

[role="_abstract"]
Configure RBAC for the {prodname} {rhdh} plugin by using a policy file and the application configuration.

[id="ref-devhub-rbac-policy-file_{context}"]
== Policy file location

The RBAC policy file is `rbac-policy.csv`, located at the repository root.

[id="ref-devhub-rbac-app-config_{context}"]
== Application configuration

Enable RBAC and configure the policy file in your `app-config` file:

[source,yaml]
----
permission:
enabled: true
rbac:
policies-csv-file: ./rbac-policy.csv
policyFileReload: true
----

Setting `policyFileReload` to `true` enables automatic reloading of the policy file when you make changes.
19 changes: 19 additions & 0 deletions modules/ref-devhub-rbac-frontend-permissions.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: REFERENCE
[id="ref-devhub-rbac-frontend-permissions_{context}"]
= Frontend permission checks

[role="_abstract"]
The {prodname} {rhdh} plugin uses permission checks in the frontend to control UI visibility and available actions.

The plugin uses the `useKuadrantPermission` hook to check whether the current user has a specific permission. If the user does not have the required permission, the corresponding UI element is hidden. For example, the *Create API Product* button is visible only to users with the `kuadrant.apiproduct.create` permission.

For ownership-aware actions, the plugin checks both the user's permissions and the resource ownership. A *Delete* button is visible only if the user has either the `.delete.all` permission or the `.delete.own` permission and owns the resource.

[IMPORTANT]
====
Frontend permission checks are for user experience only. The backend enforces permissions independently and does not rely on frontend checks. Hiding a button in the UI does not prevent access to the underlying API endpoint.
====
24 changes: 24 additions & 0 deletions modules/ref-devhub-rbac-per-apiproduct-access.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Module included in the following assemblies:
//
// * develop/devhub-plugin-rbac.adoc

:_mod-docs-content-type: REFERENCE
[id="ref-devhub-rbac-per-apiproduct-access_{context}"]
= Per-APIProduct access control

[role="_abstract"]
The `kuadrant.apikey.create` permission supports resource references for fine-grained control over which API products a user can request access to. Use resource references in your RBAC policy to restrict API access by namespace or by specific API product.

The following examples show RBAC policy entries that control per-product access:

[source,csv]
----
# Allow all consumers to request any API
p, role:default/api-consumer, kuadrant.apikey.create, create, allow, apiproduct:*/*

# Restrict specific APIs to specific roles
p, role:default/partner, kuadrant.apikey.create, create, allow, apiproduct:toystore/toystore-api
p, role:default/internal, kuadrant.apikey.create, create, allow, apiproduct:internal/*
----

The backend validates the resource reference when processing a request. It checks the permission against the specific `APIProduct` namespace and name, formatted as `apiproduct:_<namespace>_/_<name>_`.
Loading