chore: Optimize rego policy input allocations (#6135)

* chore: Optimize rego policy evaluation allocations

Manually convert to ast.Value instead of using generic
json.Marshal conversion.

* Add a unit test that prevents regressions of rego input

The optimized input is always compared to the normal json
marshal parser.
This commit is contained in:
Steven Masley
2023-02-09 13:47:17 -06:00
committed by GitHub
parent 22f6400ea5
commit af59e2bcfa
8 changed files with 466 additions and 58 deletions

View File

@ -263,34 +263,18 @@ func (a RegoAuthorizer) authorize(ctx context.Context, subject Subject, action A
return xerrors.Errorf("subject must have a scope")
}
subjRoles, err := subject.Roles.Expand()
astV, err := regoInputValue(subject, action, object)
if err != nil {
return xerrors.Errorf("expand roles: %w", err)
return xerrors.Errorf("convert input to value: %w", err)
}
subjScope, err := subject.Scope.Expand()
results, err := a.query.Eval(ctx, rego.EvalParsedInput(astV))
if err != nil {
return xerrors.Errorf("expand scope: %w", err)
}
input := map[string]interface{}{
"subject": authSubject{
ID: subject.ID,
Roles: subjRoles,
Groups: subject.Groups,
Scope: subjScope,
},
"object": object,
"action": action,
}
results, err := a.query.Eval(ctx, rego.EvalInput(input))
if err != nil {
return ForbiddenWithInternal(xerrors.Errorf("eval rego: %w", err), input, results)
return ForbiddenWithInternal(xerrors.Errorf("eval rego: %w", err), subject, action, object, results)
}
if !results.Allowed() {
return ForbiddenWithInternal(xerrors.Errorf("policy disallows request"), input, results)
return ForbiddenWithInternal(xerrors.Errorf("policy disallows request"), subject, action, object, results)
}
return nil
}