polizy-storage
SKILL.md
Polizy Storage
Storage adapters handle persistence of authorization tuples.
When to Apply
- User asks "set up database storage"
- User asks "use Prisma with polizy"
- User asks "create custom storage adapter"
- User asks about "production storage"
- User has performance concerns with authorization
Adapter Comparison
| Feature | InMemoryStorageAdapter | PrismaAdapter |
|---|---|---|
| Persistence | No (RAM only) | Yes (database) |
| Multi-instance | No | Yes |
| Setup | Zero config | Prisma model required |
| Performance | Fastest | Good with indexes |
| Use case | Testing, dev | Production |
Quick Setup
InMemory (Development/Testing)
import { AuthSystem, InMemoryStorageAdapter } from "polizy";
const storage = new InMemoryStorageAdapter();
const authz = new AuthSystem({ storage, schema });
Prisma (Production)
import { AuthSystem } from "polizy";
import { PrismaAdapter } from "polizy/prisma-storage";
import { PrismaClient } from "@prisma/client";
const prisma = new PrismaClient();
const storage = PrismaAdapter(prisma);
const authz = new AuthSystem({ storage, schema });
Requires Prisma model - see PRISMA-ADAPTER.md
InMemoryStorageAdapter
When to Use
- Unit tests
- Development environment
- Single-process applications
- Prototyping
Behavior
- Data stored in JavaScript
Map - Lost on process restart
- No network latency
- Fastest possible reads
Testing Example
import { describe, it, beforeEach } from "node:test";
import { AuthSystem, InMemoryStorageAdapter, defineSchema } from "polizy";
describe("authorization", () => {
let authz: AuthSystem<typeof schema>;
beforeEach(() => {
// Fresh storage for each test
const storage = new InMemoryStorageAdapter();
authz = new AuthSystem({ storage, schema });
});
it("grants access correctly", async () => {
await authz.allow({
who: { type: "user", id: "alice" },
toBe: "owner",
onWhat: { type: "doc", id: "doc1" }
});
const result = await authz.check({
who: { type: "user", id: "alice" },
canThey: "edit",
onWhat: { type: "doc", id: "doc1" }
});
assert.strictEqual(result, true);
});
});
PrismaAdapter
When to Use
- Production environments
- Multi-instance deployments
- Need audit trail
- Data must survive restarts
Setup Steps
-
Install dependencies
npm install @prisma/client npm install -D prisma -
Add Prisma model (see PRISMA-ADAPTER.md)
-
Run migrations
npx prisma migrate dev --name add_polizy -
Use adapter
import { PrismaAdapter } from "polizy/prisma-storage"; const storage = PrismaAdapter(prisma);
Storage Interface
All adapters implement:
interface StorageAdapter<S, O> {
write(tuples: InputTuple[]): Promise<StoredTuple[]>;
delete(filter: DeleteFilter): Promise<number>;
findTuples(filter: TupleFilter): Promise<StoredTuple[]>;
findSubjects(object, relation, options?): Promise<Subject[]>;
findObjects(subject, relation, options?): Promise<AnyObject[]>;
}
Common Patterns
Shared Storage Instance
// storage.ts
import { InMemoryStorageAdapter } from "polizy";
// or: import { PrismaAdapter } from "polizy/prisma-storage";
export const storage = new InMemoryStorageAdapter();
// or: export const storage = PrismaAdapter(prisma);
// auth.ts
import { AuthSystem } from "polizy";
import { storage } from "./storage";
import { schema } from "./schema";
export const authz = new AuthSystem({ storage, schema });
Environment-Based Selection
import { AuthSystem, InMemoryStorageAdapter } from "polizy";
import { PrismaAdapter } from "polizy/prisma-storage";
import { PrismaClient } from "@prisma/client";
function createStorage() {
if (process.env.NODE_ENV === "test") {
return new InMemoryStorageAdapter();
}
const prisma = new PrismaClient();
return PrismaAdapter(prisma);
}
const storage = createStorage();
export const authz = new AuthSystem({ storage, schema });
Performance Considerations
| Concern | Solution |
|---|---|
| Slow reads | Add database indexes |
| Too many queries | Reduce group nesting depth |
| Large tuple counts | Periodic cleanup of expired tuples |
| Batch operations | Use writeTuple with parallel Promise.all |
Common Issues
| Issue | Solution |
|---|---|
| Data lost on restart | Switch from InMemory to Prisma |
| "Table doesn't exist" | Run npx prisma migrate deploy |
| Slow checks | Reduce group/hierarchy depth |
| Memory growing | Clean up expired conditional tuples |
References
- PRISMA-ADAPTER.md - Full Prisma setup
- CUSTOM-ADAPTERS.md - Building custom adapters
- PERFORMANCE.md - Optimization strategies
Related Skills
- polizy-setup - Initial setup
- polizy-troubleshooting - Debugging
Weekly Installs
3
Repository
bratsos/polizyGitHub Stars
6
First Seen
Feb 3, 2026
Security Audits
Installed on
opencode3
gemini-cli3
antigravity3
claude-code3
github-copilot3
cursor3