rs-tenant 0.2.0

Multi-tenant RBAC authorization engine for Rust
Documentation

rs-tenant

Rust 多租户 RBAC 授权库。

rs-tenant 提供一个可插拔的授权引擎,目标是将“权限决策”与“业务存储实现”解耦:

  • 在租户上下文内进行授权判定:authorize
  • 在租户上下文内进行“权限 + 目标层级作用域”联合判定:authorize_with_scope
  • 在查询前计算可访问范围:scope
  • 通过 Store trait 接入任意数据库/缓存

默认策略为 Deny by default

适用场景

适合:

  • SaaS 多租户系统
  • 同时存在租户角色与平台全局角色的系统
  • 希望将权限判断从业务逻辑中抽离的服务

不适合:

  • 以复杂 ABAC 为主的授权模型
  • 需要库内直接托管 ORM 模型与迁移

核心能力

  • 强类型 ID:TenantIdPrincipalIdRoleIdGlobalRoleId
  • 权限模型:resource:action(如 invoice:read
  • 租户角色 + 平台角色并集授权
  • 可选角色继承(含环检测、深度限制)
  • 可选 wildcard(如 *:*invoice:*
  • 可选超级管理员短路授权
  • 层级作用域授权(ScopePath + ScopeStore,支持祖先路径放行)
  • 可选内存缓存(TTL、LRU、分片)
  • Axum 中间件集成(可选 JWT 解析)

快速开始

1) 添加依赖

[dependencies]
rs-tenant = { version = "0.1", features = ["memory-store"] }

2) 最小授权示例

use rs_tenant::{
    Decision, EngineBuilder, MemoryStore, Permission, PrincipalId, RoleId, TenantId,
};

async fn demo() -> rs_tenant::Result<()> {
    let store = MemoryStore::new();

    let tenant = TenantId::try_from("tenant_a")?;
    let principal = PrincipalId::try_from_parts("employee", "user_1")?;
    let role = RoleId::try_from("invoice_reader")?;
    let permission = Permission::try_from("invoice:read")?;

    store.set_tenant_active(tenant.clone(), true);
    store.set_principal_active(tenant.clone(), principal.clone(), true);
    store.add_principal_role(tenant.clone(), principal.clone(), role.clone());
    store.add_role_permission(tenant.clone(), role, permission.clone());

    let engine = EngineBuilder::new(store).build();
    let decision = engine.authorize(tenant, principal, permission).await?;

    assert_eq!(decision, Decision::Allow);
    Ok(())
}

3) 本地验证

cargo test --offline --features memory-store,memory-cache

授权语义(摘要)

authorize(tenant, principal, permission) 执行顺序:

  1. tenant_active(tenant)
  2. (可选)is_super_admin(principal)
  3. principal_active(tenant, principal)
  4. 收集权限(租户角色 + 全局角色)
  5. 按配置匹配权限,返回 AllowDeny

scope(tenant, principal, resource) 返回:

  • Scope::TenantOnly { tenant }
  • Scope::None

authorize_with_scope(tenant, principal, permission, target_scope) 执行顺序:

  1. 先执行 authorize 全流程(租户、主体、角色/全局角色权限匹配)
  2. authorize = Deny,直接返回 Deny
  3. 若开启 super-admin 且命中,直接返回 Allow
  4. 否则调用 ScopeStore::scope_allows 校验目标层级作用域,命中返回 Allow,否则 Deny

默认 scope_allows 语义为“主体作用域与目标作用域相等或为其祖先路径”。

超级管理员为平台级能力,但仍受 tenant_active 约束。

Feature 开关

[features]
default = []
serde = []
memory-store = []
memory-cache = []
axum = []
axum-jwt = []
criterion-bench = []
casbin = []

说明:

  • axum-jwt 依赖 axumserde
  • casbin 当前仅保留 feature 开关,未提供公开适配 API

生产集成建议

生产环境通常按以下步骤接入:

  1. 设计权限数据模型(租户、主体、角色、权限、继承、全局角色、超级管理员)
  2. 实现 Store 接口:TenantStoreRoleStoreGlobalRoleStore(需要层级作用域控制时再实现 ScopeStore
  3. 使用 EngineBuilder 组装引擎(继承/wildcard/super-admin/缓存)
  4. 在权限数据变更后执行缓存失效

缓存失效接口:

  • invalidate_principal(tenant, principal)
  • invalidate_role(tenant, role)
  • invalidate_tenant(tenant)

Axum 集成

  • 启用 axumaxum-jwt feature
  • 在请求扩展中注入 AuthContext { tenant, principal }
  • 使用 AuthorizeLayer 为路由绑定权限
  • 使用 JWT 时可配合 JwtAuthLayer

详细示例见 docs/06-axum-integration.md

文档目录

完整中文文档见 docs/

  • docs/README.md:文档首页
  • docs/01-overview.md:项目总览
  • docs/02-domain-model.md:领域模型与权限语义
  • docs/03-authorization-flow.md:授权流程详解
  • docs/04-quickstart.md:5 分钟接入
  • docs/05-integration-production.md:生产集成指南
  • docs/06-axum-integration.md:Axum/JWT 集成
  • docs/07-examples.md:典型案例
  • docs/08-testing-benchmark.md:测试与基准
  • docs/09-faq-troubleshooting.md:FAQ 与排查
  • docs/10-rs-tenant-vs-casbin.md:与 Casbin 的区别与选型

文档发布(mdBook + GitHub Pages)

仓库已内置 book.toml.github/workflows/mdbook.yml,文档会在 main 分支的文档变更后自动发布到 GitHub Pages。

本地预览:

cargo install mdbook --locked
mdbook serve

首次启用 GitHub Pages:

  1. 打开仓库 Settings -> Pages
  2. Build and deploymentSource 选择 GitHub Actions
  3. 合并并推送本次配置后,等待 Deploy mdBook to GitHub Pages 工作流完成

开发与测试命令

# 默认测试
cargo test --offline

# 带内存存储/缓存测试
cargo test --offline --features memory-store,memory-cache

# 手工性能测试
cargo test --offline --features memory-store,memory-cache --test perf -- --ignored --nocapture

# Criterion 基准
cargo bench --features criterion-bench,memory-store,memory-cache

设计边界

  • 本库只负责授权决策与作用域计算,不负责业务数据模型
  • 不内置数据库迁移管理
  • MemoryStore 主要用于测试与演示

贡献说明

欢迎提交 Issue 和 PR。提交前建议:

  1. 补充或更新相关测试
  2. 运行上述测试命令
  3. 若涉及性能路径,附上基准对比结果

仓库贡献约定见 AGENTS.md