Skip to Content
GuidesAuthorizationFine-Grained Authorization

Fine-Grained Authorization (FGA)

Auris FGA is a Zanzibar-style relationship-based authorization (ReBAC) engine for object-level access control. While RBAC answers “does this user have the view:invoices permission globally?”, FGA answers “does this user have the viewer relation on document #123 specifically?”.

FGA is the right tool when authorization depends on relationships between specific objects — not just user roles.

Common use cases:

  • A document sharing system where each document has individual owners, editors, and viewers
  • A multi-tenant SaaS where access to a project depends on organization membership
  • A file system where a folder’s permissions are inherited by its contents
  • A B2B portal where customer contacts can only see their own organization’s data

FGA replaces Ory Keto as Auris’s ReBAC layer. Set FGA_ENGINE_ENABLED=true in the API environment to activate FGA. When false, the system falls back to Keto (deprecated).


Core Concepts

Objects

An object is an entity in your system identified by a type and an ID, written as type:id. Examples:

  • document:inv-2024-001
  • folder:invoices-q4
  • project:website-redesign
  • organization:acme-corp

Relations

A relation describes how a subject is connected to an object. Relations are defined in the authorization model. Examples: owner, editor, viewer, member, admin.

Subjects

A subject is the entity being authorized. Subjects are also written as type:id. The most common subject type is user. Subjects can also be sets — organization:acme-corp#member means “anyone who is a member of the acme-corp organization”.

Tuples

A relationship tuple is a stored fact: (objectType, objectId, relation, subjectType, subjectId). For example: “user:alice is a viewer of document:report-2024” is stored as:

{ "objectType": "document", "objectId": "report-2024", "relation": "viewer", "subjectType": "user", "subjectId": "alice" }

Authorization Models

The authorization model is a schema written in an OpenFGA-compatible DSL. It defines what types exist and what relations each type supports.

DSL Syntax

type user type organization relations define admin: [user] define member: [user] or admin type project relations define org: [organization] define admin: [user] or admin from org define editor: [user] or admin define viewer: [user] or editor type document relations define project: [project] define owner: [user] define editor: [user] or owner or editor from project define viewer: [user] or editor or viewer from project or member from org of project

This model defines:

  • Any user can be a member or admin of an organization
  • A project belongs to an organization; project admins inherit from org admins
  • A document belongs to a project; its viewer set includes direct viewers, editors, project viewers, and org members

Rewrite Types

Auris FGA supports 6 rewrite types for computing relation membership:

TypeDescriptionDSL Syntax
thisDirect tuple lookup[user]
computedUsersetMembers of another relation on the same objector owner
tupleToUsersetFollow a relation to another object, then get its relationviewer from project
unionUsers in any of the operands[user] or owner
intersectionUsers in all operands[user] and verified
exclusionUsers in the left operand but not the right[user] but not blocked

Creating and Activating a Model

POST/api/fga/modelsRequires: manage:fga_models

Create a new authorization model version. Body: { name: string, dsl: string }. Auris parses and validates the DSL before storing.

POST/api/fga/models/:id/activateRequires: manage:fga_models

Activate a model version. Only one model can be active at a time. Activating a new model does not invalidate existing tuples.


Writing Tuples

Tuples are the runtime data — the actual relationships between objects and subjects in your application.

POST/api/fga/tuplesRequires: manage:fga_tuples

Write one or more relationship tuples. Body: { writes: TupleInput[] }. Each tuple: { objectType, objectId, relation, subjectType, subjectId, subjectRelation? }.

DELETE/api/fga/tuplesRequires: manage:fga_tuples

Delete one or more relationship tuples. Body: { deletes: TupleInput[] }.

POST/api/fga/tuples/bulkRequires: manage:fga_tuples

Write and delete tuples in a single atomic request. Body: { writes: TupleInput[], deletes: TupleInput[] }. Maximum 100 operations per request.

// Share a document with a user (write a tuple) await fetch('/api/fga/tuples', { method: 'POST', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ writes: [ { objectType: 'document', objectId: 'report-2024', relation: 'viewer', subjectType: 'user', subjectId: 'bob', }, ], }), }) // Revoke access (delete a tuple) await fetch('/api/fga/tuples', { method: 'DELETE', headers: { Authorization: `Bearer ${accessToken}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ deletes: [ { objectType: 'document', objectId: 'report-2024', relation: 'viewer', subjectType: 'user', subjectId: 'bob', }, ], }), })

Checking Authorization

Check

The check endpoint answers “does subject X have relation R on object Y?”

POST/api/fga/check

Evaluate whether a subject has a relation on an object. Returns { allowed: boolean }. No authentication required — uses the caller’s identity from the access token unless an explicit subject is provided.

Expand

The expand endpoint returns the full set of subjects that have a given relation on an object, useful for debugging and building user-facing sharing panels.

POST/api/fga/expandRequires: view:fga_tuples

Expand a relation to show all subjects (with resolution path). Body: { objectType, objectId, relation }.

List Objects

The list-objects endpoint returns all objects of a given type that a subject has a specified relation to — useful for filtering query results.

POST/api/fga/list-objectsRequires: view:fga_tuples

List all objects where the subject has the given relation. Body: { objectType, relation, subjectType, subjectId, cursor?, limit? }.


SDK Usage

import { useFga } from '@auris/react' function DocumentPage({ documentId }) { const { check, listObjects, isLoading } = useFga() const [canEdit, setCanEdit] = useState(false) useEffect(() => { check({ object: `document:${documentId}`, relation: 'editor', }).then((result) => setCanEdit(result.allowed)) }, [documentId]) return ( <div> <h1>Document</h1> {canEdit ? ( <button>Edit Document</button> ) : ( <span>Read-only</span> )} </div> ) } // Sharing panel — show who has access function SharingPanel({ documentId }) { const { expand } = useFga() const [viewers, setViewers] = useState([]) useEffect(() => { expand({ objectType: 'document', objectId: documentId, relation: 'viewer', }).then((result) => setViewers(result.subjects)) }, [documentId]) return ( <ul> {viewers.map((viewer) => ( <li key={viewer.subjectId}>{viewer.subjectId}</li> ))} </ul> ) }

Common Patterns

Google Drive Model

A hierarchy where folder permissions propagate to documents:

type user type folder relations define owner: [user] define editor: [user] or owner define viewer: [user] or editor define parent: [folder] define editor_via_parent: editor from parent define viewer_via_parent: viewer from parent type document relations define owner: [user] define parent_folder: [folder] define editor: [user] or owner or editor_via_parent from parent_folder define viewer: [user] or editor or viewer_via_parent from parent_folder

SaaS Multi-Tenant Model

Organization membership controls access to projects and resources:

type user type organization relations define admin: [user] define member: [user] or admin type project relations define organization: [organization] define admin: [user] or admin from organization define member: [user] or member from organization or admin type resource relations define project: [project] define owner: [user] define editor: [user] or owner or admin from project define viewer: [user] or editor or member from project

Debugging with the FGA Console

The Auris Console includes a FGA Debugger at ConsoleAuthorizationDebugger with three tools:

  • Check: Test any object/relation/subject combination and see the resolution tree
  • Expand: Visualize the full subject set for any relation
  • List Objects: Find all objects a user has access to

The resolution tree shows exactly which tuples and model rewrites led to the allowed: true or allowed: false result — essential for diagnosing unexpected authorization outcomes.


Model Templates

The Console provides three model templates to get started quickly:

  • Basic: Simple user/resource model with owner, editor, viewer
  • SaaS: Organization → project → resource hierarchy with team membership
  • Drive: Nested folder/document hierarchy with inherited permissions