What Cedar is
Cedar is an open-source authorization policy language maintained by AWS. It is not the Cedar tree. It is a small, well-typed language designed for expressing who can do what to which resource under what conditions.
CloudSwarm v1.0 ships a Go-translated subset of Cedar as the policy substrate for every agent in every workspace; the full Cedar evaluator is the v1.1 substrate. Either way, you get an engine with formal semantics and a decades-deep authorization literature behind it.
Policy shape
A Cedar policy is a block that is either a permit or a forbid, scoped by principal, action, and resource. Optionally constrained by a when or unless clause.
permit (
principal,
action,
resource
)
when { /* boolean expression */ }
unless { /* boolean expression */ };
Evaluation model
For each action an agent wants to perform, the runtime gathers the principal (the agent), the action (e.g. email:send), the resource (e.g. the recipient record), and the request context (budget, time, calling workspace).
- Every matching
forbidrule that evaluates true blocks the action. - Otherwise, at least one matching
permitrule must evaluate true. - If no rule permits, the default is deny. Silence is refusal.
The runtime writes every policy decision to the audit log with a pointer to the rule that triggered.
Scope composition
Policies compose at three scopes:
- Workspace envelope. The widest ceiling. Cannot be widened per-agent.
- Agent policy. Narrower or equal to the workspace envelope.
- Mission override. A one-off narrowing for a specific run.
At evaluation, the runtime intersects all three. An action must be permitted at all three scopes to run.
Worked examples
Example 1 · Emails only to known contacts
An outbound agent may send email to anyone in the declared contact list, and must not send email to anyone outside it.
permit (
principal == Agent::"outbound-sequencer",
action == Action::"email:send",
resource in List::"approved-contacts"
);
forbid (
principal == Agent::"outbound-sequencer",
action == Action::"email:send",
resource
)
unless { resource in List::"approved-contacts" };
Example 2 · Purchase approval gate above a threshold
An agent may complete purchases on its own up to $50. Anything above requires human approval (represented as a presigned approval token on the request).
permit (
principal == Agent::"office-supplies-replenisher",
action == Action::"commerce:purchase",
resource
)
when { context.amount_usd <= 50 };
permit (
principal == Agent::"office-supplies-replenisher",
action == Action::"commerce:purchase",
resource
)
when {
context.amount_usd > 50
&& context.human_approval_token.valid == true
};
Example 3 · Data-exfiltration block
An agent may write to the company Google Drive and to Slack, but may never write to any endpoint outside a whitelisted set of domains.
permit (
principal == Agent::"research-writer",
action == Action::"http:post",
resource
)
when { resource.host in ["drive.google.com", "slack.com"] };
forbid (
principal == Agent::"research-writer",
action == Action::"http:post",
resource
)
unless { resource.host in ["drive.google.com", "slack.com"] };
Example 4 · Time-of-day envelope
An on-call triage agent may act only during business hours in the workspace's timezone; outside those hours, every action routes to a human.
permit (
principal == Agent::"oncall-first-responder",
action,
resource
)
when {
context.local_hour >= 9
&& context.local_hour <= 18
&& context.local_day in ["mon","tue","wed","thu","fri"]
};
Example 5 · PII never leaves
A brand-voice linter never calls any external model with customer PII in the prompt; Veritize's PII scrub must have stamped the payload clean first.
forbid (
principal == Agent::"brand-voice-linter",
action == Action::"llm:call",
resource
)
unless { context.veritize_pii_clean == true };
Authoring tips
- Write your narrowest
forbidrules first. The default is already deny;forbidrules exist to narrow a widerpermit. - Keep policies declarative. If you find yourself writing a long conjunction, the policy is telling you the action is too big; split it.
- Reference lists by name (
List::"approved-contacts"). Store the list contents as a separate, auditable resource. - Test policies with the policy inspector; it will tell you which rule would fire against any example request.