From 8f8133f12d2a74dc6503f7545942f11c40b52092 Mon Sep 17 00:00:00 2001 From: Patrick Knight Date: Fri, 8 Dec 2023 11:20:56 -0500 Subject: [PATCH] docs(rbac): add documentation for api and known permissions (#1000) --- plugins/rbac-backend/README.md | 37 +- plugins/rbac-backend/docs/apis.md | 411 +++++++++++++++++++++++ plugins/rbac-backend/docs/permissions.md | 54 +++ 3 files changed, 492 insertions(+), 10 deletions(-) create mode 100644 plugins/rbac-backend/docs/apis.md create mode 100644 plugins/rbac-backend/docs/permissions.md diff --git a/plugins/rbac-backend/README.md b/plugins/rbac-backend/README.md index bc84df5996..f81c933812 100644 --- a/plugins/rbac-backend/README.md +++ b/plugins/rbac-backend/README.md @@ -16,13 +16,12 @@ To effectively utilize the RBAC plugin, you must have the Backstage permission f You need to [set up the permission framework in Backstage](https://backstage.io/docs/permissions/getting-started/).Since this plugin provides a dynamic policy that replaces the traditional one, there's no need to create a policy manually. Please note that one of the requirements for permission framework is enabling the [service-to-service authentication](https://backstage.io/docs/auth/service-to-service-auth/#setup). Ensure that you complete these authentication setup steps as well. -Note: Red Hat Developer Hub users enjoy the benefit of Permission Framework and backend-to-backend authentication being enabled by default - ### Configuring the Backend To connect the RBAC framework to your backend use the `PolicyBuilder` class in your backend permissions plugin (typically `packages/backend/src/plugins/permissions.ts`) as follows: ```ts +/* highlight-add-start */ import { Router } from 'express'; import { @@ -48,18 +47,32 @@ export default async function createPlugin( pluginIdProvider, ); } +/* highlight-add-end */ ``` Secondly, in your backend router (typically `packages/backend/src/index.ts`) add a route for `/permission` specifying the list of plugin id's that support permissions: ```ts -apiRouter.use( - '/permission', - await permission(permissionEnv, { - // return list static plugin which supports Backstage permissions. - getPluginIds: () => ['catalog', 'scaffolder', 'permission'], - }), -); +// ... +/* highlight-add-next-line */ +import permission from './plugins/permissions'; + +async function main() { + // ... + /* highlight-add-next-line */ + const permissionEnv = useHotMemoize(module, () => createEnv('permission')); + + // ... + /* highlight-add-start */ + apiRouter.use( + '/permission', + await permission(permissionEnv, { + // return list static plugin which supports Backstage permissions. + getPluginIds: () => ['catalog', 'scaffolder', 'permission'], + }), + ); + /* highlight-add-end */ +} ``` ### Identity resolver @@ -96,6 +109,8 @@ permission: - name: group:default/admins ``` +For more information on the available API endpoints, refer to the [API documentation](./docs/apis.md). + ### Configuring policies via file The RBAC plugin also allows you to import policies from an external file. These policies are defined in the [Casbin rules format](https://casbin.org/docs/category/the-basics), known for its simplicity and clarity. For a quick start, please refer to the format details in the provided link. @@ -104,7 +119,7 @@ Here's an example of an external permission policies configuration file named `r ```CSV p, role:default/team_a, catalog-entity, read, deny -p, role:default/team_b, catalog.entity.create, use, deny +p, role:default/team_b, catalog.entity.create, create, deny g, user:default/bob, role:default/team_a @@ -128,6 +143,8 @@ permission: policies-csv-file: /some/path/rbac-policy.csv ``` +For more information on the available permissions within Showcase and RHDH, refer to the [permissions documentation](./docs/permissions.md). + ### Configuring Database Storage for policies The RBAC plugin offers the option to store policies in a database. It supports two database storage options: diff --git a/plugins/rbac-backend/docs/apis.md b/plugins/rbac-backend/docs/apis.md new file mode 100644 index 0000000000..77e16cbfb1 --- /dev/null +++ b/plugins/rbac-backend/docs/apis.md @@ -0,0 +1,411 @@ +# APIs + +## Requirements + +To access the APIs for the RBAC Backend plugin, a user will need to have admin access. Refer to the [README](../README.md#configure-policy-admins) on how to set up admin access. + +Each endpoint also requires an Authorization header with the Bearer token that was generated by Backstage. To access this token, traverse to your deployed instance and inspect the web page. Here are two places and example network calls that will have the Bearer token + +- From the Homepage, the network call `query?term=` + +- From the Catalog, any network call with `entity-facets` + +## Role + +### GET role + +GET + +lists all roles. + +Returns: + +```json +[ + { + "memberReferences": ["user:default/adam"], + "name": "role:default/guests" + }, + { + "memberReferences": ["group:default/janus-authors", "user:default/matt"], + "name": "role:default/test" + } +] +``` + +--- + +GET +ex. + +List the single role and the members associated with that role. + +Request Parameters: + +| Parameter name | Description | Type | +| -------------- | --------------------- | ------ | +| kind | role | String | +| namespace | Namespace of the role | String | +| name | name of the role | String | + +Returns: + +```json +[ + { + "memberReferences": ["group:default/janus-authors", "user:default/matt"], + "name": "role:default/test" + } +] +``` + +--- + +### POST role + +POST + +Creates a new role. + +Request Parameters: + +| Parameter name | Description | Type | +| ---------------- | ---------------------------------------------------------------- | ------ | +| memberReferences | users / groups to be added to the role `:/` | Array | +| name | name of the role | String | + +body: + +```json +{ + "memberReferences": ["group:default/test"], + "name": "role:default/test_admin" +} +``` + +Returns a status code of 201 upon success. + +--- + +### PUT role + +PUT +ex. + +Updates a specified role. + +Request Parameters: + +| Parameter name | Description | Type | +| -------------- | --------------------- | ------ | +| kind | role | String | +| namespace | Namespace of the role | String | +| name | name of the role | String | + +Request Parameters for oldRole and newRole: + +| Parameter name | Description | Type | +| ---------------- | ---------------------------------------------------------------- | ------ | +| memberReferences | users / groups to be added to the role `:/` | Array | +| name | name of the role | String | + +body: + +```json +{ + "oldRole": { + "memberReferences": ["group:default/test"], + "name": "role:default/test_admin" + }, + "newRole": { + "memberReferences": ["group:default/test", "user:default/test2"], + "name": "role:default/test_admin" + } +} +``` + +Returns a status code of 200 upon success. + +--- + +### DELETE role + +DELETE +ex. + +Deletes a single user / group from a role. + +Request Parameters: + +| Parameter name | Description | Type | +| ---------------- | ---------------------------------------------------------------- | ------ | +| kind | role | String | +| namespace | Namespace of the role | String | +| name | name of the role | String | +| memberReferences | users / groups to be added to the role `:/` | String | +| name | name of the role | String | + +before: + +```json +{ + "memberReferences": ["group:default/test, user:default/test2"], + "name": "role:default/test_admin" +} +``` + +after: + +```json +{ + "memberReferences": ["group:default/test"], + "name": "role:default/test_admin" +} +``` + +Returns a status code of 204 upon success. + +--- + +DELETE +ex. + +Deletes a single role and all users associated with that role. + +Request Parameters: + +| Parameter name | Description | Type | +| -------------- | --------------------- | ------ | +| kind | role | String | +| namespace | Namespace of the role | String | +| name | name of the role | String | + +Returns a status code of 204 upon success. + +--- + +## Permission + +### GET permission + +GET + +lists all permission polices. + +Returns: + +```json +[ + { + "entityReference": "role:default/test", + "permission": "catalog-entity", + "policy": "read", + "effect": "allow" + }, + { + "entityReference": "role:default/test", + "permission": "catalog.entity.create", + "policy": "create", + "effect": "allow" + }, + ... +] +``` + +--- + +GET +ex. + +List permission policies related to the specified entity reference `:/`. + +Request parameters: + +| Parameter name | Description | Type | +| -------------- | ----------------------- | ------ | +| kind | Kind of the entity | String | +| namespace | Namespace of the entity | String | +| name | Username of the entity | String | + +Returns: + +```json +[ + { + "entityReference": "role:default/test", + "permission": "catalog-entity", + "policy": "read", + "effect": "allow" + }, + { + "entityReference": "role:default/test", + "permission": "catalog.entity.create", + "policy": "create", + "effect": "allow" + } +] +``` + +--- + +### POST permission + +POST + +Creates a permission policy for a specified entity. + +Request parameters: + +| Parameter name | Description | Type | +| --------------- | ----------------------------------------------------------------------------- | ------ | +| entityReference | Entity `:/` | String | +| permission | Permission from a specific plugin, Resource type or name | String | +| policy | Policy action for the permission, `create`, `read`, `update`, `delete`, `use` | String | +| effect | `allow` or `deny` | String | + +body: + +```json +{ + "entityReference": "role:default/test", + "permission": "catalog-entity", + "policy": "read", + "effect": "allow" +} +``` + +Returns a status code of 201 upon success. + +--- + +### PUT permission + +PUT +ex. + +Updates a permission policy for a specified entity. + +Request parameters: + +| Parameter name | Description | Type | +| -------------- | ----------------------- | ------ | +| kind | Kind of the entity | String | +| namespace | Namespace of the entity | String | +| name | Username of the entity | String | + +Request parameters for oldPolicy and newPolicy objects: + +| Parameter name | Description | Type | +| -------------- | ----------------------------------------------------------------------------- | ------ | +| permission | Permission from a specific plugin, Resource type or name | String | +| policy | Policy action for the permission, `create`, `read`, `update`, `delete`, `use` | String | +| effect | `allow` or `deny` | String | + +body: + +```json +{ + "oldPolicy": { + "permission": "catalog-entity", + "policy": "read", + "effect": "deny" + }, + "newPolicy": { + "permission": "policy-entity", + "policy": "read", + "effect": "allow" + } +} +``` + +Returns a status code of 200 upon success. + +--- + +### Delete permission + +DELETE +ex. + +Deletes a permission policy of a specified entity. + +Request Parameters: + +| Parameter name | Description | Type | +| -------------- | ----------------------------------------------------------------------------- | ------ | +| kind | Kind of the entity | String | +| namespace | Namespace of the entity | String | +| name | Username of the entity | String | +| permission | Permission from a specific plugin, Resource type or name | String | +| policy | Policy action for the permission, `create`, `read`, `update`, `delete`, `use` | String | +| effect | `allow` or `deny` | String | + +Returns a status code of 204 upon success. + +--- + +## Plugin + +### GET plugin permission policies + +GET + +lists all plugin permission policies from plugins installed in your Backstage instance. + +Returns: + +```json +[ + { + "pluginId": "catalog", + "policies": [ + { + "permission": "catalog-entity", + "policy": "read" + }, + { + "permission": "catalog.entity.create", + "policy": "create" + }, + { + "permission": "catalog-entity", + "policy": "delete" + }, + { + "permission": "catalog-entity", + "policy": "update" + }, + { + "permission": "catalog.location.read", + "policy": "read" + }, + { + "permission": "catalog.location.create", + "policy": "create" + }, + { + "permission": "catalog.location.delete", + "policy": "delete" + } + ] + }, + ... +] +``` + +--- + +## HTTP status codes + +| Code | Descriptions | +| ---- | ----------------------------------------------- | +| 200 | Request was successful | +| 201 | New resource was successfully created | +| 204 | No additional content to send in response | +| 400 | Input Error | +| 401 | Lacks valid authentication | +| 403 | Refusal to authorize | +| 404 | Could not find resource | +| 409 | Conflict with current state and target resource | + +--- diff --git a/plugins/rbac-backend/docs/permissions.md b/plugins/rbac-backend/docs/permissions.md new file mode 100644 index 0000000000..3ee9456361 --- /dev/null +++ b/plugins/rbac-backend/docs/permissions.md @@ -0,0 +1,54 @@ +# Example permissions within Showcase / RHDH + +Note: The requirements section primarily pertains to the frontend and may not be strictly necessary for the backend. + +When defining a permission for the RBAC Backend plugin to consume, follow these guidelines: + +- If the permission has a Resource Type, it must be used. Otherwise, use the name of the permission. + + - Example: `p, role:default/test, catalog.entity.read, read, allow` will not be properly picked up. + - Instead, use: `p, role:default/test, catalog-entity, read, allow` + +- If the permission does not have a policy associated with it, use the keyword `use` in its place. + - Example: `p, role:default/test, kubernetes.proxy, use, allow` + +## Catalog + +| Name | Resource Type | Policy | Description | Requirements | +| ----------------------- | -------------- | ------ | ------------------------------------------------------- | ----------------------- | +| catalog.entity.read | catalog-entity | read | Allows the user to read from the catalog | X | +| catalog.entity.create | | create | Allows the user to create catalog entities | catalog.location.create | +| catalog.entity.refresh | catalog-entity | update | Allows the user to refresh one or more catalog entities | catalog.entity.read | +| catalog.entity.delete | catalog-entity | delete | Allows the user to delete one or more catalog entities | catalog.entity.read | +| catalog.location.read | | read | Allows the user to read one or more catalog locations | catalog.entity.read | +| catalog.location.create | | create | Allows the user to create one or more catalog locations | catalog.entity.create | +| catalog.location.delete | | delete | Allows the user to delete one or more catalog locations | catalog.entity.delete | + +## Jenkins + +| Name | Resource Type | Policy | Description | Requirements | +| --------------- | -------------- | ------ | ---------------------------------------------------------- | ------------------- | +| jenkins.execute | catalog-entity | update | Allows the user to execute an action in the Jenkins plugin | catalog.entity.read | + +## Kubernetes + +| Name | Resource Type | Policy | Description | Requirements | +| ---------------- | ------------- | ------ | ----------------------------------------------------------------------------------------------------------- | ------------------- | +| kubernetes.proxy | | | Allows the user to access the proxy endpoint (ability to read pod logs and events within Showcase and RHDH) | catalog.entity.read | + +## RBAC + +| Name | Resource Type | Policy | Description | Requirements | +| -------------------- | ------------- | ------ | ----------------------------------------------------- | ------------ | +| policy.entity.read | policy-entity | read | Allows the user to read permission policies / roles | X | +| policy.entity.create | policy-entity | create | Allows the user to create permission policies / roles | X | +| policy.entity.update | policy-entity | update | Allow the user to update permission policies / roles | X | +| policy.entity.delete | policy-entity | delete | Allow the user to delete permission policies / roles | X | + +## Scaffolder + +| Name | Resource Type | Policy | Description | Requirements | +| ---------------------------------- | ------------------- | ------ | ------------------------------------------------- | ----------------------------------------------------------------- | +| scaffolder.action.execute | scaffolder-action | | Allows the execution of an action from a template | scaffolder.template.parameter.read, scaffolder.template.step.read | +| scaffolder.template.parameter.read | scaffolder-template | read | Allows the user to read parameters of a template | scaffolder.template.step.read | +| scaffolder.template.step.read | scaffolder-template | read | Allows the user to read steps of a template | scaffolder.template.paramater.read |