What is OpenFGA?
OpenFGA is an open-source authorization engine inspired by Google's Zanzibar — the system that powers authorization for Google Drive, YouTube, and Google Cloud. Built by the Auth0/Okta team.
It answers the question: "Can user X do action Y on resource Z?" — at massive scale.
Quick Start
docker pull openfga/openfga
docker run -p 8080:8080 -p 3000:3000 openfga/openfga run
Define Your Authorization Model
{
"schema_version": "1.1",
"type_definitions": [
{
"type": "user"
},
{
"type": "document",
"relations": {
"owner": { "this": {} },
"editor": {
"union": {
"child": [
{ "this": {} },
{ "computedUserset": { "relation": "owner" } }
]
}
},
"viewer": {
"union": {
"child": [
{ "this": {} },
{ "computedUserset": { "relation": "editor" } }
]
}
}
},
"metadata": {
"relations": {
"owner": { "directly_related_user_types": [{ "type": "user" }] },
"editor": { "directly_related_user_types": [{ "type": "user" }] },
"viewer": { "directly_related_user_types": [{ "type": "user" }] }
}
}
},
{
"type": "folder",
"relations": {
"owner": { "this": {} },
"viewer": {
"union": {
"child": [
{ "this": {} },
{ "computedUserset": { "relation": "owner" } }
]
}
},
"parent": { "this": {} }
},
"metadata": {
"relations": {
"owner": { "directly_related_user_types": [{ "type": "user" }] },
"viewer": { "directly_related_user_types": [{ "type": "user" }] },
"parent": { "directly_related_user_types": [{ "type": "folder" }] }
}
}
}
]
}
This creates a Google Drive-like permission model: owners can edit, editors can view.
Write Relationships
# Alice owns document:readme
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:readme"},
{"user": "user:bob", "relation": "editor", "object": "document:readme"},
{"user": "user:charlie", "relation": "viewer", "object": "document:readme"}
]
}
}'
Check Permissions
# Can Bob view the readme?
curl -X POST http://localhost:8080/stores/STORE_ID/check \
-H "Content-Type: application/json" \
-d '{
"tuple_key": {
"user": "user:bob",
"relation": "viewer",
"object": "document:readme"
}
}'
# Response: {"allowed": true}
# Bob is an editor, and editors can view (inherited)
Node.js SDK
import { OpenFgaClient } from "@openfga/sdk";
const fga = new OpenFgaClient({
apiUrl: "http://localhost:8080",
storeId: "YOUR_STORE_ID",
authorizationModelId: "YOUR_MODEL_ID",
});
// Check permission
const { allowed } = await fga.check({
user: "user:alice",
relation: "viewer",
object: "document:readme",
});
console.log(`Alice can view: ${allowed}`); // true
// Write relationship
await fga.write({
writes: [
{ user: "user:dave", relation: "editor", object: "document:readme" },
],
});
// List objects user can access
const { objects } = await fga.listObjects({
user: "user:alice",
relation: "viewer",
type: "document",
});
console.log(objects); // ["document:readme", "document:notes"]
// List users who can access an object
const { users } = await fga.listUsers({
object: { type: "document", id: "readme" },
relation: "viewer",
user_filters: [{ type: "user" }],
});
Express Middleware
import { OpenFgaClient } from "@openfga/sdk";
const fga = new OpenFgaClient({ apiUrl: "http://localhost:8080", storeId: "..." });
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();
};
}
// Usage
app.get("/documents/:id",
authorize("viewer", (req) => `document:${req.params.id}`),
(req, res) => { /* handler */ }
);
app.put("/documents/:id",
authorize("editor", (req) => `document:${req.params.id}`),
(req, res) => { /* handler */ }
);
Why OpenFGA?
| Feature | OpenFGA | RBAC | ACL |
|---|---|---|---|
| Fine-grained | Yes | No | Partial |
| Relationship-based | Yes | No | No |
| Scale | Millions of checks/sec | Depends | Depends |
| Inherited permissions | Yes | Manual | No |
| Zanzibar model | Yes | No | No |
Need fine-grained authorization for your app?
📧 spinov001@gmail.com
🔧 My tools on Apify Store
RBAC or relationship-based auth — what do you use?
Top comments (0)