4.6 KiB
Principals
The unified abstraction for entities that can hold permissions in Cognee
Principals: The Abstraction
A principal is any entity that can hold permissions in Cognee. This abstraction allows the permission system to work with different types of entities in a unified way, eliminating the need for separate permission systems for users, tenants, and roles.
Polymorphic design — All principal types use the same permission mechanism, making the system flexible and consistent.
Principal Types
There are three types of principals:
- Users — Individual people who interact with the system
- Tenants — Organizations or groups that contain users
- Roles — Groups of users within a tenant
All three types inherit from the same base Principal class, which means they can all be granted permissions on datasets using the same functions and mechanisms.
How Principals Work with Permissions
The system stores permissions by linking principals to datasets. You can grant permissions to any of the principals using built-in functions like give_permission_on_dataset() and get_principal_datasets(). When you grant a permission, you specify:
- Which principal gets the permission
- Which dataset the permission applies to
- What type of permission (read, write, delete, share)
This unified approach means you can grant permissions to:
- Individual users for personal access
- Tenants for organization-wide access
- Roles for team-based access within a tenant
id: Unique identifier (UUID primary key)created_at: Timestamp when createdupdated_at: Timestamp when last modifiedtype: Discriminator field for polymorphic inheritance
Each principal type (User, Tenant, Role) has its own table that references the principals table via foreign key, storing additional fields specific to that type.
The permission system links principals to datasets with permissions:principal_id: References the principal (user, tenant, or role)dataset_id: References the datasetpermission_id: References the permission type
This many-to-many relationship allows flexible permission management across different entity types.
* `give_permission_on_dataset(principal, dataset_id, permission)`: Writes a single ACL row (or reuses an existing one) so a [user](./users), [tenant](./tenants), or [role](./roles) gains read, write, delete, or share on that dataset. It's the building block used after dataset creation or whenever access is delegated.get_principal_datasets(principal, permission): Queries those ACL entries (and the related dataset records) so you can list every dataset where that same principal holds the requested permission—handy for permission checks or UI listings.
Permission Inheritance
The principal system supports hierarchical permission inheritance:
- Direct permissions — Explicitly granted to a specific principal
- Role permissions — Inherited through role memberships
- Tenant permissions — Inherited through tenant membership
When a user tries to access data, the system evaluates their effective permissions by combining all three sources. This allows for flexible access control patterns:
- Grant broad permissions at the tenant level
- Refine access with role-specific permissions
- Override with direct user permissions when needed
Benefits of the Principal System
- Unified interface — Same functions work for all principal types
- Flexible access control — Support for individual, team, and organization-level permissions
- Scalable management — Easy to add new principal types or modify existing ones
- Consistent behavior — All principals follow the same permission rules and patterns
To find navigation and other pages in this documentation, fetch the llms.txt file at: https://docs.cognee.ai/llms.txt