polizy-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Polizy Implementation Patterns

Polizy权限授权实现模式

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
  • 用户询问“如何实现X权限”
  • 用户要求“为团队分配项目访问权限”
  • 用户要求“让文件继承文件夹权限”
  • 用户要求“授予临时访问权限”
  • 用户要求“撤销所有权限”
  • 用户需要实现特定的授权场景

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

场景模式参考文档
特定用户 → 特定资源直接权限DIRECT-PERMISSIONS.md
团队/组访问组访问GROUP-ACCESS.md
文件夹/文件权限继承层级权限HIERARCHY.md
敏感字段(薪资、个人身份信息)字段级权限FIELD-LEVEL.md
承包商/到期访问限时权限TIME-LIMITED.md
移除访问权限权限撤销REVOCATION.md
租户隔离多租户权限MULTI-TENANT.md

Pattern 1: Direct Permissions

模式1:直接权限

Grant specific user access to specific resource.
typescript
// 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" }
});

为特定用户授予特定资源的访问权限。
typescript
// 授予权限
await authz.allow({
  who: { type: "user", id: "alice" },
  toBe: "owner",
  onWhat: { type: "document", id: "doc1" }
});

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

Pattern 2: Team-Based Access

模式2:基于团队的访问

Grant access through group membership.
typescript
// 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:
typescript
relations: {
  member: { type: "group" },  // Required!
  editor: { type: "direct" },
}

通过组成员身份授予访问权限。
typescript
// 1. 将用户添加到团队
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. 为团队授予资源访问权限
await authz.allow({
  who: { type: "team", id: "engineering" },
  toBe: "editor",
  onWhat: { type: "project", id: "project1" }
});

// 3. 团队成员现在可访问资源
const canAliceEdit = await authz.check({
  who: { type: "user", id: "alice" },
  canThey: "edit",
  onWhat: { type: "project", id: "project1" }
}); // true
Schema要求:
typescript
relations: {
  member: { type: "group" },  // 必须配置!
  editor: { type: "direct" },
}

Pattern 3: Folder/File Hierarchy

模式3:文件夹/文件层级权限

Inherit permissions from parent resources.
typescript
// 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:
typescript
relations: {
  parent: { type: "hierarchy" },  // Required!
  viewer: { type: "direct" },
},
hierarchyPropagation: {
  view: ["view"],  // CRITICAL: Without this, no inheritance!
}

从父级资源继承权限。
typescript
// 1. 配置层级关系
await authz.setParent({
  child: { type: "document", id: "doc1" },
  parent: { type: "folder", id: "folder1" }
});

// 2. 在文件夹层级授予访问权限
await authz.allow({
  who: { type: "user", id: "alice" },
  toBe: "viewer",
  onWhat: { type: "folder", id: "folder1" }
});

// 3. 文件继承文件夹的权限
const canView = await authz.check({
  who: { type: "user", id: "alice" },
  canThey: "view",
  onWhat: { type: "document", id: "doc1" }
}); // true
Schema要求:
typescript
relations: {
  parent: { type: "hierarchy" },  // 必须配置!
  viewer: { type: "direct" },
},
hierarchyPropagation: {
  view: ["view"],  // 关键配置:无此配置则无法继承权限!
}

Pattern 4: Field-Level Permissions

模式4:字段级权限

Protect sensitive fields within records.
typescript
// 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

保护记录中的敏感字段。
typescript
// 授予记录的通用访问权限
await authz.allow({
  who: { type: "user", id: "employee" },
  toBe: "viewer",
  onWhat: { type: "profile", id: "emp123" }
});

// 授予特定字段的访问权限
await authz.allow({
  who: { type: "user", id: "hr_manager" },
  toBe: "viewer",
  onWhat: { type: "profile", id: "emp123#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可查看薪资字段
await authz.check({
  who: { type: "user", id: "hr_manager" },
  canThey: "view",
  onWhat: { type: "profile", id: "emp123#salary" }
}); // true

Pattern 5: Temporary Access

模式5:临时权限

Grant time-limited permissions.
typescript
// 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
  }
});

授予限时访问权限。
typescript
// 权限有效期30天
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)
  }
});

// 预定未来生效的权限
await authz.allow({
  who: { type: "user", id: "new_hire" },
  toBe: "viewer",
  onWhat: { type: "onboarding", id: "docs" },
  when: {
    validSince: new Date("2024-02-01")  // 2月1日生效
  }
});

Pattern 6: Revocation

模式6:权限撤销

Remove permissions.
typescript
// 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" }
});

移除已授予的权限。
typescript
// 移除特定权限
await authz.disallowAllMatching({
  who: { type: "user", id: "bob" },
  was: "editor",
  onWhat: { type: "document", id: "doc1" }
});

// 移除用户对某一资源的所有权限
await authz.disallowAllMatching({
  who: { type: "user", id: "bob" },
  onWhat: { type: "document", id: "doc1" }
});

// 移除某一资源的所有权限(删除资源时使用)
await authz.disallowAllMatching({
  onWhat: { type: "document", id: "doc1" }
});

// 将用户从团队中移除
await authz.removeMember({
  member: { type: "user", id: "alice" },
  group: { type: "team", id: "engineering" }
});

Pattern 7: Listing Accessible Objects

模式7:列出可访问资源

Find what a user can access.
typescript
// 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
});

查询用户可访问的资源。
typescript
// 列出Alice可访问的所有文档
const result = await authz.listAccessibleObjects({
  who: { type: "user", id: "alice" },
  ofType: "document"
});

// 返回结果:
// {
//   accessible: [
//     { object: { type: "document", id: "doc1" }, actions: ["edit", "view", "delete"] },
//     { object: { type: "document", id: "doc2" }, actions: ["view"] },
//   ]
// }

// 按操作权限筛选
const editableOnly = await authz.listAccessibleObjects({
  who: { type: "user", id: "alice" },
  ofType: "document",
  canThey: "edit"  // 仅返回可编辑的文档
});

Pattern 8: Combining Patterns

模式8:组合使用多种模式

Real apps often combine multiple patterns:
typescript
// 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

实际应用中通常会组合多种模式:
typescript
// 组织架构(组关系)
await authz.addMember({ member: alice, group: frontend });
await authz.addMember({ member: frontend, group: engineering });

// 资源层级
await authz.setParent({ child: codeFile, parent: srcFolder });
await authz.setParent({ child: srcFolder, parent: projectRoot });

// 在项目层级为团队授予访问权限
await authz.allow({ who: engineering, toBe: "editor", onWhat: projectRoot });

// Alice现在可通过以下路径编辑codeFile:
// alice → 成员 → frontend → 成员 → engineering → 编辑者 → projectRoot ← 父级 ← srcFolder ← 父级 ← codeFile

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

Common Mistakes

常见错误

MistakeSymptomFix
Missing
member: { type: "group" }
addMember()
throws
Add group relation to schema
Missing
parent: { type: "hierarchy" }
setParent()
throws
Add hierarchy relation to schema
Missing
hierarchyPropagation
Parent permissions don't flowAdd propagation config
Relation not in
actionToRelations
check()
returns false
Add relation to action's array
Checking wrong action
check()
returns false
Verify action name matches schema

错误表现修复方案
缺失
member: { type: "group" }
addMember()
抛出错误
在Schema中添加组关系配置
缺失
parent: { type: "hierarchy" }
setParent()
抛出错误
在Schema中添加层级关系配置
缺失
hierarchyPropagation
父级权限无法向下继承添加权限继承传播配置
关系未配置在
actionToRelations
check()
返回false
将关系添加到对应操作的数组中
检查的操作权限名称错误
check()
返回false
验证操作名称与Schema配置一致

References

参考文档

Each pattern has detailed documentation:
  • DIRECT-PERMISSIONS.md - Simple user-resource access
  • GROUP-ACCESS.md - Teams, departments, nested groups
  • HIERARCHY.md - Folders, projects, inheritance
  • FIELD-LEVEL.md - PII, sensitive data protection
  • TIME-LIMITED.md - Contractors, expiring access
  • REVOCATION.md - Removing access patterns
  • MULTI-TENANT.md - Tenant isolation strategies
每种模式都有详细文档:
  • DIRECT-PERMISSIONS.md - 简单的用户-资源访问配置
  • GROUP-ACCESS.md - 团队、部门、嵌套组权限
  • HIERARCHY.md - 文件夹、项目、权限继承
  • FIELD-LEVEL.md - 个人身份信息、敏感数据保护
  • TIME-LIMITED.md - 承包商、到期权限配置
  • REVOCATION.md - 权限移除模式
  • MULTI-TENANT.md - 租户隔离策略

Related Skills

相关技能

  • polizy-schema - Schema design
  • polizy-troubleshooting - When things go wrong
  • polizy-schema - Schema设计
  • polizy-troubleshooting - 问题排查