-
-
Notifications
You must be signed in to change notification settings - Fork 642
Description
Motivation
Many real-world applications require sophisticated row-level security (data permissions) where different users should see different subsets of data based on their roles, departments, or other contextual attributes. Currently, SeaORM users must implement data permission logic manually by adding filter conditions to each query, which leads to:
Code duplication: Similar permission logic repeated across multiple queries
Maintenance overhead: Business rule changes require code modifications
Security risks: Inconsistent permission application due to human error
Poor separation of concerns: Data access rules mixed with business logic
The expected outcome is a declarative system where data permission rules can be defined externally and applied consistently across all queries, similar to Axelor's proven permission system.
Proposed Solutions
Current Codebase Opportunity
I noticed that in the current SeaORM codebase, the RBAC entity structure at src/rbac/entity/resource.rs:13has a foundation that could be extended to support this feature:
pub struct Model {
#[sea_orm(primary_key)]
pub id: ResourceId,
#[sea_orm(unique_group = "1")]
pub schema: Option<String>,
#[sea_orm(unique_group = "1")]
pub table: String,
// Proposed additions for data permissions:
// pub condition: Option<String>, // Permission condition expression
// pub condition_values: Option<Json>, // Parameter values for the condition
}
Adding conditionand condition_valuesfields would provide native support for storing row-level data permission rules directly in the entity definition, making SeaORM a complete solution for both schema management and data access control.
- Permission Rule Configuration
Allow defining data permission rules in YAML/JSON that can be loaded at runtime:
# data_permissions.yaml
permissions:
- entity: "post"
condition: "user_id = ?1 OR status = 'public'"
parameters:
- position: 1
value_source: "current_user.id"
enabled: true
- entity: "post"
condition: "department_id = ?1 AND created_at > ?2"
parameters:
- position: 1
value_source: "current_user.department.id"
- position: 2
value_source: "fixed_value"
value: "2024-01-01"
- Query Builder Integration
Extend SeaORM's query builder with permission-aware methods:
// Automatic permission application
let posts = Post::find()
.with_data_permissions(¤t_user_context)
.all(db)
.await?;
// Manual rule application for complex cases
let query = Post::find()
.apply_permission_rule("department_posts", &context)
.filter(/* other conditions */);
- Permission-Aware Selector
A new trait for automatic permission injection:
#[derive(DataPermission)]
#[permission(rules = "path/to/permissions.yaml")]
pub struct PostPermission;
// Auto-applies rules to all Post queries
let posts = Post::find().secure_fetch(db, &user_context).await?;
- Expression Language Features
Support common SQL operators and functions:
Comparison: =, !=, >, >=, <, <=, IN, LIKE
Logical: AND, OR, NOT
Functions: CURRENT_DATE, LOWER, etc.
Parameter resolution: ?1, ?2with value sources (current user, session, fixed values)
Additional Information
Prior Art & Inspiration
Axelor: Proven enterprise permission system with declarative rules
Django: Row-level permissions via model meta
Hibernate: @Filterannotation for session-level filtering
PostgreSQL: Native row-level security policies
Implementation Considerations
Performance: Rule compilation/caching to minimize runtime overhead
Flexibility: Support both global and per-query permission application
Compatibility: Work with existing SeaORM features (relations, transactions, etc.)
Extensibility: Allow custom parameter resolvers and condition builders
Use Cases
Multi-tenant applications: Data isolation between tenants
Enterprise systems: Department-based data access
CRM/ERP systems: User role-based record visibility
Compliance requirements: Regulatory data access controls
This feature would significantly enhance SeaORM's enterprise readiness while maintaining the excellent developer experience it's known for. I believe this aligns well with SeaORM's philosophy of being both powerful and ergonomic.
I'm happy to contribute to the implementation if this feature proposal is accepted by the core team.