Delegate independent tasks to specialized agents working concurrently with isolated context.
Polizy Troubleshooting
polizy-troubleshooting
Debug and fix polizy authorization issues. Use when permission checks fail unexpectedly, errors occur, or authorization behavior is confusing. Covers check algorithm, common issues, and anti-patterns.
SKILL.md
Full skill instructions
Polizy Troubleshooting
Debug authorization issues when things don't work as expected.
When to Apply
- User says "permission check not working"
- User says "user can't access X but should"
- Error messages from polizy
- User confused about why authorization behaves a certain way
check()returnsfalseunexpectedly
Quick Diagnosis Flowchart
check() returns false unexpectedly
│
▼
Is the relation in actionToRelations?
│ │
NO YES
│ │
▼ ▼
ADD IT Is there a group relation?
│ │
NO YES
│ │
▼ ▼
(Direct check) Is user in group?
│ │
▼ NO → Check addMember()
Is tuple YES
present? │
│ ▼
NO Does group have permission?
│ │
▼ NO → Check group's allow()
Add with YES
allow() │
▼
Check depth limit
Common Issues
1. Relation Not Mapped to Action
Symptom: check() returns false even with permission granted.
// Schema
actionToRelations: {
view: ["viewer"], // "editor" missing!
edit: ["editor"],
}
// Grant
await authz.allow({ who: alice, toBe: "editor", onWhat: doc });
// Check
await authz.check({ who: alice, canThey: "view", onWhat: doc }); // false!
Fix: Add relation to action's array:
actionToRelations: {
view: ["viewer", "editor"], // Now editors can view
edit: ["editor"],
}
2. Missing Group Relation
Symptom: addMember() throws error.
// Schema missing group type
relations: {
viewer: { type: "direct" },
}
await authz.addMember({ member: alice, group: team });
// Error: No group relation defined in schema
Fix: Add group relation:
relations: {
viewer: { type: "direct" },
member: { type: "group" }, // Add this
}
3. Missing Hierarchy Propagation
Symptom: Parent permission doesn't flow to children.
// Schema
relations: {
parent: { type: "hierarchy" },
viewer: { type: "direct" },
},
// Missing hierarchyPropagation!
await authz.setParent({ child: doc, parent: folder });
await authz.allow({ who: alice, toBe: "viewer", onWhat: folder });
await authz.check({ who: alice, canThey: "view", onWhat: doc }); // false!
Fix: Add hierarchyPropagation:
hierarchyPropagation: {
view: ["view"], // Now view propagates
}
4. User Not in Group
Symptom: Group has permission but user can't access.
Debug:
// Check group membership
const memberships = await authz.listTuples({
subject: { type: "user", id: "alice" },
relation: "member",
});
console.log("Alice's groups:", memberships);
Fix: Add user to group:
await authz.addMember({ member: alice, group: team });
5. Max Depth Exceeded
Symptom: Deep group chain returns false silently.
Detect:
const authz = new AuthSystem({
storage,
schema,
throwOnMaxDepth: true, // Throws instead of silent false
});
try {
await authz.check({ who: alice, canThey: "view", onWhat: doc });
} catch (error) {
if (error instanceof MaxDepthExceededError) {
console.log("Depth exceeded at:", error.depth);
}
}
Fix: Increase depth or reduce nesting:
const authz = new AuthSystem({
storage,
schema,
defaultCheckDepth: 20, // Increase from default 10
});
6. Time-Based Condition Not Valid
Symptom: Permission granted with when but check fails.
Debug:
const tuples = await authz.listTuples({
subject: alice,
object: doc,
});
for (const tuple of tuples) {
console.log("Condition:", tuple.condition);
if (tuple.condition?.validSince) {
console.log("Starts:", tuple.condition.validSince);
}
if (tuple.condition?.validUntil) {
console.log("Expires:", tuple.condition.validUntil);
}
}
Common causes:
validSinceis in the futurevalidUntilis in the past
Debugging Techniques
1. List All Tuples for Subject
const tuples = await authz.listTuples({
subject: { type: "user", id: "alice" },
});
console.log("Alice's permissions:");
for (const tuple of tuples) {
console.log(` ${tuple.relation} on ${tuple.object.type}:${tuple.object.id}`);
}
2. List All Tuples for Object
const tuples = await authz.listTuples({
object: { type: "document", id: "doc1" },
});
console.log("Permissions on doc1:");
for (const tuple of tuples) {
console.log(` ${tuple.subject.type}:${tuple.subject.id} is ${tuple.relation}`);
}
3. Trace Group Membership
async function traceGroupPath(userId: string) {
const user = { type: "user", id: userId };
const groups: string[] = [];
const directMemberships = await authz.listTuples({
subject: user,
relation: "member",
});
for (const tuple of directMemberships) {
groups.push(`${tuple.object.type}:${tuple.object.id}`);
// Check nested groups
const nestedMemberships = await authz.listTuples({
subject: tuple.object,
relation: "member",
});
for (const nested of nestedMemberships) {
groups.push(` → ${nested.object.type}:${nested.object.id}`);
}
}
return groups;
}
console.log("Group path:", await traceGroupPath("alice"));
4. Trace Hierarchy Path
async function traceHierarchyPath(objectType: string, objectId: string) {
const path: string[] = [`${objectType}:${objectId}`];
let current = { type: objectType, id: objectId };
while (true) {
const parentTuples = await authz.listTuples({
subject: current,
relation: "parent",
});
if (parentTuples.length === 0) break;
const parent = parentTuples[0].object;
path.push(`${parent.type}:${parent.id}`);
current = parent;
}
return path;
}
console.log("Hierarchy:", await traceHierarchyPath("document", "doc1"));
// ["document:doc1", "folder:subfolder", "folder:root"]
5. Enable Logging
const debugLog: string[] = [];
const authz = new AuthSystem({
storage,
schema,
logger: {
warn: (msg) => {
debugLog.push(msg);
console.warn("[Polizy]", msg);
},
},
});
// After operations, check debugLog for warnings
Error Reference
| Error | Cause | Fix |
|---|---|---|
SchemaError: Relation "X" is not defined | Using undefined relation | Add relation to schema |
SchemaError: No group relation defined | Missing group type | Add member: { type: "group" } |
SchemaError: No hierarchy relation defined | Missing hierarchy type | Add parent: { type: "hierarchy" } |
MaxDepthExceededError | Group/hierarchy too deep | Increase depth or flatten |
ConfigurationError: storage is required | Missing storage adapter | Provide storage in constructor |
ConfigurationError: schema is required | Missing schema | Provide schema in constructor |
Anti-Patterns to Avoid
See ANTI-PATTERNS.md for detailed explanations:
- Duplicating permissions across users - Use groups
- Deep group nesting - Keep 2-3 levels
- Generic relation names - Use semantic names
- Checking after action - Check before
- Not handling authorization errors - Show feedback
References
- CHECK-ALGORITHM.md - How check() works internally
- COMMON-ISSUES.md - Detailed issue solutions
- ANTI-PATTERNS.md - What NOT to do
Related Skills
- polizy-schema - Schema design
- polizy-patterns - Implementation patterns
More Other skills
brand-guidelines
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
theme-factory
Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.
internal-comms
A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).
Fundamental design principles for writing maintainable, testable Python code.
responsive-design
Modern responsive layouts using container queries, fluid typography, CSS Grid, and mobile-first strategies.
Generate Playwright tests from scenarios using interactive browser exploration and validation.
Automated website exploration and test case generation using Playwright.
Modern React state management with Redux Toolkit, Zustand, Jotai, and React Query for every state category.
gdpr-data-handling
GDPR-compliant data handling with consent management, data subject rights, and privacy controls.
Python error handling patterns including input validation, exception hierarchies, and partial failure handling. Use when implementing validation logic, designing exception strategies, handling batch processing failures, or building robust APIs.
refactor-plan
Detailed multi-file refactor planning with safety checks and rollback guidance.
