Skip to main content

Policy & Access Control

This example demonstrates Fluree's data-centric access control model. Unlike traditional application-layer authorization, Fluree policies are stored as data in the ledger itself, ensuring consistent enforcement across all queries and transactions.

The Scenario

A multi-tenant SaaS application needs to:

  • Isolate tenants: Users from ACME should never see Globex's documents
  • Enforce roles: Admins can do everything, Editors can create/edit (but not delete), Viewers can only read
  • Handle confidentiality: Confidential documents are restricted to users in the same department
  • Support public content: Some documents are visible to everyone

These requirements must be enforced consistently, regardless of how the data is accessed.

Schema Overview

graph LR u(User) -->|organization| o(Organization) u -->|role| r(Role) d(Document) -->|organization| o d -->|author| u p(Policy) -.->|controls| d

Entities

EntityDescription
OrganizationTenant (e.g., ACME, Globex)
UserPerson with role and organization membership
RolePermission level (Admin, Editor, Viewer)
DocumentContent with visibility (public, internal, confidential)
PolicyAccess control rules stored as data

Users and Roles

The example includes users across two organizations with different roles:

UserOrganizationRoleDepartment
AliceACMEAdmin-
BobACMEEditor-
CarolACMEViewer-
FrankACMEViewerFinance
GraceACMEEditorHR
DanGlobexAdmin-
EveGlobexEditor-

Document Visibility Levels

Documents have three visibility levels:

LevelWho Can See
publicEveryone (even across organizations)
internalAll users in the same organization
confidentialOnly users in the same department

Policy Model

Fluree policies are defined as data using the f:Policy type. Each policy specifies:

  • Target class: Which entity type the policy applies to
  • Target role: Which users the policy affects
  • Actions: What operations are allowed (view, modify, delete)
  • Where clause: Conditions that must be met

Example policy structure:


{
"@id": "app:policies/tenant-isolation",
"type": ["f:Policy"],
"f:targetClass": { "@id": "app:Document" },
"f:allow": [
{
"f:targetRole": { "@id": "app:roles/viewer" },
"f:action": [{ "@id": "f:view" }],
"f:where": {
"@list": [
{ "@list": ["?$this", "app:organization", "?org"] },
{ "@list": ["?$identity", "app:organization", "?org"] }
]
}
}
]
}

The where clause uses the same pattern language as queries:

  • ?$this refers to the document being accessed
  • ?$identity refers to the current user
  • The clause requires both to share the same organization (?org)

What You'll Learn

In the following pages, you'll explore:

  1. Defining Policies - Create access control rules step by step
  2. Testing Policies - Query as different users and verify restrictions
tip

Fluree's policy model treats authorization as data, which means policies are queryable, version-controlled, and auditable just like any other data in your ledger.