Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat: Add RBAC package for managing user permissions #929

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

Merged
merged 79 commits into from
Apr 13, 2022

Conversation

Emyrk
Copy link
Member

@Emyrk Emyrk commented Apr 8, 2022

What this does

Authorize is the stub function that will be called externally. This is the main entry-point for the package.

#715 , #716, #718, #720, #725

Making a user with given roles

See example_test.go to see how to add multiple roles to a user. SubjectTODO is a placeholder, and roles can be serialized for db storage. Serialization is not implemented until required.

user := authz.SubjectTODO{
	UserID: "alice",
	Roles: []authz.Role{
		authz.RoleOrgAdmin("default"),
		authz.RoleSiteMember,
	},
}

Using Authorize

Authorize is a function on an authorizer. For now, the authorizer just precompiles a builtin rego policy.

For example, to "Read all workspaces in the org Coder", we create a ResourceWorkspace owned by the org Coder

// In practice 'Coder' would be a uuid
authz.Authorize(ctx, user.ID, user.Roles, authz.ActionRead, authz.ResourceWorkspace.InOrg("Coder"))

To read all workspaces across the whole product, we omit the owner id since we want to include the set of all workspaces.

authz.Authorize(ctx, user.ID, user.Roles,  authz.ActionRead, authz.ResourceWorkspace.All())

Making a new Role

Most roles are just * and easy to write. One example of enumerating certain permissions uses a helper function to keep the role as few LoC:

RoleSiteAuditor = Role{
Name: "site-auditor",
Site: permissions(map[ResourceType][]Action{
ResourceAuditLogs: {ActionRead},
// Should be able to read user details to associate with logs.
// Without this the user-id in logs is not very helpful
ResourceUser: {ActionRead},
}),

The helper func omits negative permissions, but those can be defined explicitly. Note that no builtin roles require negative permissions, and are only needed for edge cases that we don't need to support in MVP.

Benchmarks

736 permission checks were done in <300ms. I think this is fast enough.
The rego handles role expansion, which is kinda neat.

Emyrk and others added 30 commits March 31, 2022 15:46
Just testing out some ideas. The code is far from finished, and
very sloppy. Committing to share it to start conversations
Playing around with helper functions to make life easy
- Cleanup some code too
@Emyrk Emyrk marked this pull request as ready for review April 12, 2022 14:55
Copy link
Member

@kylecarbs kylecarbs left a comment

Choose a reason for hiding this comment

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

I think we should change the PR title to something like: feat: Add RBAC package for managing user permissions. This is a big deal!

Comment on lines +23 to +32
query, err := rego.New(
// allowed is the `allow` field from the prepared query. This is the field to check if authorization is
// granted.
rego.Query("allowed = data.authz.allow"),
rego.Module("policy.rego", policy),
).PrepareForEval(ctx)

if err != nil {
return nil, xerrors.Errorf("prepare query: %w", err)
}
Copy link
Member

Choose a reason for hiding this comment

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

Could we do this in init and panic if an error occurs? Then users don't have to hold a struct, and can just call Authorize.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was thinking about that, and I just hate init() functions. I figure we can put the init() anywhere if it's a pain to pass around, meaning we can put the init in coderd somewhere too. So we can decide to init() once we use this.

We will need more PRs for integration, and that is when I think we can make that call.

Copy link
Member

Choose a reason for hiding this comment

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

Fair enough fair enough

@Emyrk Emyrk changed the title feat: Authorize stub function feat: Add RBAC package for managing user permissions Apr 12, 2022
@Emyrk Emyrk mentioned this pull request Apr 12, 2022
10 tasks
@johnstcn johnstcn self-requested a review April 13, 2022 13:27
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.

5 participants