cedar-policy / cedar

Implementation of the Cedar Policy Language
https://www.cedarpolicy.com
Apache License 2.0
772 stars 64 forks source link

Metadata to specify expected types for linked template variables #777

Open mwhicks1 opened 3 months ago

mwhicks1 commented 3 months ago

Category

Cedar validation features/changes

Describe the feature you'd like to request

I'd like to be able to validate an unlinked template against stated assumptions of the types of ?principal or ?resource that it will be linked against. Doing so would allow me to ensure that the policy won't be impossible, or won't exhibit a type error, once it is linked.

Off the top of my head, I'd propose @__linktype("?principal=T,?resource=T") where the T is a legal entity type (namespaced identifier). For each @__linktype annotation, validate the template assumed to be linked with entities of the given types.

I am assuming that my use of __ clarifies that this is a Cedar-specific annotation, and not user/customer annotation, so that this is not a breaking change.

Describe alternatives you've considered

Leaving the status quo delays discovery of errors until link-time.

I thought of specifying linking assumptions in the schema, but then you have to name the templates from the policies file, which I don't see how to do.

Additional context

For example, suppose I have this template:

@__linktype("?principal=User,?resource=Hotel")
@__linktype("?principal=User,?resource=Customer")
permit(
  principal == ?principal,
  action in [Action::"viewReservation"],
  resource in ?resource);

Suppose that Reservation entities are in a corresponding Hotel entity, per the schema. Then this template should validate according to the first annotation. However, if Reservation entities are not in Customer entities, then it will not validate according to the second annotation. This problem would be missed today because the validator checks if there exists a possible ?resource type that properly validates a template, not that all intended ones actually do, because it has no way of knowing user intent.

Is this something that you'd be interested in working on?

khieta commented 3 months ago

I'm marking this as requires-RFC because I think adding annotations with special behavior is effectively extending the language, so we should use the RFC process to discuss.

My initial impressions:

mwhicks1 commented 3 months ago

Motivation: We need type information to analyze (valid) unlinked templates. We want to analyze unlinked templates for a variety of useful application scenarios. Validating/analyzing only unlinked templates is insufficient.

I like the look of ?principal:User but what does it mean at policy evaluation time? We don't have any other language constructs that are no-ops at evaluation time, and useful only for validation. Using an annotation as I describe here makes it clear that there is no run-time effect.

cdisselkoen commented 4 weeks ago

Counterpoint: Why not have something that is also enforced, not just assumed at validation/analysis time? Why not have some syntax that specifies the allowed types of ?principal and ?resource for a given template, and then the linker fails to link if you try to link with a ?principal or ?resource of a different type?