Fine-Grained Authorization
Role-based access answers "what can an editor do?". Fine-grained authorization answers "can this editor change this specific document?", taking into account the actor's roles, who owns the resource, which folder it sits in, who it has been shared with, and the context of the request.
Authorization Models
| Model | Decides from | Fits when | Watch for |
|---|---|---|---|
| Roles (RBAC) | The actor's roles in the organization | Permissions follow job function. | Role explosion when exceptions are modeled as roles. |
| Relationships (ReBAC) | A graph of relationships between actors and resources | Access follows ownership, hierarchy, and sharing. Engines such as OpenFGA or SpiceDB. | A second datastore to keep consistent with product data. |
| Attributes (ABAC) | Attributes of the actor, resource, and request | Decisions depend on context: region, classification, time, plan. Engines such as Cedar or Open Policy Agent. | Policies nobody can read; they need tests like any code. |
Most products combine organization roles with resource relationships, and add attribute conditions only where a requirement names them.
Roles and Custom Roles
Rendering diagram…
Diagram source
flowchart LR
subgraph product [Defined by the product]
permissions[Permissions: invoices.read, projects.delete, ...]
system[System roles: Admin, Member, Viewer]
end
subgraph org [Defined by each organization]
custom[Custom roles]
conditions[Optional conditions]
end
permissions --> system
permissions --> custom
conditions --> custom
system --> assignments[Role assignments]
custom --> assignments
assignments --> engine[Policy engine]
- Permissions are the product's vocabulary. They are defined in code, versioned, and documented. Organizations cannot invent new permissions; they can only combine existing ones.
- System roles are immutable. Their permissions evolve with the product. Custom roles are owned by the organization and change only when its admins change them.
- New permissions need a decision. A permission that extends an existing capability (
reports.export) can follow an implication rule such as "reports.readimpliesreports.export". One that grants new sensitive access (billing.refund) is never added to custom roles automatically.
Relationships and Ownership
Rendering diagram…
Diagram source
flowchart LR alice([user:alice]) -->|member| team[team:design] team -->|editor| folder[folder:brand] folder -->|parent| doc[document:logo-v3] bob([user:bob]) -->|viewer| doc org[org:acme] -->|owns| folder carol([user:carol]) -->|admin| org
An authorization model defines how permissions follow relationships:
type document
relations
define parent: [folder]
define viewer: [user, team#member] or editor
define editor: [user, team#member] or editor from parentWith this model, check(user:alice, edit, document:logo-v3) is allowed: Alice is a member of the design team, which edits the parent folder. Bob can view but not edit. Carol's access follows from an organization-level rule.
Sharing and Delegation
Sharing lets an actor grant others access to something they control. Delegation goes further, letting an actor hand over part of their own authority, such as an assistant who manages a calendar for an executive. Both are stored as relationships the policy engine already understands.
| Grant | Example | Stored as |
|---|---|---|
| Direct share | Share a document with Bob as editor | document:42#editor@user:bob |
| Group share | Share a project with the design team | project:7#viewer@team:design#member |
| Link share | Anyone in the organization with the link can view | Relationship to a wildcard within the organization |
| External share | Share with a guest outside the organization | Guest membership with no organization-wide permissions |
| Delegation | Assistant acts for an executive on calendar items | Delegation record with scope and expiry |
- No escalation. An actor can grant at most the access they hold. A viewer cannot share as editor.
- Organization boundaries. Organization policy decides whether external sharing and public links are allowed at all.
- Expiry. Shares and delegations can carry an expiry; guest access in particular should expire by default.
- Delegation is scoped. A delegate acts within an explicit scope, and every action records both the delegate and the person they acted for.
Decision Flow
Rendering diagram…
Diagram source
sequenceDiagram autonumber participant A as Application participant E as Policy engine participant C as Decision cache A->>C: check(alice, edit, document:logo-v3) C-->>A: miss A->>E: check(alice, edit, document:logo-v3) E->>E: Walk relationships and evaluate conditions E-->>A: allowed, via team:design editor of folder:brand A->>C: store with short expiry
Rules that apply to everyone, such as "only the resource owner can delete it" or "suspended organizations are read-only", live as policies in the engine's language alongside tests:
subject action resource expected
user:alice (admin) project.delete project:42 (org A) allow
user:bob (viewer) project.delete project:42 (org A) deny
user:alice (admin) project.delete project:77 (org B) denyAcross Ownership Scopes
| Scope | Who owns what |
|---|---|
| Managed | The broker's roles and permissions, within what the platform models. Resource-level rules usually outgrow it. |
| Hybrid | The application owns the authorization model, evaluated in code or through a dedicated engine. |
| Built | Policies, relationships, evaluation, and enforcement are implemented internally, usually around an open-source engine. |
Watch For
- Role explosion. If every exception becomes a new role, roles stop meaning anything. Exceptions belong in resource-level grants or conditions.
- Explainability. Every decision should come with a reason, for support staff and for audits. Engines that return the path of a decision make this cheap.
- Model changes. The authorization model is code: reviewed, versioned, and tested against a table of expected decisions before deployment.
- Self-lockout. Prevent changes that would leave an organization without anyone able to manage roles.
- Ownership transfer. When an owner leaves, decide whether their resources move to a manager, to the organization, or stay frozen.
- Link shares. Links are bearer credentials. They need revocation and, for sensitive resources, should require sign-in.
- Listing, not just checking. "Which documents can Alice see?" is a different query from "can Alice see this document?". See Authorization-Aware Data Access.