This playbook is the Cedar-specific companion to the Playbook – Permissions and Authorisation. Apply the preceding model and boundary design regardless of whether Cedar is selected.
Good Cedar fit
Cedar is particularly strong when a system needs combinations of RBAC, ownership/relationship rules, tenant containment, and attributes; when decisions are shared across services; or when policy review and explainability matter.
Use groups to represent broad roles and policies to grant role capabilities. Add resource relationships or attributes for rules that roles cannot express cleanly. Keep individual grants and exceptions narrow, scoped to both principal and resource where possible. Prefer fine-grained permissions in the model, then aggregate them into user-facing product roles or screens.
What Cedar provides
Cedar is a policy language and decision engine developed by AWS and released open-source under Apache 2.0. It evaluates policies against an authorisation request with four parts: principal, action, resource, context (PARC), plus the relevant entities and their relationships. It returns Allow or Deny and decision diagnostics.
Cedar's evaluation semantics are useful safety properties:
- no matching
permitmeans Deny; - a matching
forbidoverrides matching permits; - a policy evaluation error causes that policy to be skipped and reported in diagnostics rather than automatically determining the entire decision.
The third rule makes validation and diagnostics operationally important. A faulty policy does not itself cause a global outage, but it can be skipped while another permit still allows a request. Validate policies against the schema before publication, alert on evaluation diagnostics, and test both policy and schema changes.
A Cedar design normally contains:
- a schema for entity types, attributes, memberships, actions, and context shapes;
- entities representing trusted domain facts and relationships;
permitandforbidpolicies;- a policy store and change process;
- an application adapter that constructs the PARC request and relevant entity slice, invokes Cedar, records the decision, and enforces it.
What Cedar does not solve
Cedar does not:
- authenticate users or issue/validate JWTs;
- decide which entity data is true; your application must assemble trusted, correctly scoped entity data;
- filter a database query automatically or protect a storage bucket on its own;
- replace validation of input, tenancy checks, audit retention, rate limits, or business invariants;
- provide a complete UI, approval workflow, or governance process for users editing policies.
If policy authors are customers or non-engineering staff, design policy administration as a product: constrained templates, preview/simulation, approval and rollback, audit history, and strict meta-permissions for who may grant which access.
Implementing Cedar: a step-by-step approach
1. Start with one high-value boundary
Choose one coherent domain, such as organisation membership, documents, or projects, not the entire legacy permission surface. Keep existing authorisation in place elsewhere. Define the success measure: for example, all document operations are evaluated at one server-side boundary and the decision can be explained from logs.
2. Define the Cedar schema and action vocabulary first
Define the namespace, entity types, action groups, and action applicability before drafting many policies. Ensure each action identifies the permitted principal and resource types and the specific transient context shape it accepts.
namespace ExampleApp {
entity User in [Role, Organisation] {};
entity Role {};
entity Organisation {};
entity Document in [Organisation] = { owner: User, locked: Bool };
action "document.read" appliesTo {
principal: [User],
resource: [Document],
context: {}
};
}
This is illustrative only. The schema must reflect the actual domain and its authoritative data sources. The Cedar schema defines what an authorization request and its entities are allowed to look like; it does not establish where those facts come from or whether they are trustworthy. That is the responsibility of the adapter and the data contract described in the [[Pessoal/Playbooks/playbook-permissions-and-authorization|general playbook]].
3. Model policy rules as business rules
Policies should be specific and readable. A role grant and an owner rule may coexist; a forbid can express a guardrail that must win even if a role policy permits access.
// Role-based: document readers can read any document in their scope.
// Assumes the user's role membership is represented in the entity graph.
permit (
principal in ExampleApp::Role::"document_reader",
action == ExampleApp::Action::"document.read",
resource
);
permit (
principal,
action == ExampleApp::Action::"document.update",
resource
)
when { resource.owner == principal && !resource.locked };
forbid (
principal,
action == ExampleApp::Action::"document.update",
resource
)
when { resource.locked };
Do not paste this example into production unchanged. In particular, scope policies as tightly as the domain requires and validate all policy text against the deployed schema.
4. Create one authorisation adapter
Application code should call a small, well-tested boundary with a request such as:
authorize({ principal, action, resource, context }) → allow/deny + decision metadata
The adapter resolves canonical IDs, loads the minimum authoritative entity slice, calls the Cedar authorizer, handles diagnostics according to the service's safety requirements, emits safe audit telemetry, and blocks execution on denial. It should not accept arbitrary Cedar entities or policy text from an untrusted caller.
5. Assemble the entity slice carefully
Cedar evaluates policies against the entities you provide, not against your database. The adapter must load the minimum authoritative entity slice: the principal, the resource, and the relationships the policies might traverse (group memberships, tenant containment, ownership links).
This is where the [[Pessoal/Playbooks/playbook-permissions-and-authorization|general playbook]]'s data contract guidance becomes concrete. For each entity attribute and relationship:
- What is the canonical source?
- What is the freshness expectation?
- Who owns the data?
Keep principal, action, and resource facts in their respective models. Use request context only for transient, action-specific facts such as an MFA assertion, request time, or an IP/network signal — not as a duplicate source for identity, role, tenant, or resource ownership. If the entity slice is wrong, the decision is wrong, regardless of how correct the policies are.
6. Handle diagnostics as a first-class concern
Because evaluation errors are skipped rather than fatal, diagnostics are not optional telemetry, but safety signal. A policy that errors is a policy that is not applying. If that policy was a forbid guardrail, the request may be allowed by a different permit that the forbid was meant to override.
Handle diagnostics according to the service's safety requirements:
- Alert on evaluation errors at a rate that indicates a policy or entity-slice problem, not a transient blip.
- Treat a diagnostics-only decision (no matching
permitorforbid, but errors present) asDenyunless the service has a deliberate, documented reason to do otherwise. - Include diagnostic information in audit records so post-incident investigation can reconstruct why a decision was made.
Cedar-specific verification
In addition to the general test strategy from the [[Pessoal/Playbooks/playbook-permissions-and-authorization|general playbook]], Cedar introduces its own verification surface:
| Layer | Verify |
|---|---|
| Schema validation | Schema compiles, entity types and actions are consistent, context shapes match action definitions |
| Policy unit tests | Each permit and forbid produces the expected decision for representative entity slices |
| Entity-slice mapping tests | The adapter loads the correct entities and relationships for a given request. No missing relationships, no stale data |
| Diagnostics-handling tests | Evaluation errors are surfaced, alerted, and do not silently allow access |
| Schema-change tests | Adding, removing, or changing entity attributes or actions does not silently alter existing decisions |
For every new policy, include at least one must allow, must deny, and must not leak scenario. Test actions, not UI controls, because direct API calls and background execution bypass the UI. This is the same discipline as the general playbook, now applied to Cedar's permit/forbid semantics.
Cedar-specific anti-patterns
In addition to the general anti-patterns from the [[Pessoal/Playbooks/playbook-permissions-and-authorization|general playbook]]:
- Trusting unvalidated entity data: passing request-supplied attributes or relationships into Cedar without resolving them from a trusted source. Cedar evaluates what you give it — incorrect entity data can produce incorrect authorization decisions.
- Forgetting
forbidwhen adding newpermits: a newpermitthat broadens access may override a constraint that was previously enforced by the absence of a permit, not by an explicitforbid. Express guardrails asforbidso they survive new permits. - Ignoring diagnostics: treating evaluation errors as harmless noise. A skipped
forbidis a silent security gap. - Overloading context with entity facts: using the context map to pass principal roles, tenant membership, or resource ownership instead of modelling them as entities and relationships. Context is for transient, action-specific facts.
- Policy-store drift: changing policies without schema validation, version pinning, or regression tests. A policy that validated against the previous schema may error against the new one.