cognee_database/traits/acl_db.rs
1use async_trait::async_trait;
2use uuid::Uuid;
3
4use crate::types::DatabaseError;
5
6/// Access control list database trait.
7///
8/// Provides methods to check, grant, and revoke permissions on datasets
9/// for principals (users, roles, tenants). All implementations must be
10/// thread-safe for async multi-threaded usage.
11///
12/// The blanket `impl AclDb for DatabaseConnection` moved to the closed
13/// `cognee-access-control` crate. OSS callers wire ACL through `MockAclDb` (tests) or through the
14/// closed `AccessControl` newtype (production cloud builds).
15#[async_trait]
16pub trait AclDb: Send + Sync {
17 /// Check if a principal has a specific permission on a dataset.
18 ///
19 /// Returns `true` if a matching ACL row exists (direct principal match).
20 async fn has_permission(
21 &self,
22 principal_id: Uuid,
23 dataset_id: Uuid,
24 permission_name: &str,
25 ) -> Result<bool, DatabaseError>;
26
27 /// Return all dataset IDs for which the principal has the given permission.
28 async fn authorized_dataset_ids(
29 &self,
30 principal_id: Uuid,
31 permission_name: &str,
32 ) -> Result<Vec<Uuid>, DatabaseError>;
33
34 /// Grant a permission on a dataset to a principal.
35 ///
36 /// Idempotent: no-op if the grant already exists.
37 async fn grant_permission(
38 &self,
39 principal_id: Uuid,
40 dataset_id: Uuid,
41 permission_name: &str,
42 ) -> Result<(), DatabaseError>;
43
44 /// Revoke a permission on a dataset from a principal.
45 async fn revoke_permission(
46 &self,
47 principal_id: Uuid,
48 dataset_id: Uuid,
49 permission_name: &str,
50 ) -> Result<(), DatabaseError>;
51
52 /// Ensure a principal row exists (upsert by ID).
53 async fn ensure_principal(
54 &self,
55 principal_id: Uuid,
56 principal_type: &str,
57 ) -> Result<(), DatabaseError>;
58
59 /// Check permission considering role and tenant inheritance.
60 ///
61 /// Resolution order (mirrors Python `get_all_user_permission_datasets`):
62 /// 1. Direct user ACL
63 /// 2. Tenant-level ACL for each tenant the user belongs to
64 /// 3. Role-level ACL for each role the user holds in those tenants
65 async fn has_permission_with_roles(
66 &self,
67 user_id: Uuid,
68 dataset_id: Uuid,
69 permission_name: &str,
70 ) -> Result<bool, DatabaseError>;
71
72 /// Return all dataset IDs the user can access via direct, tenant, or
73 /// role grants. Deduplicates results.
74 async fn authorized_dataset_ids_with_roles(
75 &self,
76 user_id: Uuid,
77 permission_name: &str,
78 ) -> Result<Vec<Uuid>, DatabaseError>;
79}