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

feat(admin): implement basic admin user roles #3522

Merged
merged 4 commits into from
Jan 12, 2023

Conversation

MeredithAnya
Copy link
Member

@MeredithAnya MeredithAnya commented Dec 15, 2022

context:
The access to the snuba admin tool right now for SaaS is determined via google IAP which is great for all or nothing access but doesn't really allow for more granular permissions. The reason that we want more granular permissions is so that we can open up parts admin tooling to more folks (outside the SNS team) without giving access to everything

Roles
I've added the concept of roles to the admin user. A role has two properties:

  • name - the name of the role
  • actions - the actions a user is allowed to take on specified resources, for migrations this would be the actions they could take on a migration(s) within a migration group

Actions
Actions correspond to specific resources, instead of generic actions that apply to all resources. Custom actions can be implemented for each category (e.g. "migrations" resource has the MigrationsAction) and those can be further split up in specific actions within a category

[EDIT]: Instead of scopes, the actions within a role map to a policy. e.g. ExecuteNonBlockingAction would correspond to the NonBlockingMigrationsPolicy.
Scopes will be used to map to migration polices - this PR https://github.com/getsentry/snuba/pull/3543/files builds off of this one to do just that.

This PR adds the roles to the user but doesn't do any checking of the roles. This will come later when implementing this for migrations.

@MeredithAnya MeredithAnya marked this pull request as ready for review December 19, 2022 19:20
@MeredithAnya MeredithAnya requested a review from a team as a code owner December 19, 2022 19:20
MEMBER_READ = "member_read"


ADMIN_CATEGORY_RESOURCES = {
Copy link
Member

Choose a reason for hiding this comment

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

Would it be possible/worth it to generate this list automatically from the migration groups in code?

Copy link
Contributor

Choose a reason for hiding this comment

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

+1, we should not have to add a new scope in the admin tool code each time we add a new migration group. That is something product teams do.

@lynnagara
Copy link
Member

lynnagara commented Dec 21, 2022

Lgtm though I think @dbanda may want to take a look as I saw some offline conversations about this.

Where will the user -> group -> role -> category -> resource mappings be kept? Can you give a rough idea of how you imagine this configuration would look/be managed?

Copy link
Contributor

@fpacifici fpacifici left a comment

Choose a reason for hiding this comment

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

If somebody uses the migrations tool without going through the admin, should we have an equivalent permissions model ?

MEMBER_READ = "member_read"


ADMIN_CATEGORY_RESOURCES = {
Copy link
Contributor

Choose a reason for hiding this comment

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

+1, we should not have to add a new scope in the admin tool code each time we add a new migration group. That is something product teams do.

Comment on lines 26 to 32
class AuthScope:
category: str
resource: str
role: AdminRole

def to_str(self) -> str:
return f"{self.category}.{self.resource}.{self.role.value}"
Copy link
Contributor

Choose a reason for hiding this comment

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

I am a bit confused about this model.
As I mentioned on the notion doc, most role based access system have at least three entities:

  • resources
  • actions
  • principals / roles

There generally is a relationship of ownership between a role, and action and a resource so that a role is granted the permission to execute the action on a resource.
Then you assign roles to a person.

Here I think the resource is composed by the pair category + resource. Is this correct ?
I cannot see the action in this model.
Also does the scope represent the relationship between the three ?

Since these concepts in role based access control are generally familiar to developers I would suggest we stick to them without introducing new ones. That makes it much easier for somebody who does not know the snuba admin to pick them up without having to understand the custom model.

return scopes


ADMIN_SCOPES = scopes()
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks like it will generate all permutations of scopes for each resource and admin role. Is there a reason why this is done? It looks like the only place ADMIN_SCOPES is used is in _set_scopes() which will assign all these scopes to the user. Was that intentional?

@codecov-commenter
Copy link

codecov-commenter commented Jan 9, 2023

Codecov Report

Base: 92.19% // Head: 92.46% // Increases project coverage by +0.27% 🎉

Coverage data is based on head (c552b5e) compared to base (c92c14b).
Patch coverage: 94.66% of modified lines in pull request are covered.

❗ Current head c552b5e differs from pull request most recent head 050c861. Consider uploading reports for the commit 050c861 to get more accurate results

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3522      +/-   ##
==========================================
+ Coverage   92.19%   92.46%   +0.27%     
==========================================
  Files         726      734       +8     
  Lines       33790    34019     +229     
==========================================
+ Hits        31152    31456     +304     
+ Misses       2638     2563      -75     
Impacted Files Coverage Δ
snuba/cli/subscriptions_scheduler.py 0.00% <0.00%> (ø)
snuba/datasets/configuration/json_schema.py 100.00% <ø> (ø)
snuba/datasets/slicing.py 88.88% <ø> (ø)
snuba/datasets/storage.py 94.02% <ø> (+0.69%) ⬆️
snuba/datasets/entities/generic_metrics.py 97.91% <50.00%> (+0.04%) ⬆️
snuba/datasets/pluggable_entity.py 94.11% <87.50%> (-1.05%) ⬇️
snuba/subscriptions/scheduler.py 96.38% <88.46%> (-1.51%) ⬇️
snuba/admin/auth_roles.py 92.10% <92.10%> (ø)
...ba/datasets/entities/storage_selectors/sessions.py 92.59% <92.59%> (ø)
...nuba/datasets/entities/storage_selectors/errors.py 93.33% <93.33%> (ø)
... and 38 more

Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here.

☔ View full report at Codecov.
📢 Do you have feedback about the report comment? Let us know in this issue.

Copy link
Contributor

@fpacifici fpacifici left a comment

Choose a reason for hiding this comment

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

I like this model more than the previous one.
I would consider renaming the action so that they are more explicit about the policy they would adopt.


class Action(Enum):
EXECUTE = "execute"
LIMITED_EXECUTE = "limited_execute"
Copy link
Contributor

Choose a reason for hiding this comment

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

Have you considered calling the actions in the same way as the policy ?

@MeredithAnya MeredithAnya changed the title feat(admin): implement basic admin user scopes feat(admin): implement basic admin user roles Jan 11, 2023
Copy link
Contributor

@dbanda dbanda left a comment

Choose a reason for hiding this comment

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

LGTM

pass


# todo, shoudln't need .keys() once ADMIN_ALLOWED_MIGRATION_GROUPS is a set not dict
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
# todo, shoudln't need .keys() once ADMIN_ALLOWED_MIGRATION_GROUPS is a set not dict
# todo, `shouldn't` need .keys() once ADMIN_ALLOWED_MIGRATION_GROUPS is a set not dict

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.

6 participants