-
Notifications
You must be signed in to change notification settings - Fork 5.6k
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
feat: allow permission checks for signals #23171
base: master
Are you sure you want to change the base?
Conversation
Changed Packages
|
Uffizzi Ephemeral Environment - Virtual ClusterYour cluster
Access the |
continue; | ||
} | ||
|
||
const decisions = await this.permissions.authorize(permissions, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this check be done in the plugin sending the event instead? 🤔
What's the advantage of passing the plain permissions, performing the check at signals-backend
level?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not possible as the signals can have many receivers. Of course, if you send the signal to only the current user, the permission check can be done in the sender end. An example for this:
- DevTools wants to broadcast updates to info data (CPU/mem usage etc.) for all users at the
devtools
page - To see the info in the first place, the user must have
devToolsInfoReadPermission
devtools-backend
cannot see which users have subscribed to the signals- Thus the permission must be checked during sending and not in the
devtools-backend
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not possible as the signals can have many receivers
ah I see, thank you for clarifying!
How does the subscription flow work? For instance, as a Backstage user, how can I subscribe to updates for the devtools' plugin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or maybe even better, here's PR for devtools that explains it in code: #23194 :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thank you so much. It makes sense.
Do you have any suggestions about how to potentially deal with an expired client token here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a bit of a hard thing to do. One option would be to send the token via websocket channel instead in headers and refresh it on the client side when needed. I have to think about this a bit but I think it's in another PR. If you guys have ideas, they are more than welcome 🙏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Briefly mentioned in #23194, but I wonder if it's better to authorize permissions when subscribing to a signal channel? Just to avoid hammering the permissions backend for small frequent signals. That could also come with the added benefit that an up-to-date user token can be included in that request, fixing the token expiration problem.
Since there's no concept of persistent channels with metadata or anything like that, the permission would simply have to be matched against permissions required when sending a signal later on. i.e. if a user subscribes to channel example.a
with permission example.read
, then the signal backend would allow signals through on that channel that either do not require any permission, or require example.read
, signals with any other permission would be rejected.
I think that flow might have the additional benefit that we can set up a request/response flow for the signal subscription where the frontend can get feedback on whether the user has permission or not. Ofc you'd usually want to check that upfront in the frontend with a separate check, but with this the failure mode can be a bit better than just complete silence, even if we just forward permissions errors to the ErrorApi
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem with this is exactly with the channels as the signal manager does not know which channel would require which kind of permission. IMHO I don't think it's a good idea to mix the channel name with permissions as it:
- Gets really confusing to the signal sender as they have to match the permission name and the signal channel. This can lead to errors especially when refactoring things
- Doesn't allow resource permission checks. For example, some plugins might want to send information in the same channel about different resources and with this architecture, it's not possible
For the performance issue you mentioned in the other PR, I think this should be taken care of in the PermissionService
instead. Checking the same access rights multiple times for the same token should be very fast as it happens also in other places in the system. Another option would be to cache the authorization results per connection but I think that's not the right way to go either as it only applies to signals.
Personally, I would like to keep this as light as possible in the frontend side, you can subscribe to anything but there's no guarantee that you will ever get data from that channel.
this requires backstage#23171 for permission checks Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution! |
Not stale, needs a rebase |
97df5a9
to
0cd2322
Compare
this requires backstage#23171 for permission checks Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
this requires backstage#23171 for permission checks Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
0cd2322
to
7c751f8
Compare
this requires backstage#23171 for permission checks Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution! |
Hi! Sorry but there's a conflict now. |
Hey, will check once back at the hotel |
7c751f8
to
044e089
Compare
This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution! |
Not stale |
This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution! |
Not stale |
This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll put my tentative approval on here. With the caveats that:
- Indeed token expiration must be handled. Maybe re-send the credentials over the channel, or simply re-establish. The latter sounds simpler, it's not like it happens all that often.
- Likewise, the new
userInfo
service should be used for getting ownership refs, and you want to re-fetch those periodically. If you re-establishment of the connection as per above, then that happens over and over by design, but otherwise you'll want a slow loop to update it over time - I don't have a strong opinion on where and when the permissions are checked. I'll leave that to your discretion to choose. If it can be done early, then @Rugvip is right that that feels more robust and clear, and afaik matches how subscriptions work in pubsub systems out there etc. But it's also to some degree a "UX optimization issue" and can be changed to be more strict in the future, right? Even though it's technically a breaking change
But maybe those can all be iterated on separately.
This also needs a rebase. And it would be good to have a few 👀 from @vinzscam and @Rugvip once more
044e089
to
41febf7
Compare
Rebased |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like bringing authentication support to signals brought some technical issues that it would be nice to address. As pointed out it would be nice to check the permissions at subscription time. If the current implementation of signals doesn’t allow us to do this, perhaps something can be improved in the design of the current signal solution? Shall we have a design session in order to see if it is possible to revisit and improve the overall design of signals/events?
@vinzscam the problem with subscription time checks is that we don't know the topics sent through signals at that time. This would require the backend plugins to register their topics before sending signals to them with necessary access rights. Of course, this is possible but would mean some extra steps for the signal sender. |
Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
41febf7
to
7e0aeec
Compare
@vinzscam I added a new way to register channels to the Signals that can include the permissions needed to subscribe to that channel. This way we can handle the checks during subscription phase for signals that need permissions. Adds a bit more complexity but I think there's not so many cases we need the permissions, maybe :) |
Sorry but there are conflicts. Maybe after the release tomorrow there'll be some more - could rebase after that perhaps |
Yeah, I'll rebase after the release! |
Hmm, after thinking about this, it will not work if there are multiple nodes running the backend and some of them are restarted individually as it will lose all channel registrations. One option would be to have a database for the channels but that would require a bit more changes and I am not sure if that's a better option either. The first version of this where the permissions were sent as part of the signal didn't have this kind of issue but of course, it requires a bit more runtime resources as the permissions need to be checked for each signal individually. Have to think what would be the best course for this. |
This PR has been automatically marked as stale because it has not had recent activity from the author. It will be closed if no further activity occurs. If the PR was closed and you want it re-opened, let us know and we'll re-open the PR so that you can continue the contribution! |
Not stale |
Hey, I just made a Pull Request!
This allows the signal payload to have permissions check included for things that require it.
✔️ Checklist
Signed-off-by
line in the message. (more info)