Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RBAC: enforce permissions in frontend using user roles #986

Merged
merged 25 commits into from
Nov 28, 2024

Conversation

VikaCep
Copy link
Contributor

@VikaCep VikaCep commented Nov 8, 2024

This PR integrates the newly defined roles from #982 into the app. The roles are used to restrict access to different parts of the app where applicable, providing more granular control over permissions and user access.

Resolves https://github.com/grafana/synthetic-monitoring/issues/167

Reader
image

Screen.Recording.2024-11-13.at.17.55.42.mov

Editor
image

Screen.Recording.2024-11-13.at.18.07.33.mov

Admin
image

Screen.Recording.2024-11-13.at.18.10.14.mov

Mixed: Viewer + can write checks
image

Screen.Recording.2024-11-13.at.18.11.37.mov

Mixed: Viewer + can write probes
image
https://github.com/user-attachments/assets/65d268b9-62c8-4a7f-adb5-a7f5381f7c27

@VikaCep VikaCep self-assigned this Nov 8, 2024
@VikaCep VikaCep force-pushed the rbac-permissions-front branch 3 times, most recently from f167e0b to 75b7eb3 Compare November 13, 2024 20:46
@VikaCep VikaCep marked this pull request as ready for review November 13, 2024 21:21
@VikaCep VikaCep requested a review from a team as a code owner November 13, 2024 21:21
@w1kman
Copy link
Contributor

w1kman commented Nov 14, 2024

Note: need to supply Grafana with an enterprise license to review this PR. :)

Copy link
Contributor

@w1kman w1kman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The config page, probably dont need to be visible for non-writers?

Without a basic role (`orgRole), it seems I cannot do much, even if I have SM checks:reader and probe:reader/writer
The only thing that changes are the nav items.

image

When logged in as admin, you can clearly see that the app is already initialized
image

@VikaCep
Copy link
Contributor Author

VikaCep commented Nov 19, 2024

Without a basic role (`orgRole), it seems I cannot do much, even if I have SM checks:reader and probe:reader/writer The only thing that changes are the nav items.

When logged in as admin, you can clearly see that the app is already initialized.

The reason this happens is because if no basic roles are set (at least Viewer), you'd need to add the general datasources:reader permission to the user in order to use the plugin. If Viewer is set, this is not needed.

image
image

I tried to include this permission by default in the custom permissions we define (similar to how I added the plugin:access permission here) to avoid requiring users to manually configure it. However, it doesn't seem to be possible. I suspect the permission is too broad to be auto-granted in the plugin's definition. I wonder if @d0ugal has encountered a similar issue when implementing this in k6.

For reference, this is the error I get when trying to grant datasources:read permission.

grafana-synthetic-monitoring-app | logger=plugins.roles.registration t=2024-11-19T14:32:51.931169754Z level=warn msg="Declare plugin roles failed." pluginId=grafana-synthetic-monitoring-app error="expected action 'datasources:read' to be prefixed with any of '[plugins.app:access grafana-synthetic-monitoring-app: grafana-synthetic-monitoring-app.]'"

In any case, I think the simplest solution is to recommend to always set the Viewer role to get basic permissions, and customize from there on.

@VikaCep VikaCep force-pushed the rbac-permissions-front branch from 75b7eb3 to e9c3969 Compare November 19, 2024 19:24
@VikaCep
Copy link
Contributor Author

VikaCep commented Nov 21, 2024

Without a basic role (`orgRole), it seems I cannot do much, even if I have SM checks:reader and probe:reader/writer The only thing that changes are the nav items.

I've discussed this issue with @d0ugal, as it seems to be a common scenario. If a user is assigned a custom role but lacks the necessary fixed roles required for an action, the custom role alone will not be sufficient. In these cases, it’s important to highlight the missing roles in the UI so that users understand what’s happening and can request the required roles.
As an example, this PR shows how it's handled in k6, by clarifying what are the missing permissions when an action is not allowed.

In Synthetic Monitoring, if a user is not assigned the global datasources: read role then the app won't display any data. This role is a required global permission that must be assigned to users in order for them to use the app (unless the Viewer role is assigned). I’ve updated the message (as shown in the screenshot) to clarify this so that it's not confused with the "app not initialized" state.

Note no datasource:read permission assigned:
image

Note the new error message indicating missing permissions:
image

When the user is assigned the datasources:read permission, then the app can be used, even if no org role is assigned along the custom ones:

Note datasources:read is assigned:
image

Note the app loads correctly:
image

@VikaCep VikaCep requested a review from w1kman November 22, 2024 14:09
Copy link
Contributor

@w1kman w1kman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the fix for a missing base role 🥳
There are some nits that you may or may not wanna change.

src/components/ConfigActions.tsx Outdated Show resolved Hide resolved
src/components/ProgrammaticManagement.tsx Outdated Show resolved Hide resolved
src/hooks/useUserPermissions.ts Outdated Show resolved Hide resolved
src/hooks/useUserPermissions.ts Outdated Show resolved Hide resolved
src/types.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@ckbedwell ckbedwell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've done some testing but need to go through in detail to double-check. Wanted to get the initial review done with some feedback -- looks ace, found a few small things to take a look at.

src/hooks/useUserPermissions.ts Outdated Show resolved Hide resolved
src/components/ProbeCard/ProbeCard.tsx Show resolved Hide resolved
src/test/utils.ts Outdated Show resolved Hide resolved
src/components/ProbeEditor/ProbeEditor.tsx Outdated Show resolved Hide resolved
@@ -39,7 +39,7 @@ const Alerting = () => {
Learn more about alerting for Synthetic Monitoring.
</a>
</p>
{canRead ? <AlertingPageContent /> : <InsufficientPermissions />}
{canReadAlerts ? <AlertingPageContent /> : <InsufficientPermissions />}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I saw the insufficient permissions when I just had the basic 'Viewer' role (I didn't look into why). Should we provide more detail what permissions are missing as there are two places you would need to update to have the right permissions?

Screenshot of the Synthetic Monitoring Alerts page showing the insufficient permissions banner.

Copy link
Contributor Author

@VikaCep VikaCep Nov 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm I'm confused as I'm not sure how you got to that screen.

Users with only the Viewer role assigned, should see this:
image
assigned roles:
image

Users without the Viewer role, but with the Alerts reader role, see the following:
image
assigned roles:
image

The difference lies in that Viewer assigns fixed:alerting:reader by default and without it it needs to be manually added.

@VikaCep VikaCep force-pushed the rbac-permissions-front branch from 588556f to d11f6d4 Compare November 26, 2024 20:32
- instead, we should query permissions from getUserPermissions
@VikaCep VikaCep force-pushed the rbac-permissions-front branch from 64e4f79 to 96541a2 Compare November 26, 2024 22:27
@VikaCep VikaCep requested review from ckbedwell and w1kman November 26, 2024 22:28
const canEditAlertInDs = useDSPermission(`metrics`, `alert.instances.external:write`);

return {
canReadAlerts,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed Query permissions for Viewer in my metrics datasource and I get faced with an infinitely loading spinner. This should be a simple case of checking if there is a value being returned for useMetricsDS() and adding it to the return for each of the canReadAlerts / canWriteAlerts / canDeleteAlerts.

The Alerts page. It shows the Alerts intro text follow by a loading spinner.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch. I've added that check and changed the message to indicate the missing permissions:

image

@VikaCep VikaCep requested a review from ckbedwell November 27, 2024 21:36
@VikaCep VikaCep merged commit 61036cc into rbac-roles Nov 28, 2024
3 checks passed
@VikaCep VikaCep deleted the rbac-permissions-front branch November 28, 2024 14:28
VikaCep added a commit that referenced this pull request Nov 28, 2024
* feat: create useUserPermissions hook

* feat: define PluginPermissions type

* feat: enforce Check permissions using RBAC

* feat: enforce Probe permissions usign RBAC

* feat: enforce Alert permissions using RBAC

* fix: lint

* feat: enforce Config permissions using RBAC

* feat: apply new permissions to plugin installation

* fix: remove console.log

* fix: fallback to basic user roles contemplating roles hierarchy

* fix: change PluginPermission to use write instead of edit

* fix: add tests

* fix: update types for access-tokens permissions

* fix: lint

* fix: tests

* fix: show missing permissions alert

* fix: adjust types to match plugin definitions

* fix: refactor getUserPermissions function

* fix: change plugin permissions to use template literal types

* fix: uppercase RBAC in function names

* fix: updates after rebasing with main

* fix: adapt after rebasing with main

* fix: remove useCanWriteSM hook

- instead, we should query permissions from getUserPermissions

* fix: lint

* fix: check for metrics ds query access in order to display alerts
VikaCep added a commit that referenced this pull request Nov 29, 2024
* feat: create useUserPermissions hook

* feat: define PluginPermissions type

* feat: enforce Check permissions using RBAC

* feat: enforce Probe permissions usign RBAC

* feat: enforce Alert permissions using RBAC

* fix: lint

* feat: enforce Config permissions using RBAC

* feat: apply new permissions to plugin installation

* fix: remove console.log

* fix: fallback to basic user roles contemplating roles hierarchy

* fix: change PluginPermission to use write instead of edit

* fix: add tests

* fix: update types for access-tokens permissions

* fix: lint

* fix: tests

* fix: show missing permissions alert

* fix: adjust types to match plugin definitions

* fix: refactor getUserPermissions function

* fix: change plugin permissions to use template literal types

* fix: uppercase RBAC in function names

* fix: updates after rebasing with main

* fix: adapt after rebasing with main

* fix: remove useCanWriteSM hook

- instead, we should query permissions from getUserPermissions

* fix: lint

* fix: check for metrics ds query access in order to display alerts
VikaCep added a commit that referenced this pull request Dec 3, 2024
* feat: create useUserPermissions hook

* feat: define PluginPermissions type

* feat: enforce Check permissions using RBAC

* feat: enforce Probe permissions usign RBAC

* feat: enforce Alert permissions using RBAC

* fix: lint

* feat: enforce Config permissions using RBAC

* feat: apply new permissions to plugin installation

* fix: remove console.log

* fix: fallback to basic user roles contemplating roles hierarchy

* fix: change PluginPermission to use write instead of edit

* fix: add tests

* fix: update types for access-tokens permissions

* fix: lint

* fix: tests

* fix: show missing permissions alert

* fix: adjust types to match plugin definitions

* fix: refactor getUserPermissions function

* fix: change plugin permissions to use template literal types

* fix: uppercase RBAC in function names

* fix: updates after rebasing with main

* fix: adapt after rebasing with main

* fix: remove useCanWriteSM hook

- instead, we should query permissions from getUserPermissions

* fix: lint

* fix: check for metrics ds query access in order to display alerts
VikaCep added a commit that referenced this pull request Dec 12, 2024
* feat: create useUserPermissions hook

* feat: define PluginPermissions type

* feat: enforce Check permissions using RBAC

* feat: enforce Probe permissions usign RBAC

* feat: enforce Alert permissions using RBAC

* fix: lint

* feat: enforce Config permissions using RBAC

* feat: apply new permissions to plugin installation

* fix: remove console.log

* fix: fallback to basic user roles contemplating roles hierarchy

* fix: change PluginPermission to use write instead of edit

* fix: add tests

* fix: update types for access-tokens permissions

* fix: lint

* fix: tests

* fix: show missing permissions alert

* fix: adjust types to match plugin definitions

* fix: refactor getUserPermissions function

* fix: change plugin permissions to use template literal types

* fix: uppercase RBAC in function names

* fix: updates after rebasing with main

* fix: adapt after rebasing with main

* fix: remove useCanWriteSM hook

- instead, we should query permissions from getUserPermissions

* fix: lint

* fix: check for metrics ds query access in order to display alerts
VikaCep added a commit that referenced this pull request Dec 18, 2024
* feat: define new roles

* feat: add role requirements for routes and pages

* fix: add plugin access permission for all roles

* fix: configure general read/write permissions for ds plugin.json config

* fix: remove redundant granted roles

* fix: improve names and remove token writer access for editors

* fix: rename edit permission

* fix: rename tokens to access-tokens

* fix: restrict config page to writers

* fix: change required permissions to register a ds

* fix: change access-token create for write to match convention

* fix: add missing threshold: delete permission in Threshold Writer role

* fix: change required permissions to see SM home page

* RBAC: enforce permissions in frontend using user roles (#986)

* feat: create useUserPermissions hook

* feat: define PluginPermissions type

* feat: enforce Check permissions using RBAC

* feat: enforce Probe permissions usign RBAC

* feat: enforce Alert permissions using RBAC

* fix: lint

* feat: enforce Config permissions using RBAC

* feat: apply new permissions to plugin installation

* fix: remove console.log

* fix: fallback to basic user roles contemplating roles hierarchy

* fix: change PluginPermission to use write instead of edit

* fix: add tests

* fix: update types for access-tokens permissions

* fix: lint

* fix: tests

* fix: show missing permissions alert

* fix: adjust types to match plugin definitions

* fix: refactor getUserPermissions function

* fix: change plugin permissions to use template literal types

* fix: uppercase RBAC in function names

* fix: updates after rebasing with main

* fix: adapt after rebasing with main

* fix: remove useCanWriteSM hook

- instead, we should query permissions from getUserPermissions

* fix: lint

* fix: check for metrics ds query access in order to display alerts

* fix: lint

* fix: add generic UnauthorizedPage and enforce permissions on home and view pages

* fix: display missing write alerts permission

* fix: lint

* fix: consolidate enable/disable plugin actions into a single write one

* fix: lint

* fix: prevent displaying missing write message to readers

* fix: addressing review comments

* chore: remove ConfigActions as not user after rebase with main

* fix: add message when missing access token write permission

* fix: remove Access Tokens Reader role

* fix: remove access-tokens: read and delete actions

- There's no use for them right now

* fix: list missing permissions to initialize plugin

* fix: change Unauthorized page layout

- Remove card to get rid of hover effect
- Only dispay the relevant message

* fix: restrict terraform access

* fix: lint

* chore: add rbac feature flag

* fix: update test after rebase with main

* fix: change fallback role required to generate access tokens

- When the RBAC FF is off, canWriteTokens requires a min role of Editor to respect current behavior
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants