Skip to content
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
pass scope in partial executations
  • Loading branch information
Emyrk committed Sep 22, 2022
commit 2247a72661c29b439c1fc02dbbfca65c85df7db0
12 changes: 9 additions & 3 deletions coderd/rbac/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func NewAuthorizer() (*RegoAuthorizer, error) {
type authSubject struct {
ID string `json:"id"`
Roles []Role `json:"roles"`
Scope Role `json:"scope"`
}

// ByRoleName will expand all roleNames into roles before calling Authorize().
Expand Down Expand Up @@ -122,8 +123,8 @@ func (a RegoAuthorizer) Authorize(ctx context.Context, subjectID string, roles [
"subject": authSubject{
ID: subjectID,
Roles: roles,
Scope: scope,
},
"scope": scope,
"object": object,
"action": action,
}
Expand All @@ -147,7 +148,7 @@ func (a RegoAuthorizer) Authorize(ctx context.Context, subjectID string, roles [

// Prepare will partially execute the rego policy leaving the object fields unknown (except for the type).
// This will vastly speed up performance if batch authorization on the same type of objects is needed.
func (RegoAuthorizer) Prepare(ctx context.Context, subjectID string, roles []Role, scope Scope, action Action, objectType string) (*PartialAuthorizer, error) {
func (RegoAuthorizer) Prepare(ctx context.Context, subjectID string, roles []Role, scope Role, action Action, objectType string) (*PartialAuthorizer, error) {
ctx, span := tracing.StartSpan(ctx)
defer span.End()

Expand All @@ -168,5 +169,10 @@ func (a RegoAuthorizer) PrepareByRoleName(ctx context.Context, subjectID string,
return nil, err
}

return a.Prepare(ctx, subjectID, roles, scope, action, objectType)
scopeRole, err := ScopeRole(scope)
if err != nil {
return nil, err
}

return a.Prepare(ctx, subjectID, roles, scopeRole, action, objectType)
}
2 changes: 1 addition & 1 deletion coderd/rbac/authz_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -741,7 +741,7 @@ func testAuthorize(t *testing.T, name string, subject subject, sets ...[]authTes
assert.Error(t, authError, "expected unauthorized")
}

partialAuthz, err := authorizer.Prepare(ctx, subject.UserID, subject.Roles, ScopeAll, a, c.resource.Type)
partialAuthz, err := authorizer.Prepare(ctx, subject.UserID, subject.Roles, must(ScopeRole(ScopeAll)), a, c.resource.Type)
require.NoError(t, err, "make prepared authorizer")

// Also check the rego policy can form a valid partial query result.
Expand Down
5 changes: 3 additions & 2 deletions coderd/rbac/partial.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,14 +94,15 @@ EachQueryLoop:
return ForbiddenWithInternal(xerrors.Errorf("policy disallows request"), pa.input, nil)
}

func newPartialAuthorizer(ctx context.Context, subjectID string, roles []Role, scope Scope, action Action, objectType string) (*PartialAuthorizer, error) {
func newPartialAuthorizer(ctx context.Context, subjectID string, roles []Role, scope Role, action Action, objectType string) (*PartialAuthorizer, error) {
ctx, span := tracing.StartSpan(ctx)
defer span.End()

input := map[string]interface{}{
"subject": authSubject{
ID: subjectID,
Roles: roles,
Scope: scope,
},
"object": map[string]string{
"type": objectType,
Expand All @@ -112,7 +113,7 @@ func newPartialAuthorizer(ctx context.Context, subjectID string, roles []Role, s
// Run the rego policy with a few unknown fields. This should simplify our
// policy to a set of queries.
partialQueries, err := rego.New(
rego.Query("data.authz.scope_allow = true"),
rego.Query("data.authz.role_allow = true data.authz.scope_allow = true"),
rego.Module("policy.rego", policy),
rego.Unknowns([]string{
"input.object.owner",
Expand Down
2 changes: 1 addition & 1 deletion coderd/rbac/policy.rego
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ number(set) = c {
default site = 0
site := site_allow(input.subject.roles)
default scope_site := 0
scope_site := site_allow([input.scope])
scope_site := site_allow([input.subject.scope])

site_allow(roles) := num {
# allow is a set of boolean values without duplicates.
Expand Down