kirino 0.1.0

A customizable, zero-trust authentication framework.
Documentation

A fully generic, trait-based authentication and authorization framework for Rust. Provides identity types, credential management, passport challenges, and a complete RBAC system (RBAC0/1/2) implementing the ANSI INCITS 359-2004 standard.

The name kirino comes from the character Kirino in the game Blue Archive.

Still in development, the API may change in the future.

Features

  • ๐Ÿ›ก๏ธ Zero-Trust Architecture: Anonymous, Basic, Temporary, and Service identity types
  • ๐Ÿ”‘ Multi-Credential Support: One-time tokens, JWT, service tokens, and more
  • ๐ŸŽซ Passport Challenges: Static password, key pair, OAuth, TOTP/HOTP, captcha, biometric
  • ๐Ÿ”’ Argon2 Password Hashing: Secure password verification out of the box
  • ๐ŸŽฏ Full RBAC System: RBAC0 (base), RBAC1 (hierarchy), RBAC2 (constraints)
  • ๐Ÿ”„ Role Inheritance: Multi-level role hierarchies with cycle detection
  • โ›“๏ธ Separation of Duty: SSD (static) and DSD (dynamic) constraint enforcement
  • ๐Ÿ“Š Cardinality & Prerequisite Constraints: Limit role holders and enforce role prerequisites
  • โฑ๏ธ Temporal Constraints: Time-bounded role validity with automatic expiry
  • ๐Ÿ’พ In-Memory First: Zero-dependency reference implementations for all backends
  • ๐Ÿ—„๏ธ Pluggable Storage: Trait-based backends for SQL, Redis, and more
  • ๐Ÿ“ Audit Logging: Permission check audit trail for compliance
  • ๐Ÿงฉ Fully Generic: Define your own Permission and Subject types via traits
  • โšก Async/Tokio: Built on async Rust with Tokio runtime
  • ๐Ÿ”Œ JWT Integration: Built-in JWT issuance and verification

Quick Start

Add kirino to your Cargo.toml:

[dependencies]
kirino = "0.1"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }

Define your permissions and roles:

use serde::{Deserialize, Serialize};
use kirino::rbac::prelude::*;

#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
enum MyPermission {
    DocumentRead,
    DocumentWrite,
    UserManage,
}

impl Permission for MyPermission {
    fn name(&self) -> &str {
        match self {
            Self::DocumentRead => "document:read",
            Self::DocumentWrite => "document:write",
            Self::UserManage => "user:manage",
        }
    }

    fn domain(&self) -> &str {
        match self {
            Self::DocumentRead | Self::DocumentWrite => "document",
            Self::UserManage => "user",
        }
    }
}

async fn setup() {
    // Create permission registry
    let perm_registry = StaticPermissionRegistry::from_set(
        [MyPermission::DocumentRead, MyPermission::DocumentWrite,
         MyPermission::UserManage].into()
    );

    // Define roles
    let mut role_registry = StaticRoleRegistry::new();
    role_registry.register(SimpleRole::new("admin", [
        MyPermission::DocumentRead, MyPermission::DocumentWrite,
        MyPermission::UserManage,
    ].into()));
    role_registry.register(SimpleRole::new("viewer", [
        MyPermission::DocumentRead,
    ].into()));

    // Build engine
    let engine = RbacEngine::new(
        Arc::new(role_registry),
        Arc::new(perm_registry),
        Arc::new(InMemoryAssignmentStore::new()),
    );

    // Assign roles and check permissions
    let alice = StringSubject::new("alice");
    engine.assign_role(&alice, "admin").await.unwrap();
    assert!(engine.check(&alice, &MyPermission::DocumentWrite).await);
}

Or use the built-in AuthService for a complete setup:

use kirino::service::login::{AuthService, build_default_engine};

let engine = Arc::new(build_default_engine());
let service = AuthService::new(engine);

// First user gets admin role automatically
service.register("admin", "password123").await.unwrap();
let token = service.login("admin", "password123").await.unwrap();

Documentation

Multilingual documentation is available:

Language Index
English docs/en/guides/index.md
็ฎ€ไฝ“ไธญๆ–‡ (Simplified Chinese) docs/zhs/guides/index.md
็น้ซ”ไธญๆ–‡ (Traditional Chinese) docs/zht/guides/index.md
ๆ—ฅๆœฌ่ชž (Japanese) docs/ja/guides/index.md
ํ•œ๊ตญ์–ด (Korean) docs/ko/guides/index.md
ะ ัƒััะบะธะน (Russian) docs/ru/guides/index.md
Espaรฑol (Spanish) docs/es/guides/index.md
Franรงais (French) docs/fr/guides/index.md

Crate-level API documentation is available at docs.rs/kirino.

Architecture

Kirino is a layered authentication and authorization framework:

graph TD
    subgraph SERVICE["Service Layer"]
        AUTH["AuthService<br/>register / login / verify"]
        SESSION["SessionManager<br/>create / activate / destroy"]
    end

    subgraph AUTHN["Authentication Layer"]
        IDENTITY["Identity<br/>Anonymous / Basic / Temporary / Service"]
        CREDENTIAL["Credential<br/>OneTime / JWT / ServiceToken"]
        PASSPORT["Passport<br/>StaticPassword / KeyPair / OAuth / DynamicPassword / Captcha / Biometric"]
    end

    subgraph AUTHZ["Authorization Layer (RBAC)"]
        ENGINE["RbacEngine<br/>check / check_batch / check_hierarchical"]
        STORE["AssignmentStore / RoleStore"]
        CONSTRAINTS["ConstraintValidator<br/>SSD / DSD / Cardinality / Prerequisite"]
        CACHE["PermissionCache<br/>TTL-based LRU"]
        AUDIT["AuditLogger"]
    end

    subgraph DB["Database Layer"]
        MEMORY["InMemory Stores<br/>(zero-dependency ref impl)"]
        SQL["SQL Backend<br/>(feature: rbac-sql)"]
        REDIS["Redis Cache<br/>(feature: rbac-redis)"]
    end

    IDENTITY --> CREDENTIAL --> PASSPORT --> AUTH --> SESSION
    SESSION --> ENGINE
    ENGINE --> STORE
    ENGINE --> CONSTRAINTS
    ENGINE --> CACHE
    ENGINE --> AUDIT
    STORE --> MEMORY
    STORE --> SQL
    CACHE --> REDIS

Core Concepts

Authentication Pipeline

Kirino authenticates users through a three-step pipeline:

flowchart LR
    I["Identity<br/>Who are you?"]
    C["Credential<br/>Prove it"]
    P["Passport<br/>Challenge accepted"]

    I --> C --> P

RBAC Layers

Implements all three levels of the ANSI INCITS 359-2004 RBAC standard:

graph TD
    subgraph RBAC0["RBAC0 โ€” Base"]
        B0["Subject โ†” Role โ†” Permission"]
    end
    subgraph RBAC1["RBAC1 โ€” Hierarchy"]
        B1["Role inheritance with cycle detection"]
    end
    subgraph RBAC2["RBAC2 โ€” Constraints"]
        B2["SSD / DSD / Cardinality / Prerequisite / Temporal"]
    end
    RBAC0 --> RBAC1 --> RBAC2

Decision Flow

flowchart TD
    START(["check(subject, permission)"]) --> CACHE{"Cache hit?"}
    CACHE -->|yes| RETURN_CACHED(["Return cached result"])
    CACHE -->|no| DENIED{"In denied_permissions?"}
    DENIED -->|yes| RETURN_DENY(["DENY โ€” persist to cache"])
    DENIED -->|no| EXTRA{"In extra_permissions?"}
    EXTRA -->|yes| RETURN_ALLOW(["ALLOW โ€” persist to cache"])
    EXTRA -->|no| ROLES["Resolve assigned roles"]
    ROLES --> HIER["Expand role hierarchy"]
    HIER --> CHECK["Permission โˆˆ role permissions?"]
    CHECK -->|yes| RETURN_ALLOW2(["ALLOW โ€” persist to cache"])
    CHECK -->|no| RETURN_DENY2(["DENY โ€” persist to cache"])

Deny-override semantics: Denied permissions always take precedence over granted ones โ€” even over role-based or extra permissions.

Identity Types

Identity Description
Anonymous Unauthenticated visitor, minimal permissions
Basic Standard user, starts with minimal permissions
Temporary Time-limited account, auto-expires
Service Service account for permission delegation

Built-in Roles (Default Engine)

Role Permissions
admin All permissions (13 across 6 domains)
operator agent:, config:read, knowledge:, container:read, system:read
viewer agent:read, config:read, knowledge:read, container:read, system:read
agent agent:execute, agent:read

Feature Flags

[features]
default = []                    # RBAC core + in-memory backends
rbac-core = []                  # Traits and engine only
rbac-inmemory = ["rbac-core"]   # In-memory assignment/role stores
rbac-hierarchy = ["rbac-core"]  # RBAC1 hierarchical role inheritance
rbac-constraints = ["rbac-core"]# RBAC2 constraint models (SSD/DSD)
rbac-sql = ["rbac-core"]        # SQL-based persistent stores
rbac-sea-orm = ["rbac-core"]    # SeaORM entity models
rbac-redis = ["rbac-core"]      # Redis-based permission cache
rbac-full = [                   # All features enabled
    "rbac-inmemory", "rbac-hierarchy", "rbac-constraints",
    "rbac-sql", "rbac-sea-orm", "rbac-redis"
]

Design Philosophy

Kirino is designed to be a pure library consumed by downstream projects:

  • โœ… Provides generic trait-based abstractions for RBAC
  • โœ… Implements ANSI INCITS 359-2004 standard (RBAC0/1/2)
  • โœ… Zero-dependency in-memory reference implementations
  • โœ… Domain-agnostic: define your own Subject and Permission types
  • โœ… Deny-override semantics for security-first access control
  • โœ… Cache-aware permission checks with TTL support

It does not prescribe:

  • โŒ Specific permission or role types (you define your own)
  • โŒ Authentication UI or middleware (library-level only)
  • โŒ Database schema (trait-based โ€” bring your own backend)
  • โŒ Network protocols (expose via your own API layer)

Requirements

  • Rust 1.75+ (edition 2021)
  • Tokio async runtime
  • Optional: PostgreSQL (for rbac-sql), Redis (for rbac-redis)

License

Apache 2.0