Programmatic policy creation using JSON policy format
You can use the Cedar Policy::to_json()
method to convert the specified policy into a JSON document.
You can also use the Policy::from_json()
method to convert a JSON document into a new Cedar policy. This gives you another option for programmatically constructing or parsing your policies.
The JSON document format you receive or submit using either of these methods is described in this topic.
Example
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": {
"Literal": "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 key word
principal
with no constraints. In this case, theprincipal
object doesn’t require any additional objects.Example
Cedar policy line:
principal
JSON representation:
"principal": { "op": "All" }
-
==
If present, then theprincipal
object must also have one of the following: -
in
If present, then the
principal
object must also have one of the following:
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 key word
action
with no constraints. In this case, theaction
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:-
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:-
Example
Cedar policy line:
action in Action::"readOnly"
JSON representation:
"action": { "op": "in", "entity": { "type": "Action", "id": "readOnly" } }
-
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 key word
resource
with no constraints. In this case, theresource
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:-
Example
Cedar policy line:
resource == file::"vacationphoto.jpg"
JSON representation:
"resource": { "op": "==", "entity": { "type": "file", "id": "vacationphoto.jpg" } }
-
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:
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 and values, which must all be strings, correspond to the Cedar annotation keys and values on the policy.
entity
This object has a value that specifies the Cedar type
and unique id
of a single entity.
"entity": { "type": "User", "id": "12UA45" }
entities
This object is a JSON array or list of objects. Each entry in the list is a each with a value that specifies the type
and id
of the entity.
"entities": [
{ "type": "User", "id": "12UA45" },
{ "type": "Group", "id": "67VB89" }
]
slot
This key is required only if the policy being rendered is a template that uses a placeholder and the principal
or resource
object uses the ==
or in
operator.
"slot": "?principal"
"slot": "?resource"
JsonExpr objects
An JsonExpr object is an object with a single key that is any of the following.
Value
Var
Slot
Unknown
!
orneg
operators- Binary operators:
==
,!=
,in
,<
,<=
,>
,>=
,&&
,||
,+
,-
,*
,contains
,containsAll
,containsAny
.
,has
like
if-then-else
Set
Record
Any other key
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
. 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
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"
}
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 any 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"
}
]
}
]
}
}
]