Loading...
Loading...
Schema design guide for polizy authorization. Use when defining relations, actions, action mappings, hierarchy propagation, or modifying authorization models. Covers direct, group, and hierarchy relation types.
npx skill4agent add bratsos/polizy polizy-schemadefineSchemaactionToRelations| Priority | Decision | Impact |
|---|---|---|
| Critical | Choose correct relation types | Wrong type = broken inheritance |
| Critical | Map all actions to relations | Unmapped = always denied |
| Important | Configure hierarchyPropagation | Without it, no parent→child inheritance |
| Important | Use semantic names | Clarity for future maintainers |
| Optional | Keep schema minimal | Start simple, expand as needed |
import { defineSchema } from "polizy";
const schema = defineSchema({
// 1. Define relationship types
relations: {
owner: { type: "direct" }, // Direct permission
editor: { type: "direct" },
viewer: { type: "direct" },
member: { type: "group" }, // Group membership
parent: { type: "hierarchy" } // Parent-child resources
},
// 2. Map actions to relations that grant them
actionToRelations: {
delete: ["owner"],
edit: ["owner", "editor"],
view: ["owner", "editor", "viewer"]
},
// 3. Optional: Define hierarchy propagation
hierarchyPropagation: {
view: ["view"], // view on parent → view on child
edit: ["edit"] // edit on parent → edit on child
}
});| Type | Purpose | Example | Use When |
|---|---|---|---|
| User → Resource | alice is owner of doc1 | Specific user needs specific resource access |
| User → Group membership | alice is member of engineering | Team-based access, organizational structure |
| Resource → Parent resource | doc1's parent is folder1 | Folder/file, project/task, inherited permissions |
const schema = defineSchema({
relations: {
owner: { type: "direct" },
editor: { type: "direct" },
viewer: { type: "direct" },
},
actionToRelations: {
delete: ["owner"],
edit: ["owner", "editor"],
view: ["owner", "editor", "viewer"],
},
});const schema = defineSchema({
relations: {
owner: { type: "direct" },
editor: { type: "direct" },
viewer: { type: "direct" },
member: { type: "group" }, // Required for addMember()
},
actionToRelations: {
manage: ["owner"],
edit: ["owner", "editor"],
view: ["owner", "editor", "viewer"],
},
});const schema = defineSchema({
relations: {
owner: { type: "direct" },
editor: { type: "direct" },
viewer: { type: "direct" },
parent: { type: "hierarchy" }, // Required for setParent()
},
actionToRelations: {
delete: ["owner"],
edit: ["owner", "editor"],
view: ["owner", "editor", "viewer"],
},
hierarchyPropagation: {
view: ["view"], // CRITICAL: Without this, no inheritance
edit: ["edit"],
},
});const schema = defineSchema({
relations: {
// Direct permissions
owner: { type: "direct" },
editor: { type: "direct" },
viewer: { type: "direct" },
commenter: { type: "direct" },
// Group membership
member: { type: "group" },
// Hierarchy
parent: { type: "hierarchy" },
},
actionToRelations: {
// Destructive
delete: ["owner"],
transfer: ["owner"],
// Modification
edit: ["owner", "editor"],
comment: ["owner", "editor", "commenter"],
// Read
view: ["owner", "editor", "viewer", "commenter"],
},
hierarchyPropagation: {
view: ["view"],
edit: ["edit"],
comment: ["comment"],
},
});Need to grant access to a specific user on a specific resource?
→ Use "direct" relation (owner, editor, viewer)
Need users to inherit access from a team/department?
→ Use "group" relation (member)
→ Add users to groups with addMember()
→ Grant group access with allow()
Need child resources to inherit parent permissions?
→ Use "hierarchy" relation (parent)
→ Set parent with setParent()
→ Configure hierarchyPropagation| Mistake | Symptom | Fix |
|---|---|---|
| Missing relation in actionToRelations | | Add relation to the action's array |
No | | Add group relation to schema |
No | | Add hierarchy relation to schema |
| Missing hierarchyPropagation | Parent permissions don't flow to children | Add hierarchyPropagation config |
| Using generic names ("access") | Can't distinguish read/write | Use semantic names (viewer, editor) |
// v1: Basic
const schemaV1 = defineSchema({
relations: {
owner: { type: "direct" },
viewer: { type: "direct" },
},
actionToRelations: {
edit: ["owner"],
view: ["owner", "viewer"],
},
});
// v2: Add editor role
const schemaV2 = defineSchema({
relations: {
owner: { type: "direct" },
editor: { type: "direct" }, // NEW
viewer: { type: "direct" },
},
actionToRelations: {
edit: ["owner", "editor"], // UPDATED
view: ["owner", "editor", "viewer"], // UPDATED
},
});
// v3: Add groups
const schemaV3 = defineSchema({
relations: {
owner: { type: "direct" },
editor: { type: "direct" },
viewer: { type: "direct" },
member: { type: "group" }, // NEW
},
actionToRelations: {
edit: ["owner", "editor"],
view: ["owner", "editor", "viewer"],
},
});