ACL: Permission Storage and Inheritance

The ACL (Access Control List) system stores all permissions and handles permission checking at runtime. ACL entries are stored in the acls table, with each row linking a principal to a dataset with a specific permission.
Runtime permission calculation — The system doesn’t store “effective permissions” anywhere—it calculates them on demand by querying ACL entries.

How ACL Works

When a user tries to access data, the system queries all relevant ACL entries and aggregates the permissions. The permission checking function get_all_user_permission_datasets() unions the user’s direct permissions with those inherited from their tenant and roles, combining all three sources: direct user permissions, tenant-level permissions, and role-level permissions. This approach ensures permissions are always current and allows for complex permission inheritance without data duplication.

ACL Storage Schema

The ACL system uses a simple but powerful schema to store permissions:

Permission Resolution Order

The system evaluates permissions in a specific order:
  1. Direct user permissions — Explicitly granted to the user
  2. Role permissions — Inherited through the user’s role memberships
  3. Tenant permissions — Inherited through the user’s tenant membership
This order allows for flexible permission management where more specific permissions can override broader ones.

ACL Operations

The ACL system supports several key operations:
  • Grant permissions — Add new ACL entries to grant access
  • Revoke permissions — Remove ACL entries to revoke access
  • Check permissions — Query ACL entries to determine access
  • List permissions — Get all permissions for a principal or dataset

Permission Inheritance

The ACL system implements a three-tier inheritance model:
  • User level — Direct permissions granted to individual users
  • Role level — Permissions granted to roles, inherited by role members
  • Tenant level — Permissions granted to tenants, inherited by all tenant members
Users receive the union of all permissions from these three sources, giving them the most permissive access available.

Performance Considerations

The ACL system is designed for performance:
  • Indexed queries — Database indexes on principal_id, dataset_id, and permission_id
  • Efficient lookups — Single query to get all permissions for a user
  • Caching opportunities — Permission results can be cached for frequently accessed datasets
  • Batch operations — Support for granting/revoking multiple permissions at once

Security Features

The ACL system includes several security features:
  • Immutable ownership — Dataset ownership cannot be changed
  • Permission validation — All permission checks go through the ACL system
  • Audit trail — All permission changes are logged with timestamps
  • Isolation — Users can only access datasets they have permissions for

Troubleshooting

Common ACL-related issues and solutions:
  • Permission denied — Check if user has required permission on the dataset
  • Missing permissions — Verify ACL entries exist for the principal and dataset
  • Inheritance issues — Check role and tenant memberships
  • Performance problems — Review database indexes and query patterns