Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

chore: authz 'any_org' to return if at least 1 org has perms#14009

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
Emyrk merged 8 commits intomainfromstevenmasley/authcheck_any_org
Jul 30, 2024

Conversation

Emyrk
Copy link
Member

@EmyrkEmyrk commentedJul 25, 2024
edited
Loading

What this does

The UI needs to ask the question, "Can this user create a template?". This question is now complicated withmulti-organizations, since the answer is true if the user can create the template in any org they are a member of.

The UI today would have to on every page:

  • Fetch all organizations
  • Loop over the organizations, create a/authcheck for each org for create template
    • Add create template at the site wide too for site admins

This feels like it could add to the number of db queries for a question that doesn't actually require the database. This question can be answered entirely by the policy in memory, since it has the roles and permissions.

So I added a field to an object calledany_org, that when specified makes the policy return "true" for theorg_allow section if any organization would return a truthy value.

This is a policy change, however we can rely on our extensive rbac testing to avoid regressions.

Closes#14003

Alternative

Rego supports, and we use, partial queries. This is possible with 0 modification of the original policy, meaning we do not need to input this as a first class feature.This was the original plan.

The problem with this plan, is the resulting query to inspect and determine if we should return true/false looks something like:

+---------+---------------------------------------------------------------------------------+| Query 1 | "5750d635-82e0-4681-bd44-815b18669d65" = input.object.org_owner                 |+---------+---------------------------------------------------------------------------------+| Query 2 | input.object.org_owner != ""                                                    ||         | input.object.org_owner in {"5750d635-82e0-4681-bd44-815b18669d65"}              ||         | "create" in input.object.acl_group_list["b617a647-b5d0-4cbe-9e40-26f89710bf18"] |+---------+---------------------------------------------------------------------------------+| Query 3 | input.object.org_owner != ""                                                    ||         | input.object.org_owner in {"5750d635-82e0-4681-bd44-815b18669d65"}              ||         | "*" in input.object.acl_group_list["b617a647-b5d0-4cbe-9e40-26f89710bf18"]      |+---------+---------------------------------------------------------------------------------+| Query 4 | input.object.org_owner != ""                                                    ||         | input.object.org_owner in {"5750d635-82e0-4681-bd44-815b18669d65"}              ||         | "create" in input.object.acl_group_list[input.object.org_owner]                 |+---------+---------------------------------------------------------------------------------+| Query 5 | input.object.org_owner != ""                                                    ||         | input.object.org_owner in {"5750d635-82e0-4681-bd44-815b18669d65"}              ||         | "*" in input.object.acl_group_list[input.object.org_owner]                      |+---------+---------------------------------------------------------------------------------+| Query 6 | "create" in input.object.acl_user_list["10d03e62-7703-4df5-a358-4f76577d4e2f"]  |+---------+---------------------------------------------------------------------------------+| Query 7 | "*" in input.object.acl_user_list["10d03e62-7703-4df5-a358-4f76577d4e2f"]       |+---------+---------------------------------------------------------------------------------+

There is two ways to take this output and make it useful.

Conduct some AST analysis and figure out if there exists andorg_id in which at least 1 query returns true. Thisfeels trivialas long as our output ASTs remain static. Any policy change could probably break any first draft AST analysis.FRAGILE

^--- That would be my choice given unlimited time

The second idea is to execute the queries with various inputs. We caneval() each query with a differentinput.object, and some weak ast analysis could probably pick out someuuids to throw back in. This would use proper rego evaluation, and bestrong and consistent against changes. This however would result in some loop of execution, becoming a O(n) problem.

In the end, if we are going to use regoeval() to conclude the result, it makes the most optimization sense just to bake this into the policy itself. Determine the result on the first eval(), rather than trying to rig up something externally.

Allows checking if a user can do an action in any organization,rather than a specific one. Allows asking general questions on theUI to determine which elements to show.
@EmyrkEmyrk marked this pull request as draftJuly 25, 2024 02:17
@EmyrkEmyrk marked this pull request as ready for reviewJuly 25, 2024 11:30
Comment on lines +594 to +606
{
Name: "CreateTemplateAnyOrg",
Actions: []policy.Action{policy.ActionCreate},
Resource: rbac.ResourceTemplate.AnyOrganization(),
AuthorizeMap: map[bool][]hasAuthSubjects{
true: {owner, templateAdmin, orgTemplateAdmin, otherOrgTemplateAdmin, orgAdmin, otherOrgAdmin},
false: {
userAdmin, memberMe,
orgMemberMe, orgAuditor, orgUserAdmin,
otherOrgMember, otherOrgAuditor, otherOrgUserAdmin,
},
},
},
Copy link
Member

Choose a reason for hiding this comment

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

Can you extend these tests to other organization-scoped RBAC objects?
I tried this out for workspaces and ran into behaviour I didn't expect:

{Name:     "CreateWorkspaceAnyOrg",Actions:  []policy.Action{policy.ActionCreate},Resource: rbac.ResourceWorkspace.AnyOrganization(),AuthorizeMap: map[bool][]hasAuthSubjects{true: {owner, orgAdmin, otherOrgAdmin, orgMemberMe},false: {memberMe, userAdmin, templateAdmin,orgAuditor, orgUserAdmin, orgTemplateAdmin,otherOrgMember, otherOrgAuditor, otherOrgUserAdmin, otherOrgTemplateAdmin,},},},
    --- FAIL: TestRolePermissions/CreateWorkspaceAnyOrg (0.01s)        roles_test.go:675:                 Error Trace:    /workspaces/coder/coderd/rbac/roles_test.go:675                Error:          Received unexpected error:                                rbac: forbidden: (subject: { f8981f20-e4cc-4be9-a14c-c391200d086e [member organization-member:2c498c97-8c96-4742-9e37-3cd431780fd3] [] all <nil>}), (action: create), (object: {   true workspace map[] map[]}), (output: [])                Test:           TestRolePermissions/CreateWorkspaceAnyOrg                Messages:       Should pass: CreateWorkspaceAnyOrg as "org_member_me" doing "create" on "workspace"

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I can add more tests for sure. The test you wrote is missing withWithOwner. The test as is, asks the question "Can I create a workspace in any organization that is not owned by me?"

The correct question to see if you can make a workspace belonging to yourself is:

rbac.ResourceWorkspace.AnyOrganization().WithOwner(currentUser.String())

The reason the test without the owner works for some roles, is because owners and org admins are able to create workspaces on behalf of other users

Copy link
Member

@johnstcnjohnstcnJul 26, 2024
edited
Loading

Choose a reason for hiding this comment

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

Ah whoops 👍 I'm still holding the package wrong!

Emyrk reacted with thumbs up emoji
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

It's not perfect for sure. Maybe there is some api wrapper that could exist that translates everything into some more readable language 🤷‍♂️.

I agree it's nuanced

Copy link
Member

Choose a reason for hiding this comment

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

I checked the RBAC benchmarks before/after and didn't see any concerning differences here 👍

Emyrk reacted with thumbs up emoji
count(org_members) > 0
}


Copy link
Member

Choose a reason for hiding this comment

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

Suggested change

Copy link
Member

@johnstcnjohnstcn left a comment

Choose a reason for hiding this comment

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

We need to beextremely careful of how we useAnyOrgOwner. I could see accidental usage of this indbauthz or similar causing a permissions bug. As this is primarily meant for the UI, it might be good as a follow-up to add a linter for any usage of this outside therbac package in Go, or in the endpoint for checking permissions.

@Emyrk
Copy link
MemberAuthor

We need to beextremely careful of how we useAnyOrgOwner. I could see accidental usage of this indbauthz or similar causing a permissions bug. As this is primarily meant for the UI, it might be good as a follow-up to add a linter for any usage of this outside therbac package in Go, or in the endpoint for checking permissions.

Good idea with the linter. I agree it should be protected somehow

@EmyrkEmyrk merged commit3209c86 intomainJul 30, 2024
33 checks passed
@EmyrkEmyrk deleted the stevenmasley/authcheck_any_org branchJuly 30, 2024 00:58
@github-actionsgithub-actionsbot locked and limited conversation to collaboratorsJul 30, 2024
Sign up for freeto subscribe to this conversation on GitHub. Already have an account?Sign in.
Reviewers

@johnstcnjohnstcnjohnstcn approved these changes

@spikecurtisspikecurtisAwaiting requested review from spikecurtis

Assignees

@EmyrkEmyrk

Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

Authchecks in the UI are static tosite scope, needs to handle organization scope for multi-org
2 participants
@Emyrk@johnstcn

[8]ページ先頭

©2009-2025 Movatter.jp