Define the entity hierarchy in the Cedar schema: Folder is a parent type of Document, and User has a parent type of Team
Populate the entities JSON with parent relationships: {"uid": "Document::doc1", "attrs": {}, "parents": ["Folder::folder1"]} and {"uid": "User::alice", "attrs": {}, "parents": ["Team::engineering"]}
Write a permit policy using 'in' to grant access transitively: 'permit(principal in Team::"engineering", action == Action::"Read", resource in Folder::"engineering-docs");'
The 'in' operator traverses the entity graph transitively; a user who is a member of a sub-team of engineering will also match if Team::subteam has Team::engineering as a parent
Test with a user who is two levels deep in the hierarchy to verify transitive 'in' resolution works as expected
Use 'cedar validate --schema schema.cedarschema --policies policies.cedar' to catch type errors before runtime
Known gotchas
The entity graph is evaluated at authorization time using the entities provided in the request; if parents are omitted from the entities payload, 'in' checks will fail silently even if the relationship exists in your database
Cyclic parent relationships in the entities payload cause Cedar to return an error rather than looping; validate your entity loading code to prevent cycles before passing to the authorizer
Cedar schema validation catches policy type errors but does not validate that the entity data matches the schema at runtime; a mismatch between schema-declared attribute types and actual entity attribute types can cause unexpected evaluation results
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