Skip to content

TPE Fails to Eliminate Irrelevant Policies #2500

Description

@tustvold

Before opening, please confirm:

Describe the bug

When the typechecker determines that a policy is irrelevant, it still gets added to the residual set

https://github.com/cedar-policy/cedar/blob/main/cedar-policy-core/src/tpe.rs#L69

I'm not entirely sure why this would be, given we've already proven that the policy is irrelevant? Is it something to do with error propagation?

Reproduction steps

use cedar_policy::{
    Entities, EntityTypeName, EntityUid, PartialEntities, PartialEntityUid, PartialRequest, Policy,
    PolicyId, PolicySet, Schema,
};
use std::str::FromStr;

fn main() {
    let (schema, _) = Schema::from_cedarschema_str(
        r#"
        entity Group;
        entity Role;
        entity User in [Group];
        entity Service;
        action "AssumeRole" appliesTo {
          principal: [User, Service],
          resource: Role,
        };
        "#,
    )
    .unwrap();

    let policies = PolicySet::from_policies([
        Policy::parse(
            Some(PolicyId::new("eq_service")),
            r#"permit(principal == Service::"Automation", action, resource);"#,
        )
        .unwrap(),
        Policy::parse(
            Some(PolicyId::new("in_group")),
            r#"permit(principal, action, resource) when { principal in Group::"1" };"#,
        )
        .unwrap(),
    ])
    .unwrap();

    let entities = PartialEntities::from_concrete(Entities::empty(), &schema).unwrap();
    let action = EntityUid::from_str(r#"Action::"AssumeRole""#).unwrap();

    for ty in ["User", "Service"] {
        let request = PartialRequest::new(
            PartialEntityUid::new(EntityTypeName::from_str(ty).unwrap(), None),
            action.clone(),
            PartialEntityUid::new(EntityTypeName::from_str("Role").unwrap(), None),
            None,
            &schema,
        )
        .unwrap();

        let response = policies.tpe(&request, &entities, &schema).unwrap();
        println!("=== principal: {ty}  decision: {:?}", response.decision());
        for p in response.nontrivial_residual_policies() {
            println!("{}", p.to_cedar().unwrap());
        }
    }
}

Both policies are returned for both, even though only a user can be in a group

Metadata

Metadata

Assignees

No one assigned

    Labels

    feature-requestThis issue requets a substantial new feature

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions