OpenFGA is an open-source authorization engine inspired by Google Zanzibar — the system that powers permissions in Google Drive, YouTube, and Google Cloud. Build relationship-based access control for any app.
Why OpenFGA?
- Google Zanzibar: Same model used by Google, Airbnb, GitHub
- Relationship-based: 'Alice is editor of document:1'
- Sub-millisecond: Check permissions in <1ms
- Any scale: Handles billions of relationships
- Open source: CNCF project from Auth0/Okta
- Language SDKs: JS, Go, Python, Java, .NET
Docker Setup
docker run -p 8080:8080 -p 3000:3000 openfga/openfga run
Define Authorization Model
{
"schema_version": "1.1",
"type_definitions": [
{
"type": "document",
"relations": {
"owner": {"this": {}},
"editor": {"union": {"child": [{"this": {}}, {"computedUserset": {"relation": "owner"}}]}},
"viewer": {"union": {"child": [{"this": {}}, {"computedUserset": {"relation": "editor"}}]}}
}
},
{
"type": "folder",
"relations": {
"owner": {"this": {}},
"viewer": {"union": {"child": [{"this": {}}, {"computedUserset": {"relation": "owner"}}]}}
}
}
]
}
This means: owners are editors, editors are viewers (inheritance).
Write Relationships
curl -X POST http://localhost:8080/stores/STORE_ID/write \
-H 'Content-Type: application/json' \
-d '{
"writes": {
"tuple_keys": [
{"user": "user:alice", "relation": "owner", "object": "document:budget-2026"},
{"user": "user:bob", "relation": "editor", "object": "document:budget-2026"},
{"user": "user:charlie", "relation": "viewer", "object": "document:budget-2026"}
]
}
}'
Check Permission
curl -X POST http://localhost:8080/stores/STORE_ID/check \
-H 'Content-Type: application/json' \
-d '{
"tuple_key": {
"user": "user:alice",
"relation": "editor",
"object": "document:budget-2026"
}
}'
# {"allowed": true} — Alice is owner, owners inherit editor
JavaScript SDK
import { OpenFgaClient } from '@openfga/sdk';
const fga = new OpenFgaClient({
apiUrl: 'http://localhost:8080',
storeId: 'STORE_ID',
});
// Write relationship
await fga.write({
writes: [{ user: 'user:alice', relation: 'editor', object: 'document:report' }],
});
// Check permission
const { allowed } = await fga.check({
user: 'user:alice',
relation: 'viewer',
object: 'document:report',
});
console.log(allowed); // true (editors inherit viewer)
// List objects user can access
const { objects } = await fga.listObjects({
user: 'user:alice',
relation: 'viewer',
type: 'document',
});
console.log(objects); // ['document:report', 'document:budget-2026']
Express Middleware
function authorize(relation: string, getObject: (req) => string) {
return async (req, res, next) => {
const { allowed } = await fga.check({
user: `user:${req.user.id}`,
relation,
object: getObject(req),
});
if (!allowed) return res.status(403).json({ error: 'Forbidden' });
next();
};
}
app.get('/documents/:id',
authorize('viewer', (req) => `document:${req.params.id}`),
getDocument
);
app.put('/documents/:id',
authorize('editor', (req) => `document:${req.params.id}`),
updateDocument
);
Real-World Use Case
A document collaboration app used RBAC (admin/user roles). Users wanted to share individual docs with specific people — impossible with RBAC. After switching to OpenFGA, they built Google Drive-style sharing in 1 day: per-document owner/editor/viewer with inheritance.
Need to automate data collection? Check out my Apify actors for ready-made scrapers, or email spinov001@gmail.com for custom solutions.
Top comments (0)