Cedar Policies
Cedar policies define authorization rules: who can do what, under which conditions.
Policy Files
Policies are written in .cedar files, separate from the schema:
policies/main.cedar
// Folder owners can read their folders
permit (
principal,
action == DocShare::Action::"Folder::Read",
resource
) when {
principal in resource.owners
};
// Document owners can read and write
permit (
principal,
action in [
DocShare::Action::"Document::Read",
DocShare::Action::"Document::Write"
],
resource
) when {
principal == resource.owner
};
Policy Structure
Every policy has three parts:
permit|forbid (
principal [== <entity> | in <group>],
action [== <action> | in [<actions>]],
resource [== <entity> | in <parent>]
) [when { <conditions> }];
Effect
permit- Allow the request if conditions matchforbid- Deny the request if conditions match (takes precedence)
Scope
Constrain which principals, actions, and resources the policy applies to:
// Any principal, specific action, any resource
permit (principal, action == DocShare::Action::"Document::Read", resource);
// Specific principal type
permit (principal is DocShare::User, action, resource);
// Resource in a parent
permit (principal, action, resource in DocShare::Folder::"shared-folder");
Conditions
The when clause adds attribute-based conditions:
permit (principal, action, resource)
when {
principal in resource.viewers &&
resource.locked == false
};
Loading Policies
cedar4s loads policies at runtime:
val engine = CedarEngine.fromResources[Future](
policiesPath = "policies",
policyFiles = Seq("main.cedar", "admin.cedar")
)
Policies are loaded from the classpath (typically src/main/resources/policies/).
Policy Evaluation
Cedar evaluates policies using default-deny:
- If any
forbidpolicy matches → Deny - If any
permitpolicy matches → Allow - Otherwise → Deny
This means you must have at least one permit policy for any action to succeed.
Common Patterns
Role-Based Access
// Admins can do anything
permit (principal, action, resource)
when { principal in DocShare::Role::"admin" };
Hierarchical Access
// Access to folder grants access to documents in it
permit (principal, action == DocShare::Action::"Document::Read", resource)
when { resource in principal.folders };
Time-Based Access
permit (principal, action, resource)
when {
context.requestTime >= resource.accessStart &&
context.requestTime <= resource.accessEnd
};