-
Notifications
You must be signed in to change notification settings - Fork 14
feat: implement policy templates #83
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
base: main
Are you sure you want to change the base?
feat: implement policy templates #83
Conversation
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we are close to being able to merge this.
However, after consulting internally at StrongDM, we'd like to move the template-supporting PolicySet into x/exp/templates
for now. Some work we just to expose an Authorize()
function that takes a policy set iterator interface will probably help make that work well.
Can we sync up on the Cedar Slack to discuss further?
return Policy{}, fmt.Errorf("slot env length %d does not match template slot length %d", len(p.slotEnv), len(body.Slots())) | ||
} | ||
|
||
for _, slot := range body.Slots() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This bookkeeping seems unnecessary. Let's just hunt for slot usages in the expected places and replace them with the provided values from the environment or return an error if no value is provided.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which bookkeeping do you refer to?
- Checking if
slotEnv
size is the same as the number of slots in the template? If so, I did the same as in the Rust impl, such that if a policy fails in the Rust impl it also fails in the Go impl. - Iterating over the return from
Slots()
? It just makes it easier to check whether the slot is used or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was imagining that we didn't need Slots()
at all. It seems to me that ast.Policy
ought to not know anything about templates (beyond the VariableSlot
nodes in the AST) and that we could just iterate the AST here looking for VariableSlot
s to replace with values from slotEnv
. The error conditions would then be:
- A value does not exist in the
slotEnv
when we go to replace it - A value in the
slotEnv
isn't used. We'd obviously have to do some bookkeeping locally inRender()
to keep track of that, but I think I prefer that to pollutingtypes.Policy
with knowledge about templates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, when parsing a Cedar document and trying to decide whether it's a Policy
or a Template
, I'd just look at the scope AST to see if there are any VariableSlot
s.
If templates ever become more general (which, perhaps, one day they may), this will be more expensive and we can address it then. For now, it's easy enough to look through the scope AST to decide what's going on.
…emplates-2 * 'main' of github.com:caiorcferreira/cedar-go: (23 commits) cedar-go: remove golangci-lint badge from README.md cedar-go: retract v1.2.0 cedar-go: change receiver type for IsAuthorized() and Get() for efficiency reasons and mark Map() as deprecated cedar-go: change the name of the AuthorizationPolicySet to PolicyIterator cedar-go: reduce the minimum go version 1.23.0 and require the version of golang.org/x/exp that introduces constraints cedar-go: reduce the usage of x/exp/maps in favor of the standard library cedar-go: add documentation for batch and Go version requirements types: fix test weirdnesses cedar-go: add an All() method to PolicyMap to make it easy to pass to Authorize() cedar-go: change Authorize() to take an interface with a single All() method rather than a bare iter.Seq2 cedar-go: add code coverage enforcement to CI x/exp/batch: change the batch Authorize function to take a policy iterator as well cedar-go: get test coverage up to 100% cedar-go: advertize new features in README.md cedar-go: use the PolicySet.All() iterator to implement PolicySet.IsAuthorized() cedar-go: consolidate Github workflows types: add iterators to each of the container types defined in the module. cedar-go: Add a new top-level Authorize() function cedar-go: upgrade golangci-lint checks to v2 and fix all issues found cedar-go: remove vendor directory ... Signed-off-by: Caio Ferreira <[email protected]>
…cies Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
3335052
to
39bdf0e
Compare
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
Signed-off-by: Caio Ferreira <[email protected]>
I see there are some conflicts here yet. |
Description of changes:
One of Cedar's main features is Policy Templates, which allows for managing large sets of policies while keeping the authorization rules centralized.
This PR is an attempt to implement Templates in
cedar-go
.Features
This implementation follows the Template behavior described in the Language Guide.
We can break the Template behavior described in the Language Guide in 3 main requirements:
1. Template Variables
To fulfill this requirement, we introduce
types.SlotID
with two possible values:PrincipalSlotID
(?principal
) andResourceSlotID
(?resource
).The unmarshaling logic expects only these values and errors otherwise.
2. Operator support
This requirement guided the changes in marshaling and the
ScopeTypeX
supported by thelinkScope
function.3. Cascade change propagation
Based on this requirement, we created the
LinkedPolicy
type. It holds a template reference, a template ID, a link ID, and the slot env with values that will replace the variables.The
LinkedPolicy
can be serialized to JSON, following the cedar-cli structure, so that it can be persisted and later rendered into a policy again. Because we store the template ID (instead of the actual template), if the template content changes in the meantime, the client code should be able to retrieve the template's latest version and create a new instance of theLinkedPolicy
to render the policy.Conclusion
Policy templates will soon become a critical feature for my Cedar use case. Hence, I want to try to move this feature forward, and I appreciate any help!