JSON policy format

To allow for programmatically constructing and parsing policies, Cedar supports a JSON policy format. This topic describes the JSON format for individual policies/templates and policy sets.

Topics on this page

Representing a policy with JSON

Overview

A “standard” Cedar policy looks like the following:

permit (
    principal == User::"12UA45",
    action == Action::"view",
    resource in Folder::"abc"
) when {
    context.tls_version == "1.3"
};

When you retrieve the JSON representation of this policy, it looks like the following:

{
    "effect": "permit",
    "principal": {
        "op": "==",
        "entity": { "type": "User", "id": "12UA45" }
    },
    "action": {
        "op": "==",
        "entity": { "type": "Action", "id": "view" }
    },
    "resource": {
        "op": "in",
        "entity": { "type": "Folder", "id": "abc" }
    },
    "conditions": [
        {
            "kind": "when",
            "body": {
                "==": {
                    "left": {
                        ".": {
                            "left": {
                                "Var": "context"
                            },
                            "attr": "tls_version"
                        }
                    },
                    "right": {
                        "Value": "1.3"
                    }
                }
            }
        }
    ]
}

In this topic, the term policy refers to both static policies and policy templates.

The JSON representation of a Cedar policy does not preserve comments, whitespace, or newline characters.

The JSON representation of a policy contains the following keys:

effect

The effect object is required.

The value of this object must be either the string permit or the string forbid.

"effect": "permit",
"effect": "forbid",

principal

The principal object is required.

The value of this object must include an object with the key op, and depending on the value of op, an object with the key entity or slot.

op

The op key is required. The op object must have one of the following string values:

  • All

    If present, then the original policy contains only the keyword principal with no constraints. In this case, the principal object doesn’t require any additional objects.

    Example

    Cedar policy line:

      principal
    

    JSON representation:

      "principal": {
          "op": "All"
      }
    
  • == If present, then the principal object must also have one of the following:

    • entity

      Example

      Cedar policy line:

      principal == User::"12UA45"
      

      JSON representation:

      "principal": {
          "op": "==",
          "entity": { "type": "User", "id": "12UA45" }
      }
      
    • slot

      Example

      Cedar policy line:

      principal == ?principal
      

      JSON representation:

      "principal": {
          "op": "==",
          "slot": { "?principal" }
      },
      
  • in

    If present, then the principal object must also have one of the following:

    • entity

      Example

      Cedar policy line:

      principal in Group::"Admins"
      

      JSON representation:

      "principal": {
          "op": "in",
          "entity": { "type": "Group", "id": "Admins" }
      }
      
    • slot

      Example

      Cedar policy line:

      principal in ?principal
      

      JSON representation

      "principal": {
          "op": "in",
          "slot": { "?principal" }
      },
      
  • is

    If present, then the principal object must also have an entity_type key.

    Example

    Cedar policy line:

    principal is User
    

    JSON representation:

    "principal": {
        "op": "is",
        "entity_type": "User"
    }
    

    The principal object may also optionally have an in key. The value of this key is an object with one of the following:

    • entity

      Example

      Cedar policy line:

      principal is User in Group::"Admins"
      

      JSON representation:

      "principal": {
          "op": "is",
          "entity_type": "User",
          "in": {
              "entity": { "type": "Group", "id": "Admins" }
          }
      }
      
    • slot

      Example

      Cedar policy line:

      principal is User in ?principal
      

      JSON representation

      "principal": {
          "op": "is",
          "entity_type": "User",
          "in": {
              "slot": { "?principal" }
          }
      },
      

action

The action object is required.

The value of this object must include an object with the key op, and depending on the value of op, an object with the key [entity](#entity) or [entities](#entities).

op

The op key is required.

The op object must have one of the following string values:

  • All

    If present, then the original policy contains only the keyword action with no constraints. In this case, the action object doesn’t require any additional objects.

    Example

    Cedar policy line:

      action
    

    JSON representation:

      "action": {
          "op": "All"
      }
    
  • ==

    If present, then the action object must also have the following object:

    • entity

      Example

      Cedar policy line:

      action == Action::"readFile"
      

      JSON representation:

      "action": {
          "op": "==",
          "entity": { "type": "Action", "id": "readFile" }
      }
      
  • in

    If present, then the action object must also have one of the following:

    • entity

      Example

      Cedar policy line:

      action in Action::"readOnly"
      

      JSON representation:

      "action": {
          "op": "in",
          "entity": { "type": "Action", "id": "readOnly" }
      }
      
    • entities

      Example

      Cedar policy line:

      action in [ Action::"readFile", Action::"writeFile", Action::"deleteFile"]
      

      JSON representation

      "action": {
          "op": "in",
          "entities": [
              { "type": "Action", "id": "readFile" },
              { "type": "Action", "id": "writeFile" },
              { "type": "Action", "id": "deleteFile" }
          ]
      }
      

resource

The resource object is required.

The value of this object must include an object with the key op, and depending on the value of op, an object with the key entity or slot.

op

The op key is required.

The op object must have one of the following string values:

  • All

    If present, then the original policy contains only the keyword resource with no constraints. In this case, the resource object doesn’t require any additional objects.

    Example

    Cedar policy line:

      resource
    

    JSON representation:

      "resource": {
          "op": "All"
      }
    
  • ==

    If this operator is present, then the resource object must also have one of the following:

    • entity

      Example

      Cedar policy line:

      resource == file::"vacationphoto.jpg"
      

      JSON representation:

      "resource": {
          "op": "==",
          "entity": { "type": "file", "id": "vacationphoto.jpg" }
      }
      
    • slot

      Example

      Cedar policy line:

      resource == ?resource
      

      JSON representation:

      "resource": {
          "op": "==",
          "slot": { "?resource" }
      },
      
  • in

    If present, then the resource object must also have one of the following:

    • entity

      Example

      Cedar policy line:

      resource in folder::"Public"
      

      JSON representation:

      "resource": {
          "op": "in",
          "entity": { "type": "folder", "id": "Public" }
      }
      
    • slot

      Example

      Cedar policy line:

      resource in ?resource
      

      JSON representation

      "resource": {
          "op": "in",
          "slot": { "?resource" }
      }
      
  • is

    If present, then the resource object must also have an entity_type key.

    Example

    Cedar policy line:

    resource is file
    

    JSON representation:

    "resource": {
        "op": "is",
        "entity_type": "file"
    }
    

    The resource object may also optionally have an in key. The value of this key is an object with one of the following:

    • entity

      Example

      Cedar policy line:

      resource is file in folder::"Public"
      

      JSON representation:

      "resource": {
          "op": "is",
          "entity_type": "file",
          "in": {
              "entity": { "type": "Folder", "id": "Public" }
          }
      }
      
    • slot

      Example

      Cedar policy line:

      resource is file in ?resource
      

      JSON representation

      "resource": {
          "op": "is",
          "entity_type": "file",
          "in": {
              "slot": { "?resource" }
          }
      },
      

conditions

The conditions object is required.

The value of this object is a JSON array of objects. Each object in the array must have exactly two keys: kind and body.

The kind key must be either the string when or the string unless.

The body key must be an JsonExpr object.

Example

Cedar policy lines

when { ... }

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            ...
        }
    }
]

annotations

Annotations, if present, must be a JSON object. The keys must be strings and the values may be strings or the JSON value null. A null value corresponds to an annotation without a value (e.g., @shadow_mode) and is equivalent to the value "".

JsonExpr objects

An JsonExpr object is an object with a single key that is any of the following.

Value

The value of this key is a Cedar value in the same syntax as expected for entity attribute values in Cedar’s entity format. This can include entity reference literals, set literals, and record literals.

Example with numeric literals

Cedar policy line:

when { 1 == 2 };

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            "==": {
                "left": {
                    "Value": 1
                },
                "right": {
                    "Value": 2
                }
            }
        }
    }
]

Example with entity literals

Cedar policy line

when { User::"alice" == Namespace::Type::"SomePrincipal" };

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            "==": {
                "left": {
                    "Value": {
                        "__entity": {
                            "type": "User",
                            "id": "alice"
                        }
                    }
                },
                "right": {
                    "Value": {
                        "__entity": {
                            "type": "Namespace::Type",
                            "id": "SomePrincipal"
                        }
                    }
                }
            }
        }
    }
]

Example with set literals

Cedar policy line:

when { [1, 2, "something"] == [4, 5, "otherthing"] };

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            "==": {
                "left": {
                    "Set": [
                        { "Value": 1 },
                        { "Value": 2 },
                        { "Value": "something" },
                    ]
                },
                "right": {
                    "Set": [
                        { "Value": 4 },
                        { "Value": 5 },
                        { "Value": "otherthing" },
                    ]
                }
            }
        }
    }
]

Example with record literals

Cedar policy line:

when { {something: "spam", otherthing: false} == {} };

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            "==": {
                "left": {
                    "Record": {
                        "something": { "Value": "spam" },
                        "otherthing": { "Value": false },
                    }
                },
                "right": {
                    "Record": {}
                }
            }
        }
    }
]

Var

The value of this key is one of the strings principal, action, resource, or context.

Example

Cedar policy line:

when { principal == action && resource == context };

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            "&&": {
                "left": {
                    "==": {
                        "left": {
                            "Var": "principal"
                        },
                        "right": {
                            "Var": "action"
                        }
                    }
                },
                "right": {
                    "==": {
                        "left": {
                            "Var": "resource"
                        },
                        "right": {
                            "Var": "context"
                        }
                    }
                }
            }
        }
    }
]

Slot

The value of this key is one of the strings ?principal or ?resource and act as placeholders in policy templates. Currently, policies containing this are not valid Cedar.

Unknown

The value of this key is an object with a single key name, whose value is the name of the unknown. This is used for partial-evaluation. In particular, these values may appear in the JSON rendering of residuals.

! or neg operators

The value of this key is an object with a single key argument, whose value is itself an JsonExpr object.

Example using . and !

Example Cedar policy line:

when { !context.something };

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            "!": {
                "arg": {
                    ".": {
                        "left": {
                            "Var": "context"
                        },
                        "attr": "something"
                    }
                }
            }
        }
    }
]

Binary operators: ==, !=, in, <, <=, >, >=, &&, ||, +, -, *, contains, containsAll, containsAny, hasTag, getTag

The value for any of these keys is an object with keys left and right, which are each themselves an JsonExpr object.

Example for contains

Cedar policy line

when { principal.owners.contains("something") };

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            "contains": {
                "left": {
                    ".": {
                        "left": {
                            "Var": "principal"
                        },
                        "attr": "owners"
                    }
                },
                "right": {
                    "Value": "something"
                }
            }
        }
    }
]

., has

The value of one of these keys is an object with keys left and attr. The left key is itself an JsonExpr object, while the attr key is a string.

Example for .

Cedar policy line

context.something

JSON representation

".": {
    "left": {
        "Var": "context"
    },
    "attr": "something"
}

is

The value of this key is an object with the keys left and entity_type. The left key is itself an JsonExpr object, while the entity_type key is a string. The value may optionally have an in key which is also a JsonExpr object.

Example for is

Cedar policy line

principal is User in Group::"friends"

JSON representation

"is": {
    "left": { "Var": "principal" },
    "entity_type": "User",
    "in": {"Value": {"__entity": { "type": "Folder", "id": "Public" }}}
}

like

The value of this key is an object with keys left and pattern. The left key is itself an JsonExpr object, while the pattern key is an array composed of pattern elements. A pattern element can be one of either

  • the string Wildcard
  • an object with a single key Literal, whose value is a string

Example for pattern

The pattern /home/alice/docs/*.txt is represented as:

"pattern": [
  {
    "Literal": "/home/alice/docs/"
  },
  "Wildcard",
  {
    "Literal": ".txt"
  }
]

Note that it’s allowed to represent literals with up to one Literal per character. For instance, in the previous example, we could use up to four objects with Literal keys to represent the .txt string.

if-then-else

The value of this key is an object with keys if, then, and else, each of which are themselves an JsonExpr object.

Example for if-then-else

Cedar policy line

when {
    if context.something
    then principal has "-78/%$!"
    else resource.email like "*@amazon.com"
};

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            "if-then-else": {
                "if": {
                    ".": {
                        "left": {
                            "Var": "context"
                        },
                        "attr": "something"
                    }
                },
                "then": {
                    "has": {
                        "left": {
                            "Var": "principal"
                        },
                        "attr": "-78/%$!"
                    }
                },
                "else": {
                    "like": {
                        "left": {
                            ".": {
                                "left": {
                                    "Var": "resource"
                                },
                                "attr": "email"
                            }
                        },
                        "pattern": "*@amazon.com"
                    }
                }
            }
        }
    }
]

Set

The value of this key is a JSON array of values, each of which is itself an JsonExpr object.

Example

Cedar policy element

[1, 2, "something"]

JSON representation

{
    "Set": [
        { "Value": 1 },
        { "Value": 2 },
        { "Value": "something" },
    ]
}

Record

The value of this key is a JSON object whose keys are arbitrary strings and values are themselves JsonExpr objects.

Example for record

Cedar policy element {something: "spam", somethingelse: false}

JSON representation

{
    "Record": {
        "foo": { "Value": "spam" },
        "somethingelse": { "Value": false },
    }
}

Any other key

This key is treated as the name of an extension function or method. The value must be a JSON array of values, each of which is itself an JsonExpr object. Note that for method calls, the method receiver is the first argument. For example, for a.isInRange(b), the first argument is for a and the second argument is for b.

Example for decimal function

Cedar policy line

decimal("10.0")

JSON representation

{
    "decimal": [
        {
            "Value": "10.0"
        }
    ]
}

Example for ip function and isInRange method

Cedar policy line

when {
    context.source_ip.isInRange(ip("222.222.222.0/24"))
};

JSON representation

"conditions": [
    {
        "kind": "when",
        "body": {
            "isInRange": [
                {
                    ".": {
                        "left": {
                            "Var": "context"
                        },
                        "attr": "source_ip"
                    }
                },
                {
                    "ip": [
                        {
                            "Value": "222.222.222.0/24"
                        }
                    ]
                }
            ]
        }
    }
]

Representing a policy set with JSON

Overview

Here is an example policy set containing a static policy and policy template.

permit (
    principal == User::"12UA45",
    action == Action::"view",
    resource in Folder::"abc"
);

forbid (
    principal == User::"12UA45",
    action == Action::"view",
    resource in ?resource
);

Here is the JSON representation of this policy set, plus a template-linked policy that sets the ?resource placeholder of the template.

{
    "staticPolicies": {
        "policy0": {
            "effect": "permit",
            "principal": {
                "op": "==",
                "entity": { "type": "User", "id": "12UA45" }
            },
            "action": {
                "op": "==",
                "entity": { "type": "Action", "id": "view" }
            },
            "resource": {
                "op": "in",
                "entity": { "type": "Folder", "id": "abc" }
            },
            "conditions": []
        }
    },
    "templates": {
        "template0": {
            "effect": "forbid",
            "principal": {
                "op": "==",
                "entity": { "type": "User", "id": "12UA45" }
            },
            "action": {
                "op": "==",
                "entity": { "type": "Action", "id": "view" }
            },
            "resource": {
                "op": "in",
                "slot": { "?resource" }
            },
            "conditions": []
        }
    },
    "templateLinks": [
        {
            "templateId": "template0",
            "newId": "policy1",
            "values": {
                "?resource": {
                    "type": "Folder",
                    "id": "def"
                }
            }
        }
    ]
}

The JSON representation of a policy set contains the following keys:

staticPolicies

This field is the set of static policies in the policy set, represented as a map from policy ID to policy content in the format described above. This field can only include static policies; including a template will result in an error.

templates

This field is the set of templates in the policy set, represented as a map from policy ID to template in the format described above.

This field is a JSON array of template links. The JSON representation of a template link contains the following keys:

  • templateId
  • newId
  • values

templateId is the ID of the policy to be linked against. new_id is the ID of the newly generated template-linked policy, and values is a mapping from slots (?principal or ?resource) to entities.