← Back to list

Cedar Policy in RAR Object

Takahiko Kawasaki · 2025-12-29 14:38 · 2 claps · 8.7 min read
#cedar-policy #rar #oauth #access-token
Open on Medium ↗

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 as iss, sub, and client_id.
  • ip_address — The client’s IP address.

Design Summary

Properties

  • type — REQUIRED. The value is fixed to cedar-policy.
  • format — OPTIONAL. cedar (default) or json.
  • policy_id — OPTIONAL. Policy ID.
  • policy — REQUIRED. The Cedar Policy. If the value of the format property is cedar, this is a single string representing a Cedar Policy written in the native Cedar syntax. If the value of the format property is json, 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 a sub claim), the entity of principal is User. Otherwise, it is Client. For a User entity, the value of the sub claim in the access token is treated as the unique identifier. For a Client entity, the value of the client_id in the access token is treated as the unique identifier. Each element of groups, roles, and entitlements in the access token (RFC 9068, Section 2.2.3) is mapped to a Group, Role, or Entitlement entity, respectively, and is set as a parent entity of the principal. If the token follows RFC 7643, Section 2.4, each element is expected to be a JSON object with a value property (e.g., "groups":[{"value":"group1"}]), and the value of that value property 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 of action is defined by the resource server.
  • resource — The entity of resource is 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 as iss, sub, and client_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