-
Notifications
You must be signed in to change notification settings - Fork 135
Description
Category
Cedar language or syntax features/changes
Describe the feature you'd like to request
This issue tracks the interest in common operations on sets: intersection, difference, length, and union.
I asked @emina about these before, and she mentioned that they are analyzable, but avoided so far for performance reasons. She told that sets in SMT are unbounded, and can thus have infinite length, so to expose a length field in Cedar, one would need to perform expensive conversions back and forth. In addition, execution of a Cedar policy cannot yield a value that is bigger or smaller than what is given as input, but the intersection, difference and union operators could change that.
I guess that some optimizations could be done to e.g. evaluate set operations lazily instead of eagerly (eventually all usage of sets turn into a boolean through contains* or similar), but it's a fair point.
For the Kubernetes use-case, authorization of updates get both the old (already in storage) and new (request) objects, and in such cases, you naturally care about differences, e.g. (object.finalizers - oldobject.finalizers).isEmpty() || (object.finalizers - oldobject.finalizers) == ["allowed-value"] instead of something like (copied from upbound/kubernetes-cedar-authorizer#13)
// if (new finalizers >= old finalizers), verify either equality or one added finalizer
(if resource.request.metadata.finalizers.unorderedSet.containsAll(resource.stored.metadata.finalizers.unorderedSet) then
(resource.stored.metadata.finalizers.unorderedSet.containsAll(resource.request.metadata.finalizers.unorderedSet)
|| (resource.request.metadata.finalizers.unorderedSet.contains("my-controller-finalizer") &&
resource.request.metadata.finalizers.length == resource.stored.metadata.finalizers.length + 1))
// There was at least one old finalizer not in the new set, verify new finalizers < old, and that the difference is "my-controller-finalizer"
else
(resource.stored.metadata.finalizers.unorderedSet.containsAll(resource.request.metadata.finalizers.unorderedSet &&
resource.stored.metadata.finalizers.unorderedSet.contains("my-controller-finalizer") &&
resource.request.metadata.finalizers.length == resource.stored.metadata.finalizers.length - 1)
)
that'd you'd need to do today.
I'm not asking for this to be implemented right away, but I just wanted to open this issue to gauge interest in this feature.
Describe alternatives you've considered
Users can expose the set and the length separately, but that can produce symcc false positives.
Some of the operations could maybe technically be emulated using existing operations, but it's quite a lot of work for users and error-prone.
Additional context
No response
Is this something that you'd be interested in working on?
- 👋 I may be able to implement this feature request
-
⚠️ This feature might incur a breaking change