cedar-policy / cedar-docs

Documentation for Cedar policy language
https://docs.cedarpolicy.com
Apache License 2.0
22 stars 19 forks source link

Set attribute value must be an object #30

Closed nevolgograd closed 1 year ago

nevolgograd commented 1 year ago

What were you trying to do?

I'm encountering an issue when trying to send a context to the policy verifier. I have defined a schema where the context is supposed to be a set of strings. However, when I send the context in the expected format, I receive an error: " Error: Attribute value must be an object: "A"".

What is wrong and why?

Here is the relevant part of my schema:

{
    "Application": {
        "actions": {
            "ReadDomain": {
                "appliesTo": {
                    "context": {
                        "type": "ReusedContext"
                    },
                    "resourceTypes": [
                        "Domain"
                    ],
                    "principalTypes": [
                        "User"
                    ]
                }
            }
        },
        "commonTypes": {
            "ReusedContext": {
                "type": "Record",
                "attributes": {
                    "domains": {
                        "element": {
                            "type": "String"
                        },
                        "type": "Set"
                    }
                }
            }
        },
        "entityTypes": {
            "Domain": {...},
            "User": {...}
        }
    }
}

And here is how I'm sending the context in the test bench:

{
    "domains": {
        "set": ["A", "B"]
    }
}

What do we need to do to fix this?

According to the Cedar documentation, this seems to be the correct way to define and send a context with a set of strings. However, the error message suggests that there might be a misunderstanding or a potential issue with the Cedar policy language.

In the Cedar documentation, a set is defined as a collection of elements that can be of the same or different types. However, it seems that when I'm sending a set of strings in the context, it's not being recognized as a valid attribute type. This could potentially be a bug or a limitation in the Cedar policy language.

Could you please provide some guidance on this issue?

mwhicks1 commented 1 year ago

The schema you have given seems fine, and I've confirmed that there's no issue parsing it or using it to validate the following policy:

permit(principal, action, resource)
when {
   context.domains.contains("foo")
};

The issue is that you have specified the context incorrectly. It should be

{
  "domains": [ "A", "B" ]
}

Basically: the context is a normal JSON record, so Cedar sets are expressed simply as JSON sets. You can test this sort of thing in the Cedar policy playground: https://www.cedarpolicy.com/en/playground. (Be sure the "Amazon Verified Permissions format" box is not checked.)

mwhicks1 commented 1 year ago

Closed this issue, but opened a larger one https://github.com/cedar-policy/cedar-docs/issues/31 to address the doc problem.

nevolgograd commented 1 year ago

@mwhicks1 omg, thank you so much! My issue was with the syntax. Aws console test bench in JSON mode uses the Amazon Verified Permissions format, and I was unable to find an example of the Set anywhere in the documentation. I only realized how to write it by switching it in the playground you provided.

{
    "domains": {
        "set": [
            {
                "string": "A"
            },
            {
                "string": "B"
            }
        ]
    }
}