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: Update rego to be partial execution friendly#3449

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 30 commits intomainfromstevenmasley/rbac_update_rego
Aug 11, 2022

Conversation

Emyrk
Copy link
Member

@EmyrkEmyrk commentedAug 10, 2022
edited
Loading

What this does

Updates to a new rego policy that passes all the same tests. The new rego policy can be partially evaluated into simple queries. A unit was added to ensure the new policy always can be converted into these simple queries.

Performance

This does not affect performance when authorizing a single object. It only affects when usingFilter.

Below is theFilter as is, vs the new filtering usingPartial evaluation to optimize subsequent Auth() calls. Note this benchmark is using the new rego policy. The PR#3426 is using adifferent rego policy. So the benchmarks are expected to be different.

cpu: Intel(R) Core(TM) i7-6770HQ CPU @ 2.60GHzBenchmarkRBACFilter/NoRoles-8              11178      104742 ns/op       44944 B/op      804 allocs/opBenchmarkRBACFilter/Admin-8                 3532      314068 ns/op      101511 B/op      101 allocs/opBenchmarkRBACFilter/OrgAdmin-8              3636      305136 ns/op       99223 B/op      997 allocs/opBenchmarkRBACFilter/OrgMember-8             3472      318597 ns/op      101057 B/op      151 allocs/opBenchmarkRBACFilter/ManyRoles-8             2389      527514 ns/op      161426 B/op      404 allocs/opBenchmarkRBACFilter/NoRolesQueries-8              901699              1332 ns/op             137 B/op          3 allocs/opBenchmarkRBACFilter/AdminQueries-8               2222412               636.1 ns/op           276 B/op          0 allocs/opBenchmarkRBACFilter/OrgAdminQueries-8              29290             39604 ns/op           16264 B/op        305 allocs/opBenchmarkRBACFilter/OrgMemberQueries-8             32221             36196 ns/op           14039 B/op        264 allocs/opBenchmarkRBACFilter/ManyRolesQueries-8             43754             27587 ns/op           12949 B/op        243 allocs/op

Correctness

RBAC has a pretty good test suite, so I can pretty confidently say the behavior matches what we had before. Meaning false positives/negatives should not occur.

Notes

There is a difference between rego'sPartial andPartialResult.PartialResult does not optimize in the same wayPartial does. The reasonPartial is much faster, is that the policy converts down to a set of queries based on the unknown fields (our new rego policy is designed to compress to these queries!)

opa eval --partial --format=pretty 'data.authz.allow = true' -d policy.rego --unknowns input.object.owner --unknowns input.object.org_owner -i input.json

+---------+--------------------------------------------------------------------+| Query 1 | input.object.org_owner != ""                                       ||         | input.object.org_owner in {"feda2e52-8bf1-42ce-ad75-6c5595cb297a"} ||         | "me" = input.object.owner                                          |+---------+--------------------------------------------------------------------+| Query 2 | input.object.org_owner = ""                                        ||         | "me" = input.object.owner                                          |+---------+--------------------------------------------------------------------+

The number of queries and the content of the queries depends on the user's roles. The intention is to convert these queries into SQLWHERE clauses combined by anOR. Until we do that, we need to run through the queries ourselves, which as seen in the last benchmark, is quite fast.

@EmyrkEmyrk marked this pull request as ready for reviewAugust 10, 2022 20:22
@@ -11,24 +11,35 @@ import (

type Authorizer interface {
ByRoleName(ctx context.Context, subjectID string, roleNames []string, action Action, object Object) error
PrepareByRoleName(ctx context.Context, subjectID string, roles []string, action Action, objectType string) (PreparedAuthorized, error)
Copy link
Member

Choose a reason for hiding this comment

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

This function is only used internally, so seems like it might not need to be exported like this.

Copy link
MemberAuthor

@EmyrkEmyrkAug 10, 2022
edited
Loading

Choose a reason for hiding this comment

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

I need it for my Fake authorizer to work for some unit tests. I can't fake it without an interface☹️

recordingAuthorizer always returns false and save the auth calls so I can assert them in my tests.

kylecarbs reacted with thumbs up emoji
return objects, nil
}
objecType := objects[0].RBACObject().Type
objects, err := rbac.Filter(r.Context(), api.Authorizer, roles.ID.String(), roles.Roles, action, objecType, objects)
Copy link
Member

Choose a reason for hiding this comment

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

Seems like all of this logic could be in therbac package itself, then we wouldn't need therecordingAuthorizer code. Then functions could just callrbac.AuthorizeFilter directly.

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

You are right about the object type stuff 👍

As forrecordingAuthorizer. That is needed for my unit test that checks all the routes.recordingAuthorizer is never used outside unit tests.

@@ -11,24 +11,35 @@ import (

type Authorizer interface {
ByRoleName(ctx context.Context, subjectID string, roleNames []string, action Action, object Object) error
PrepareByRoleName(ctx context.Context, subjectID string, roles []string, action Action, objectType string) (PreparedAuthorized, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see any use case for exposing thePreparedAuthorized to consumers of authorization --- why not just expose the Filter() method here?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I wish I could, but you can't make generic methods on structs. The nice thing about the genericFilter() method is you can pass in and return the same typed slice.

If I made it a non-generic function, you'd have to take your slice of[]Workspace, convert it to[]rbac.Object, and then convert it back to[]Workspace. I could do this all in somerbac.Authorize, but it takes a lot of slice copying I prefer to avoid.

Copy link
Contributor

Choose a reason for hiding this comment

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

Well, that sucks. Go generics continue to disappoint.

Emyrk reacted with confused emoji
Copy link
MemberAuthor

Choose a reason for hiding this comment

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

Yea, it's really dumb because I don't see why it's not possible. Like I would like to know the objection to it.

@@ -1209,7 +1209,7 @@ func TestPaginatedUsers(t *testing.T) {
t.Parallel()

// This test takes longer than a long time.
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong*2)
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong*3)
Copy link
Contributor

Choose a reason for hiding this comment

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

why did we increase timeout if we decreased RBAC time?

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

I am unsure why this test was timing out. I can spend more time and look into it

Copy link
MemberAuthor

Choose a reason for hiding this comment

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

This test takes <3s on my local machine. I have no clue why it was timing out... going to drop back to *2 and see what I get.

@EmyrkEmyrkenabled auto-merge (squash)August 11, 2022 22:00
@EmyrkEmyrk merged commit3ae42f4 intomainAug 11, 2022
@EmyrkEmyrk deleted the stevenmasley/rbac_update_rego branchAugust 11, 2022 22:07
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment
Reviewers

@kylecarbskylecarbskylecarbs left review comments

@spikecurtisspikecurtisspikecurtis approved these changes

Assignees
No one assigned
Labels
None yet
Projects
None yet
Milestone
No milestone
Development

Successfully merging this pull request may close these issues.

3 participants
@Emyrk@spikecurtis@kylecarbs

[8]ページ先頭

©2009-2025 Movatter.jp