Skip to main content

Cedar Policy Language Overview

Cedar is a policy language developed by AWS for defining fine-grained permissions. It’s used by AWS Verified Permissions to implement authorization logic that’s separate from your application code.

What is Cedar?

Cedar is a declarative, human-readable policy language that lets you define authorization rules using a simple syntax. Policies in Cedar are evaluated to determine whether a principal (user) can perform an action on a resource.

Key Features

  • Human-readable syntax - Policies are easy to read and understand
  • Strongly typed - Schema validation ensures policy correctness
  • Composable - Multiple policies can work together
  • Analysis tools - Built-in validation and testing capabilities
  • Open source - Available on GitHub

Basic Policy Structure

Every Cedar policy follows this basic structure:
permit (
  principal,
  action,
  resource
)
when {
  condition
};

Components

Effect

Either permit or forbid - determines whether the policy allows or denies access

Principal

The entity performing the action (e.g., a User)

Action

The operation being performed (e.g., Read, Edit, Delete)

Resource

The entity being accessed (e.g., a Document)

Conditions

Optional conditions using when or unless clauses

Your First Cedar Policy

Here’s a simple policy that allows all Analysts to read documents:
permit (
  principal in FinancialApp::Role::"Analyst",
  action == FinancialApp::Action::"Read",
  resource
);
This policy says:
  • Effect: permit (allow access)
  • Principal: Any user who is a member of the Analyst role
  • Action: Must be the Read action
  • Resource: Any resource (no restrictions)

Policy Effects: Permit vs Forbid

Cedar supports two policy effects:
permit (
  principal in FinancialApp::Role::"Auditor",
  action == FinancialApp::Action::"Read",
  resource
);
A permit policy explicitly allows access. Multiple permit policies can apply - if any permit policy matches and no forbid policy matches, access is granted.

Conditions: When and Unless

You can add conditions to policies using when and unless clauses:

When Clause

The policy applies only if the condition is true:
permit (
  principal in FinancialApp::Role::"Analyst",
  action == FinancialApp::Action::"Read",
  resource
)
when {
  principal.department == resource.department
};
This policy allows Analysts to read documents only if they’re in the same department.

Unless Clause

The policy applies only if the condition is false:
permit (
  principal in FinancialApp::Role::"Analyst",
  action == FinancialApp::Action::"Read",
  resource
)
unless {
  resource.classification == "top-secret"
};
This policy allows Analysts to read documents unless they’re classified as top-secret.

Operators and Comparisons

Cedar supports various operators for building conditions:
OperatorDescriptionExample
==Equalityprincipal.department == "Finance"
!=Inequalityresource.status != "archived"
<, <=, >, >=Comparisonprincipal.clearance_level >= 3
inMembershipprincipal in FinancialApp::Role::"Admin"
hasAttribute presenceprincipal has email
&&Logical ANDcondition1 && condition2
``Logical OR`condition1condition2`
!Logical NOT!condition

Decision Logic

AWS Verified Permissions evaluates all policies and makes a decision using this logic:
1

Default Deny

If no policies match, access is denied by default (Zero Trust principle)
2

Check Forbid

If any forbid policy matches, access is denied (forbid always wins)
3

Check Permit

If any permit policy matches and no forbid matches, access is allowed
Forbid takes precedence: Even if 10 permit policies match, a single forbid policy will deny access.

Policy Sets

In a real application, you’ll have multiple policies working together:
// Policy 1: Analysts can read their department's documents
permit (
  principal in FinancialApp::Role::"Analyst",
  action == FinancialApp::Action::"Read",
  resource
)
when {
  principal.department == resource.department
};

// Policy 2: Admins can do everything
permit (
  principal in FinancialApp::Role::"Admin",
  action,
  resource
);

// Policy 3: Nobody can delete confidential documents
forbid (
  principal,
  action == FinancialApp::Action::"Delete",
  resource
)
when {
  resource.classification == "confidential"
};
These policies are evaluated together to make authorization decisions.

Best Practices

AWS Verified Permissions denies access by default. Only write permit policies for allowed actions. This follows the Zero Trust security model.
Name policies clearly: AllowAnalystReadOwnDepartment is better than Policy1.
Each policy should express one clear authorization rule. Complex logic should be split into multiple policies.
Leverage attribute-based access control with when clauses to create dynamic, context-aware policies.
Use the Cedar Playground or AVP console to test policies before deploying to production.

Next Steps

Schema Definition

Learn about the FinancialApp schema with entity types and actions

Policy Examples

See real-world Cedar policies from the demo scenarios

RBAC vs ABAC

Understand role-based and attribute-based access control patterns

Cedar Playground

Practice writing Cedar policies in your browser

Build docs developers (and LLMs) love