#authorization #zero-trust #anomaly-detection #rbac

kirino

Zero-trust authentication and authorization framework with RBAC and dynamic risk assessment

7 releases (4 breaking)

new 0.6.3 Aug 4, 2026
0.6.2 Aug 3, 2026
0.6.0 Jul 21, 2026
0.4.0 Jun 8, 2026
0.1.0 May 5, 2026

#1595 in Authentication

Download history 105/week @ 2026-05-17 13/week @ 2026-05-31 61/week @ 2026-07-19 108/week @ 2026-07-26 241/week @ 2026-08-02

411 downloads per month

Custom license

560KB
14K SLoC

kirino

Kirino

Zero-trust authentication and authorization framework

CI Status Crates.io Version [![License: SySL](https://img.shields.io/badge/license-SySL%201.0-blue)](https://sysl.celestia.world)

A fully generic, trait-based authentication and authorization framework for Rust. Provides identity types, credential management, passport challenges, a complete RBAC system (RBAC0/1/2) implementing the ANSI INCITS 359-2004 standard, and a dynamic authorization layer with trust scoring, anomaly detection, and DO-178C inspired autonomy levels (L0–L4).

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: Three-layer composable audit (sink + policy engine + analyzer)
  • 🧠 Dynamic Authorization: Runtime risk scoring with trust decay, anomaly detection, and domain scoping
  • 🎛️ Autonomy Levels: DO-178C inspired L0–L4 autonomy levels with configurable strategies
  • 🔍 Anomaly Detection: Sliding-window z-score pattern deviation with adaptive baselines
  • 📉 Trust Decay: Configurable exponential trust decay with background worker
  • 🧩 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.5"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }

Define your permissions and roles:

use kirino::rbac::prelude::*;

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

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

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

fn setup() {
    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()));

    let perm_registry = StaticPermissionRegistry::new([
        MyPermission::DocumentRead, MyPermission::DocumentWrite,
        MyPermission::UserManage,
    ].into());

    // Pass plain values — the engine wraps them internally via Shared<Arc>
    let engine = RbacEngine::new(role_registry, perm_registry, InMemoryAssignmentStore::<String, MyPermission>::new());
}

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

use kirino::service::login::{AuthService, build_default_engine};
use kirino::database::memory::InMemoryUserDatabase;

let db = InMemoryUserDatabase::new();
let engine = build_default_engine();
let service = AuthService::new(db, "jwt-secret", 24, engine, "admin", "viewer");

Documentation

Multilingual documentation is available:

Language Index
English docs/en/guides/index.md
简体中文 (Simplified Chinese) docs/zh-Hans/guides/index.md
繁體中文 (Traditional Chinese) docs/zh-Hant/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<br/>Sink + PolicyEngine + Analyzer"]
    end

    subgraph DYN["Dynamic Authorization"]
        ARBITER["AuthorizationArbiter<br/>authorize / risk_score / feedback"]
        TRUST["TrustScore + TrustDecayWorker"]
        ANOMALY["AnomalyDetector<br/>Sliding window + z-score"]
        POLICY["DynamicPolicy<br/>5-dim risk + autonomy L0-L4"]
        DOMAIN["TaskDomain + DomainScope"]
    end

    subgraph DB["Database Layer"]
        MEMORY["InMemory Stores<br/>(zero-dependency ref impl)"]
        DYNAMIC["Dynamic Auth<br/>(feature: rbac-dynamic)"]
        CACHE["Permission Cache<br/>(TTL-based)"]
    end

    IDENTITY --> CREDENTIAL --> PASSPORT --> AUTH --> SESSION
    SESSION --> ENGINE
    ENGINE --> STORE
    ENGINE --> CONSTRAINTS
    ENGINE --> CACHE
    ENGINE --> AUDIT
    ENGINE --> ARBITER
    ARBITER --> TRUST
    ARBITER --> ANOMALY
    ARBITER --> POLICY
    ARBITER --> DOMAIN
    ARBITER --> 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.

Dynamic Authorization

On top of static RBAC, kirino provides a runtime risk-scoring layer inspired by NIST SP 800-207/162 and DO-178C:

flowchart TD
    REQ["ActionRequest<br/>(delegator + category + domain)"]
    REQ --> RISK["Compute 5-dimension risk score"]
    RISK --> D1["Trust (30%)"]
    RISK --> D2["Sensitivity (25%)"]
    RISK --> D3["Domain Scope (25%)"]
    RISK --> D4["Anomaly (10%)"]
    RISK --> D5["Delegator Type (10%)"]
    D1 & D2 & D3 & D4 & D5 --> MAP["Map risk → Autonomy Level"]
    MAP --> L0["L0: Lockdown (reject all)"]
    MAP --> L1["L1: Human approval required"]
    MAP --> L2["L2: Escalate + audit"]
    MAP --> L3["L3: Proceed with audit"]
    MAP --> L4["L4: Autonomous"]

Trust scores decay exponentially over time. Anomaly detection uses sliding-window z-score analysis. The arbiter supports lockdown/restore and compliance/violation feedback loops.

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-inmemory", "auth-password", "auth-jwt"]
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-dynamic = ["rbac-core"]       # Dynamic risk-based authorization
rbac-full = [                      # All features enabled
    "rbac-inmemory", "rbac-hierarchy", "rbac-constraints",
    "rbac-dynamic", "auth-password", "auth-jwt"
]
auth-password = ["dep:argon2"]     # Argon2 password hashing
auth-jwt = ["dep:jsonwebtoken"]    # JWT token issuance/verification

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

License

Licensed under the Synthetic Source License (SySL), Version 1.0.

Dependencies

~10–30MB
~329K SLoC