Cedar Policy in RAR Object
Cedar Policy in RAR Object
Introduction
There is an authorization policy language called **Cedar Policy Language. Policies written in this language are called Cedar Policies**. In this article, we look at how to associate Cedar Policies with access tokens and use them for fine-grained access control.
Advantages of Cedar Policy
One of the major advantages of Cedar Policy is that it allows authorization logic to be separated from business logic. Cedar Policies can be externalized and managed independently from application code. In fact, there are commercial services available that manage Cedar Policies (see *Integrations*).
Another major advantage of Cedar Policy is that it enables authorization logic to be expressed with fine-grained control. For example, it is possible to describe an authorization rule such as: “If a user is a friend of Jane, they are allowed to view and comment on photos in Jane’s travel album.” Below is an example of a Cedar Policy excerpted from the *Example Scenario* in the Cedar Policy Language Reference Guide that expresses this authorization logic.
permit (
principal in Group::"janeFriends",
action in [Action::"view", Action::"comment"],
resource in Album::"janeTrips"
);
In Cedar Policy, you can add when and unless clauses to specify the conditions under which a policy applies. Within these conditions, you can use comparison operators, logical operators, arithmetic operators, and more, providing a high level of expressiveness.
permit (
principal,
action == Action::"read",
resource
)
when {
resource.owner == principal ||
resource.tag == "public"
};
Cedar Policy in RAR Object
By associating scopes (RFC 6749, Section 3.3) with an access token, it is possible to express coarse-grained permissions for that access token. In a similar way, if Cedar Policies could be associated with an access token, it should be possible to express fine-grained permissions for that access token.
One promising approach to realizing this idea is to represent Cedar Policies as RAR objects (RFC 9396).
✏️ NOTE: The OAuth 2.0 Rich Authorization Requests specification (RFC 9396), commonly known as RAR, does not use the term “RAR object.” However, at an event, one of the authors of the specification referred to each element in the authorization_details array that way. I found the term convenient, so I use “RAR object” in the following discussion as well.
The idea of representing Cedar Policies as RAR objects has been discussed in the past, for example in the IETF individual draft *draft-cecchetti-oauth-rar-cedar* (now expired) and in forums such as the OAuth Working Group at IETF 119.
[embed]
However, after reviewing the earlier discussions, I could not find a design that fully met my needs. Therefore, I decided to design one myself. In the next section, I will describe the considerations that guided this design.
Designing Cedar Policy as a RAR Object
Choosing a Notation for Cedar Policies
The original notation of Cedar Policy is distinctive. Whether this notation should be embedded into a RAR object as-is, or first converted into JSON (JSON Policy Format) and then embedded, is a point on which opinions may differ.
While the JSON format has good affinity with RAR, it is verbose — especially in the representation of when and unless conditions—and many in the Cedar community are likely to prefer the original notation. For this reason, standardizing on only one notation could cause issues later. In such cases, it is safer to design the specification so that both notations are supported.
This leads to a further design decision: whether the notation should be specified using the mandatory type property of a RAR object (RFC 9396, Section 2), or whether a new property (for example, format) should be introduced.
If the type property were used, its value would need to convey two meanings at once—namely, that the object represents a Cedar Policy and which notation is used—resulting in values such as cedar-policy-native or cedar-policy-json.
At first glance, overloading a single property with two distinct meanings seems like a poor design choice. Moreover, it raises the question of whether Cedar Policy is the only Cedar-related artifact that might need to be represented in RAR. It is conceivable that Cedar Policies and Cedar Policy Templates might need to be treated as distinct entities. There is also the possibility that Cedar Schemas could be represented as RAR objects in the future. In such cases, the type property would be better suited for distinguishing among these artifacts.
In conclusion, a format property is introduced, whose value is either cedar or json, allowing the original notation or the JSON notation to be selected. Furthermore, based on the expectation that more users will prefer the original notation, cedar is defined as the default value when the format property is omitted.
type Property
In a RAR object, the type property is mandatory (RFC 9396, Section 2). It has been decided that the value of this property will indicate that the content of the RAR object is a Cedar Policy, but the concrete value must still be defined.
The first candidate that comes to mind is the string cedar. However, as mentioned in the previous section, choosing cedar would likely cause problems if there is a future need to distinguish among Cedar Policy, Cedar Policy Template, and Cedar Schema.
Taking these considerations into account, it seems appropriate to use cedar-policy as the value of the type property to indicate that the object represents a Cedar Policy.
Cedar Policy Set
There is also a design choice between representing a single Cedar Policy in one RAR object or representing a Cedar Policy Set.
In *Representing a Policy Set with JSON*, the JSON representation of a Cedar Policy Set contains staticPolicies, templates, and templateLinks within a single JSON object. In principle, it would be possible to embed equivalent information into a single RAR object.
However, I could not shake the concern that, in the context of RAR, support for templates might not be necessary in the first place. When a Cedar Policy is embedded statically in a RAR object, it seems likely that any placeholders in templates would already be resolved before embedding.
That said, the decision was not straightforward, so I chose to defer it. For the time being, a Cedar Policy Set is represented using multiple RAR objects within the authorization_details array. If operational experience later reveals issues with this approach, the mapping of a Cedar Policy Set to RAR objects can be revisited and redesigned at that point.
principal, action, resource
Within a Cedar Policy, the principal, action, and resource are referenced. What values should these have?
A Cedar Policy embedded in a RAR object is evaluated when the access token to which that RAR object is attached is used to access a resource. Therefore, the values of principal, action, and resource should align with this context.
For principal, it is natural to use the subject associated with the access token (a typical example being a user ID). Following common Cedar Policy examples, using User as the entity type would be appropriate. With this approach, a condition such as “the principal is the user user001” can be expressed as follows.
principal == User::"user001"
However, access tokens issued via the Client Credentials flow (RFC 6749, Section 4.4) are not associated with a user. In such cases, the entity type should be Client.
principal == Client::"app001"
✏️ NOTE: At this point, I am not yet certain whether it is a good idea to distinguish between cases where an access token is associated with a subject and cases where it is not.
If an access token contains groups, roles, or entitlements attributes (RFC 9068, Section 2.2.3), it would be reasonable to map each of them to Group, Role, and Entitlement entities, respectively, and set them as parent entities of the principal. This would allow the use of the in operator within Cedar Policies.
principal in Group::"group1"
The value of principal is determined by the authorization server at the time the access token is issued. In contrast, action and resource belong to the resource server, and it is preferable to let the resource server define their concrete values.
For example, a server implementing the Shared Signals Framework might define the action of creating a stream as SSF::Stream::Action::"create". In that case, a Cedar Policy could include a statement such as the following.
action == SSF::Stream::Action::"create"
context
I believe that, as variables available in the context referenced from when and unless clauses in a Cedar Policy, at least the following can be provided in any environment.
time— The current time expressed as milliseconds elapsed since the Unix epoch.access_token— Information about the access token. It has sub-properties such asiss,sub, andclient_id.ip_address— The client’s IP address.
Design Summary

Properties
type— REQUIRED. The value is fixed tocedar-policy.format— OPTIONAL.cedar(default) orjson.policy_id— OPTIONAL. Policy ID.policy— REQUIRED. The Cedar Policy. If the value of theformatproperty iscedar, this is a single string representing a Cedar Policy written in the native Cedar syntax. If the value of theformatproperty isjson, this is a JSON object representing a Cedar Policy written in the JSON Policy Format.
Entities
principal— If an access token is associated with a subject (i.e., the introspection response or the payload of a JWT access token contains asubclaim), the entity ofprincipalisUser. Otherwise, it isClient. For aUserentity, the value of thesubclaim in the access token is treated as the unique identifier. For aCliententity, the value of theclient_idin the access token is treated as the unique identifier. Each element ofgroups,roles, andentitlementsin the access token (RFC 9068, Section 2.2.3) is mapped to aGroup,Role, orEntitlemententity, respectively, and is set as a parent entity of theprincipal. If the token follows RFC 7643, Section 2.4, each element is expected to be a JSON object with avalueproperty (e.g.,"groups":[{"value":"group1"}]), and the value of thatvalueproperty is treated as the unique identifier of the entity. If it does not follow RFC 7643, Section 2.4, the element is assumed to be a JSON string (e.g.,"groups":["group1"]), and the string value itself is treated as the unique identifier of the entity.action— The entity ofactionis defined by the resource server.resource— The entity ofresourceis defined by the resource server.
Context
time— The current time expressed as milliseconds elapsed since the Unix epoch.access_token— Information about the access token. It has sub-properties such asiss,sub, andclient_id.ip_address— The client’s IP address.
Examples of Cedar Policies in RAR Objects
Based on the design described above, examples of Cedar Policies in RAR objects are as follows.
[
{
"type": "cedar-policy",
"format": "cedar",
"policy_id": "policy-0",
"policy": "permit (principal == User::\"12UA45\", action == Action::\"view\", resource);"
},
{
"type": "cedar-policy",
"format": "json",
"policy_id": "policy-1",
"policy": {
"effect": "permit",
"principal": { "op": "==", "entity": { "type": "User", "id": "12UA45" } },
"action": { "op": "==", "entity": { "type": "Action", "id": "view" } },
"resource": { "op": "All" }
}
}
]
This example contains two RAR objects. The first describes a Cedar Policy using the original Cedar syntax, and the second describes the Cedar Policy using the JSON format. However, both represent exactly the same policy semantics.
Cedar Policies for Admin-Issued Access Tokens
In standardized authorization flows, an access token is issued as a result of the client requesting it. Therefore, in those flows, the client specifies the set of RAR objects to be associated with the access token by using the authorization_details request parameter. However, in real-world commercial systems, it is quite common to issue access tokens without using standardized flows—that is, in so-called out-of-band ways.
If one assumes only scenarios in which the client specifies RARs, embedding Cedar Policies in RARs may seem unnatural. In other words, it may feel odd for a client to request complex Cedar Policies on its own. However, when considering cases where a server administrator manually creates an access token and hands it to a client application, the ability to embed Cedar Policies in RAR objects becomes useful.
For example, when a server administrator issues an access token for demonstration purposes, they might want to grant broad permissions while preventing accidental deletion of a demo stream. In such a case, the administrator could associate the following Cedar Policies with the access token.
[
{
"type": "cedar-policy",
"policy": "permit(principal,action,resource);"
},
{
"type": "cedar-policy",
"policy": "forbid(principal,action==SSF::Stream::Action::\"delete\",resource==SSF::Stream::\"stj3odpcfg19u6q62t2h7k0uk3t7srkdai6e0ccd7jd4ognt\");"
}
]
In this example, executing the SSF::Stream::Action::"delete" action on the resource SSF::Stream::"stj3odpcfg19u6q62t2h7k0uk3t7srkdai6e0ccd7jd4ognt"—a Shared Signals Framework stream prepared for demonstration purposes—is forbidden.
Demo Videos
Cedar Policy in RAR Object is not merely a theoretical idea; it has been implemented in practice and demonstrated to work.
In a LinkedIn Post
In an online study session (in Japanese)
[embed]
Conclusion
Personally, I believe the question of whether Cedar Policy in RAR Object is useful has already been answered. Its usefulness has been demonstrated in a new product currently under development at our company, and a certain public-sector organization has also shown strong interest in it as a means of addressing challenges in a national strategic project.
It would be great if a specification for Cedar Policy in RAR Object were standardized, but I personally am too busy to devote time to the standardization discussions. Hopefully, it will be standardized in a form close to the implementation presented in this article.
메타데이터
- post_id
- afe8e72e9703
- slug
- cedar-policy-in-rar-object-afe8e72e9703
- url
- https://medium.com/@darutk/cedar-policy-in-rar-object-afe8e72e9703
- canonical_url
- https://medium.com/@darutk/cedar-policy-in-rar-object-afe8e72e9703
- author_url
- https://medium.com/@darutk
- status
- ok
- fetched_at
- 2026-06-20 20:29:01