Skip to main content

systemprompt_security/authz/repository/
mod.rs

1//! `AccessControlRepository` — sqlx-backed access to the two-table authz
2//! schema.
3//!
4//! `access_control_entities` owns one row per `(entity_type, entity_id)` and
5//! carries the `default_included` flag plus a `source` provenance string.
6//! `access_control_rules` is the per-(entity, subject) grant table, with a
7//! foreign key back to the entity catalog. Callers fetch the entity row
8//! first (a `None` result signals an entity unknown to access control), then
9//! list rules for it, and hand both to [`super::resolver::resolve`].
10//!
11//! Copyright (c) systemprompt.io — Business Source License 1.1.
12//! See <https://systemprompt.io> for licensing details.
13
14mod entities;
15mod rules;
16
17pub use rules::ChainFingerprint;
18
19use std::sync::Arc;
20
21use sqlx::PgPool;
22use systemprompt_database::DbPool;
23
24use super::error::{AuthzError, AuthzResult};
25use super::types::{Access, EntityKind, RuleType};
26
27#[derive(Debug, Clone)]
28pub struct ExportRuleRow {
29    pub entity_type: String,
30    pub entity_id: String,
31    pub rule_type: String,
32    pub rule_value: String,
33    pub access: String,
34    pub justification: Option<String>,
35}
36
37#[derive(Debug, Clone)]
38pub struct UpsertRuleParams<'a> {
39    pub entity_type: EntityKind,
40    pub entity_id: &'a str,
41    pub rule_type: RuleType,
42    pub rule_value: &'a str,
43    pub access: Access,
44    pub justification: Option<&'a str>,
45}
46
47#[derive(Clone, Debug)]
48pub struct AccessControlRepository {
49    pool: Arc<PgPool>,
50    write_pool: Arc<PgPool>,
51}
52
53impl AccessControlRepository {
54    pub fn new(db: &DbPool) -> AuthzResult<Self> {
55        let pool = db
56            .pool_arc()
57            .map_err(|err| AuthzError::Validation(err.to_string()))?;
58        let write_pool = db
59            .write_pool_arc()
60            .map_err(|err| AuthzError::Validation(err.to_string()))?;
61        Ok(Self { pool, write_pool })
62    }
63
64    pub fn from_pool(pool: Arc<PgPool>) -> Self {
65        let write_pool = Arc::clone(&pool);
66        Self { pool, write_pool }
67    }
68}