Role Based Access Control (RBAC)
Relevant source files
The following files were used as context for generating this wiki page:
Role Based Access Control (RBAC) in SeaORM 2.0 is a system designed to restrict database access based on user roles, permissions, and resources. It provides a layer of security that intercepts database queries to ensure the executing user has the appropriate authorization for the requested operation. This feature is integrated into the core ORM through restricted connection wrappers that perform real-time auditing of SQL statements.
Sources: src/lib.rs:434-436, src/database/restricted_connection.rs:20-24
Architecture and Core Components
The RBAC system is built around the RbacEngine, which manages the state of roles, permissions, and hierarchies. It works in conjunction with RestrictedConnection and RestrictedTransaction to enforce access rules during database interactions.
Component Overview
| Component | Description |
|---|---|
RbacEngine | The central logic unit that stores roles, permissions, and hierarchy data. It evaluates whether a user can perform an action. |
RestrictedConnection | A wrapper around DatabaseConnection that performs authorization checks before executing any query. |
RestrictedTransaction | A wrapper around DatabaseTransaction that ensures atomicity while maintaining RBAC enforcement. |
RbacEngineMount | A thread-safe container (Arc<RwLock<Option<RbacEngine>>>) used to share the engine across connections. |
RbacSnapshot | A data structure used to initialize the RbacEngine with roles, resources, and permissions. |
Sources: src/rbac/engine/mod.rs:26-38, src/database/restricted_connection.rs:20-39
Relationship Diagram
The following diagram illustrates how the components interact to provide restricted access.
Data Model and Hierarchy
The RBAC engine utilizes a complex structure of mappings to handle permissions, resources, and role inheritance.
Resource and Permission Evaluation
Permissions and resources are managed using specific IDs and requests. The engine supports wildcards (denoted by *) for both actions and resources (schemas/tables).
- Resources: Defined by a
ResourceId, schema, and table name. - Permissions: Defined by a
PermissionIdand an action (e.g., "browse", "buy"). - Wildcards: If a resource's table or schema is
*, it matches all targets. If a permission's action is*, it grants all rights for that resource.
Sources: src/rbac/engine/mod.rs:54-78, src/rbac/engine/mod.rs:206-231
Role Hierarchy
Roles can inherit permissions from other roles through a parent-child relationship. The engine flattens this hierarchy when checking permissions.
Sources: src/rbac/engine/mod.rs:264-282
Authorization Logic
The primary entry point for checking authorization is the user_can method within the RbacEngine.
Evaluation Sequence
When a request is made, the engine follows this logic:
- User Overrides: Checks if there are specific grants or denials for that specific User ID, Permission, and Resource.
- Role Flattening: Retrieves the user's assigned role and all descendant roles in the hierarchy.
- Permission Set Check: Checks if any assigned role contains the specific (PermissionId, ResourceId) pair.
- Wildcard Matching: Evaluates if any role has a wildcard permission that matches the requested action and resource.
Sources: src/rbac/engine/mod.rs:163-204
Implementation Example: Statement Auditing
Restricted connections automatically audit StatementBuilder objects before execution.
pub fn user_can_run<S: StatementBuilder>(&self, user_id: UserId, stmt: &S) -> Result<(), DbErr> {
let audit = stmt.audit().map_err(|err| DbErr::RbacError(err.to_string()))?;
let engine = self.inner.read().expect("RBAC Engine died");
let engine = engine.as_ref().expect("RBAC Engine not set");
for request in audit.requests {
let action = request.access_type.as_str();
let table = request.schema_table.1.to_string();
// Permission check logic...
}
Ok(())
}
Sources: src/database/restricted_connection.rs:355-376
Restricted Connection and Transactions
The RestrictedConnection ensures that all standard SeaORM operations (execute, query_one, query_all) are authorized.
Connection Restrictions
A key security feature is that raw SQL statements are not supported through RestrictedConnection or RestrictedTransaction. Methods like execute_raw or query_all_raw will return a DbErr::RbacError immediately. This ensures that the engine can always parse and audit the structural query components.
Sources: src/database/restricted_connection.rs:56-96
Transaction Handling
Transactions created from a RestrictedConnection inherit the user context and the RBAC engine state.
Summary
The RBAC system in SeaORM 2.0 provides a robust mechanism for enforcing fine-grained access control at the database connection level. By utilizing a hierarchy of roles, wildcard matching for resources, and explicit user overrides, it allows for complex authorization policies. Its integration via restricted wrappers ensures that developers can secure their data access layer without manually checking permissions before every query, while preventing bypasses via raw SQL.