Skip to content

Commit 46f9a84

Browse files
committed
Prepare in the same place as the normal rego policy
1 parent 891ecc5 commit 46f9a84

File tree

2 files changed

+27
-32
lines changed

2 files changed

+27
-32
lines changed

coderd/rbac/authz.go

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,8 @@ func Filter[O Objecter](ctx context.Context, auth Authorizer, subject Subject, a
139139

140140
// RegoAuthorizer will use a prepared rego query for performing authorize()
141141
type RegoAuthorizer struct {
142-
query rego.PreparedEvalQuery
142+
query rego.PreparedEvalQuery
143+
partialQuery rego.PreparedPartialQuery
143144

144145
authorizeHist *prometheus.HistogramVec
145146
prepareHist prometheus.Histogram
@@ -151,9 +152,10 @@ var (
151152
// Load the policy from policy.rego in this directory.
152153
//
153154
//go:embed policy.rego
154-
policy string
155-
queryOnce sync.Once
156-
query rego.PreparedEvalQuery
155+
policy string
156+
queryOnce sync.Once
157+
query rego.PreparedEvalQuery
158+
partialQuery rego.PreparedPartialQuery
157159
)
158160

159161
func NewAuthorizer(registry prometheus.Registerer) *RegoAuthorizer {
@@ -166,6 +168,21 @@ func NewAuthorizer(registry prometheus.Registerer) *RegoAuthorizer {
166168
if err != nil {
167169
panic(xerrors.Errorf("compile rego: %w", err))
168170
}
171+
172+
partialQuery, err = rego.New(
173+
rego.Unknowns([]string{
174+
"input.object.id",
175+
"input.object.owner",
176+
"input.object.org_owner",
177+
"input.object.acl_user_list",
178+
"input.object.acl_group_list",
179+
}),
180+
rego.Query("data.authz.allow = true"),
181+
rego.Module("policy.rego", policy),
182+
).PrepareForPartial(context.Background())
183+
if err != nil {
184+
panic(xerrors.Errorf("compile partial rego: %w", err))
185+
}
169186
})
170187

171188
// Register metrics to prometheus.
@@ -207,7 +224,8 @@ func NewAuthorizer(registry prometheus.Registerer) *RegoAuthorizer {
207224
})
208225

209226
return &RegoAuthorizer{
210-
query: query,
227+
query: query,
228+
partialQuery: partialQuery,
211229

212230
authorizeHist: authorizeHistogram,
213231
prepareHist: prepareHistogram,
@@ -289,7 +307,7 @@ func (a RegoAuthorizer) Prepare(ctx context.Context, subject Subject, action Act
289307
)
290308
defer span.End()
291309

292-
prepared, err := newPartialAuthorizer(ctx, subject, action, objectType)
310+
prepared, err := a.newPartialAuthorizer(ctx, subject, action, objectType)
293311
if err != nil {
294312
return nil, xerrors.Errorf("new partial authorizer: %w", err)
295313
}

coderd/rbac/partial.go

Lines changed: 3 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -127,24 +127,7 @@ EachQueryLoop:
127127
pa.subjectInput, pa.subjectAction, pa.subjectResourceType, nil)
128128
}
129129

130-
// Precompiled values to be reused for each Prepare call.
131-
// These values are static and do not change.
132-
var (
133-
// unknownTerms are the unknown values in the rego input.
134-
// These values are pre-parsed to prevent reparsing on every Prepare call.
135-
unknownTerms = []*ast.Term{
136-
ast.MustParseTerm("input.object.id"),
137-
ast.MustParseTerm("input.object.owner"),
138-
ast.MustParseTerm("input.object.org_owner"),
139-
ast.MustParseTerm("input.object.acl_user_list"),
140-
ast.MustParseTerm("input.object.acl_group_list"),
141-
}
142-
143-
partialQuery = ast.MustParseBody("data.authz.allow = true")
144-
policyModule = ast.MustParseModule(policy)
145-
)
146-
147-
func newPartialAuthorizer(ctx context.Context, subject Subject, action Action, objectType string) (*PartialAuthorizer, error) {
130+
func (a RegoAuthorizer) newPartialAuthorizer(ctx context.Context, subject Subject, action Action, objectType string) (*PartialAuthorizer, error) {
148131
if subject.Roles == nil {
149132
return nil, xerrors.Errorf("subject must have roles")
150133
}
@@ -157,14 +140,8 @@ func newPartialAuthorizer(ctx context.Context, subject Subject, action Action, o
157140
return nil, xerrors.Errorf("prepare input: %w", err)
158141
}
159142

160-
// Run the rego policy with a few unknown fields. This should simplify our
161-
// policy to a set of queries.
162-
partialQueries, err := rego.New(
163-
rego.ParsedQuery(partialQuery),
164-
rego.ParsedModule(policyModule),
165-
rego.ParsedUnknowns(unknownTerms),
166-
rego.ParsedInput(input),
167-
).Partial(ctx)
143+
partialQueries, err := a.partialQuery.Partial(ctx, rego.EvalParsedInput(input))
144+
168145
if err != nil {
169146
return nil, xerrors.Errorf("prepare: %w", err)
170147
}

0 commit comments

Comments
 (0)