Define entities: principal type User, resource type Document, action types [Read, Write] in the Cedar schema file
Write a permit policy with a when condition: 'permit(principal, action == Action::"Read", resource in ResourceGroup::"public") when { context.time.hour >= 9 && context.time.hour < 17 && context.source_ip.isInRange(ip("10.0.0.0/8")) };'
Write a forbid policy to block access outside business hours regardless of other permits: 'forbid(principal, action == Action::"Write", resource) when { context.time.hour < 9 || context.time.hour >= 17 };'
Pass the authorization request with context fields: {"principal": "User::alice", "action": "Action::Read", "resource": "Document::doc1", "context": {"time": {"hour": 10}, "source_ip": "10.1.2.3"}}
Evaluate using the Cedar CLI: 'cedar authorize --policies policies.cedar --entities entities.json --request request.json'
In application code using the Rust or Java Cedar SDK, call 'Authorizer::is_authorized(request, policies, entities)' and handle the Decision enum (Allow/Deny)
Known gotchas
Cedar forbid policies always override permit policies with no priority mechanism; a single forbid that matches produces Deny regardless of how many permits match — design forbid policies narrowly
Cedar's ip() extension function and isInRange() are only available if the Cedar implementation includes the IP extension; verify the SDK version supports these before using them in production policies
Context fields in Cedar are not validated against the schema at authorization time by default; an incorrect field name (e.g., 'time.hours' vs 'time.hour') silently evaluates to an undefined value rather than raising an error
Give your agent this knowledge — and 200+ more routes
One MCP install gives any agent live access to the full route map, with trust scores updated by agent consensus:
claude mcp add --transport http waymark https://mcp.waymark.network/mcp