Skip to content

chore: Minor rbac memory optimization #7391

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 10 commits into from
May 3, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Cache subject AST values to avoid reallocating slices
  • Loading branch information
Emyrk committed May 3, 2023
commit 2bc9c7e680e4d286ed7636a89eac2a34bff8b70b
8 changes: 5 additions & 3 deletions coderd/database/dbauthz/dbauthz.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ var (
},
}),
Scope: rbac.ScopeAll,
}
}.WithCachedASTValue()

subjectAutostart = rbac.Subject{
ID: uuid.Nil.String(),
Roles: rbac.Roles([]rbac.Role{
Expand All @@ -161,7 +162,8 @@ var (
},
}),
Scope: rbac.ScopeAll,
}
}.WithCachedASTValue()

subjectSystemRestricted = rbac.Subject{
ID: uuid.Nil.String(),
Roles: rbac.Roles([]rbac.Role{
Expand All @@ -188,7 +190,7 @@ var (
},
}),
Scope: rbac.ScopeAll,
}
}.WithCachedASTValue()
)

// AsProvisionerd returns a context with an actor that has permissions required
Expand Down
2 changes: 1 addition & 1 deletion coderd/httpmw/apikey.go
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ func ExtractAPIKey(rw http.ResponseWriter, r *http.Request, cfg ExtractAPIKeyCon
Roles: rbac.RoleNames(roles.Roles),
Groups: roles.Groups,
Scope: rbac.ScopeName(key.Scope),
},
}.WithCachedASTValue(),
}

return &key, &authz, true
Expand Down
2 changes: 1 addition & 1 deletion coderd/httpmw/workspaceagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -110,5 +110,5 @@ func getAgentSubject(ctx context.Context, db database.Store, agent database.Work
Roles: rbac.RoleNames(roles.Roles),
Groups: roles.Groups,
Scope: rbac.WorkspaceAgentScope(workspace.ID, user.ID),
}, nil
}.WithCachedASTValue(), nil
}
4 changes: 4 additions & 0 deletions coderd/rbac/astvalue.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ func regoPartialInputValue(subject Subject, action Action, objectType string) (a

// regoValue returns the ast.Object representation of the subject.
func (s Subject) regoValue() (ast.Value, error) {
if s.cachedASTValue != nil {
return s.cachedASTValue, nil
}

subjRoles, err := s.Roles.Expand()
if err != nil {
return nil, xerrors.Errorf("expand roles: %w", err)
Expand Down
14 changes: 14 additions & 0 deletions coderd/rbac/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,20 @@ type Subject struct {
Roles ExpandableRoles
Groups []string
Scope ExpandableScope

// cachedASTValue is the cached ast value for this subject.
cachedASTValue ast.Value
}

// WithCachedASTValue can be called if the subject is static. This will compute
// the ast value once and cache it for future calls.
func (s Subject) WithCachedASTValue() Subject {
tmp := s
v, err := tmp.regoValue()
if err == nil {
tmp.cachedASTValue = v
}
return tmp
}

func (s Subject) Equal(b Subject) bool {
Expand Down
15 changes: 15 additions & 0 deletions coderd/rbac/authz_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,21 @@ func benchmarkUserCases() (cases []benchmarkCase, users uuid.UUID, orgs []uuid.U
Groups: noiseGroups,
},
},
{
Name: "ManyRolesCachedSubject",
Actor: rbac.Subject{
// Admin of many orgs
Roles: rbac.RoleNames{
rbac.RoleOrgMember(orgs[0]), rbac.RoleOrgAdmin(orgs[0]),
rbac.RoleOrgMember(orgs[1]), rbac.RoleOrgAdmin(orgs[1]),
rbac.RoleOrgMember(orgs[2]), rbac.RoleOrgAdmin(orgs[2]),
rbac.RoleMember(),
},
ID: user.String(),
Scope: rbac.ScopeAll,
Groups: noiseGroups,
}.WithCachedASTValue(),
},
{
Name: "AdminWithScope",
Actor: rbac.Subject{
Expand Down