askill
polizy-patterns

polizy-patternsSafety 90Repository

Implementation patterns for polizy authorization. Use when implementing team access, folder inheritance, field-level permissions, temporary access, revocation, or any specific authorization scenario.

5 stars
1.2k downloads
Updated 1/31/2026

Package Files

Loading files...
SKILL.md

Polizy Implementation Patterns

Copy-paste patterns for common authorization scenarios.

When to Apply

  • User says "how do I implement X"
  • User says "give team access to project"
  • User says "make files inherit folder permissions"
  • User says "grant temporary access"
  • User says "revoke all permissions"
  • User wants to implement a specific authorization scenario

Pattern Selection Guide

ScenarioPatternReference
Specific user → specific resourceDirect PermissionsDIRECT-PERMISSIONS.md
Team/group accessGroup AccessGROUP-ACCESS.md
Folder/file inheritanceHierarchyHIERARCHY.md
Sensitive fields (salary, PII)Field-LevelFIELD-LEVEL.md
Contractor/expiring accessTime-LimitedTIME-LIMITED.md
Removing accessRevocationREVOCATION.md
Tenant isolationMulti-TenantMULTI-TENANT.md

Pattern 1: Direct Permissions

Grant specific user access to specific resource.

// Grant permission
await authz.allow({
  who: { type: "user", id: "alice" },
  toBe: "owner",
  onWhat: { type: "document", id: "doc1" }
});

// Check permission
const canEdit = await authz.check({
  who: { type: "user", id: "alice" },
  canThey: "edit",
  onWhat: { type: "document", id: "doc1" }
});

Pattern 2: Team-Based Access

Grant access through group membership.

// 1. Add users to team
await authz.addMember({
  member: { type: "user", id: "alice" },
  group: { type: "team", id: "engineering" }
});

await authz.addMember({
  member: { type: "user", id: "bob" },
  group: { type: "team", id: "engineering" }
});

// 2. Grant team access to resource
await authz.allow({
  who: { type: "team", id: "engineering" },
  toBe: "editor",
  onWhat: { type: "project", id: "project1" }
});

// 3. Team members can now access
const canAliceEdit = await authz.check({
  who: { type: "user", id: "alice" },
  canThey: "edit",
  onWhat: { type: "project", id: "project1" }
}); // true

Schema requirement:

relations: {
  member: { type: "group" },  // Required!
  editor: { type: "direct" },
}

Pattern 3: Folder/File Hierarchy

Inherit permissions from parent resources.

// 1. Set up hierarchy
await authz.setParent({
  child: { type: "document", id: "doc1" },
  parent: { type: "folder", id: "folder1" }
});

// 2. Grant access at folder level
await authz.allow({
  who: { type: "user", id: "alice" },
  toBe: "viewer",
  onWhat: { type: "folder", id: "folder1" }
});

// 3. Document inherits folder permission
const canView = await authz.check({
  who: { type: "user", id: "alice" },
  canThey: "view",
  onWhat: { type: "document", id: "doc1" }
}); // true

Schema requirement:

relations: {
  parent: { type: "hierarchy" },  // Required!
  viewer: { type: "direct" },
},
hierarchyPropagation: {
  view: ["view"],  // CRITICAL: Without this, no inheritance!
}

Pattern 4: Field-Level Permissions

Protect sensitive fields within records.

// Grant general record access
await authz.allow({
  who: { type: "user", id: "employee" },
  toBe: "viewer",
  onWhat: { type: "profile", id: "emp123" }
});

// Grant specific field access
await authz.allow({
  who: { type: "user", id: "hr_manager" },
  toBe: "viewer",
  onWhat: { type: "profile", id: "emp123#salary" }
});

// Employee can view profile, but not salary
await authz.check({
  who: { type: "user", id: "employee" },
  canThey: "view",
  onWhat: { type: "profile", id: "emp123" }
}); // true

await authz.check({
  who: { type: "user", id: "employee" },
  canThey: "view",
  onWhat: { type: "profile", id: "emp123#salary" }
}); // false

// HR can view salary
await authz.check({
  who: { type: "user", id: "hr_manager" },
  canThey: "view",
  onWhat: { type: "profile", id: "emp123#salary" }
}); // true

Pattern 5: Temporary Access

Grant time-limited permissions.

// Access valid for 30 days
await authz.allow({
  who: { type: "user", id: "contractor" },
  toBe: "editor",
  onWhat: { type: "project", id: "project1" },
  when: {
    validSince: new Date(),
    validUntil: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)
  }
});

// Scheduled future access
await authz.allow({
  who: { type: "user", id: "new_hire" },
  toBe: "viewer",
  onWhat: { type: "onboarding", id: "docs" },
  when: {
    validSince: new Date("2024-02-01")  // Starts Feb 1
  }
});

Pattern 6: Revocation

Remove permissions.

// Remove specific permission
await authz.disallowAllMatching({
  who: { type: "user", id: "bob" },
  was: "editor",
  onWhat: { type: "document", id: "doc1" }
});

// Remove all user permissions on a resource
await authz.disallowAllMatching({
  who: { type: "user", id: "bob" },
  onWhat: { type: "document", id: "doc1" }
});

// Remove all permissions on a resource (when deleting it)
await authz.disallowAllMatching({
  onWhat: { type: "document", id: "doc1" }
});

// Remove user from group
await authz.removeMember({
  member: { type: "user", id: "alice" },
  group: { type: "team", id: "engineering" }
});

Pattern 7: Listing Accessible Objects

Find what a user can access.

// List all documents alice can access
const result = await authz.listAccessibleObjects({
  who: { type: "user", id: "alice" },
  ofType: "document"
});

// Result:
// {
//   accessible: [
//     { object: { type: "document", id: "doc1" }, actions: ["edit", "view", "delete"] },
//     { object: { type: "document", id: "doc2" }, actions: ["view"] },
//   ]
// }

// Filter by action
const editableOnly = await authz.listAccessibleObjects({
  who: { type: "user", id: "alice" },
  ofType: "document",
  canThey: "edit"  // Only return editable documents
});

Pattern 8: Combining Patterns

Real apps often combine multiple patterns:

// Organizational structure (groups)
await authz.addMember({ member: alice, group: frontend });
await authz.addMember({ member: frontend, group: engineering });

// Resource hierarchy
await authz.setParent({ child: codeFile, parent: srcFolder });
await authz.setParent({ child: srcFolder, parent: projectRoot });

// Team access at project level
await authz.allow({ who: engineering, toBe: "editor", onWhat: projectRoot });

// Alice can now edit codeFile through:
// alice → member → frontend → member → engineering → editor → projectRoot ← parent ← srcFolder ← parent ← codeFile

await authz.check({ who: alice, canThey: "edit", onWhat: codeFile }); // true

Common Mistakes

MistakeSymptomFix
Missing member: { type: "group" }addMember() throwsAdd group relation to schema
Missing parent: { type: "hierarchy" }setParent() throwsAdd hierarchy relation to schema
Missing hierarchyPropagationParent permissions don't flowAdd propagation config
Relation not in actionToRelationscheck() returns falseAdd relation to action's array
Checking wrong actioncheck() returns falseVerify action name matches schema

References

Each pattern has detailed documentation:

Related Skills

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

96/100Analyzed 2/10/2026

An exceptional skill document providing comprehensive, copy-pasteable implementation patterns for the Polizy authorization library. It includes clear triggers, technical references, and troubleshooting advice.

90
100
75
98
100

Metadata

Licenseunknown
Version-
Updated1/31/2026
Publisherbratsos

Tags

No tags yet.