Skip to content

Lsh0x/wami

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

WAMI - Who Am I

Multi-cloud Identity and Access Management Library for Rust

GitHub last commit CI Codecov Docs Crates.io

Overview

WAMI (Who Am I) is a pure Rust library for Identity and Access Management (IAM), Security Token Service (STS), and Single Sign-On (SSO) operations across multiple cloud providers. Built with a domain-driven design, WAMI separates business logic from storage, making it flexible, testable, and cloud-agnostic.

Key Features:

  • 🌐 Multi-cloud Support - AWS, GCP, Azure, and custom identity providers
  • πŸ—οΈ Pure Domain Logic - Business logic without storage dependencies
  • πŸ’Ύ Pluggable Storage - In-memory, SQL, NoSQL, or custom backends
  • 🏒 Multi-tenant Architecture - Built-in hierarchical tenant isolation with opaque numeric IDs
  • πŸ” Complete IAM Suite - Users, groups, roles, policies, credentials
  • πŸ”‘ Temporary Credentials - STS sessions and role assumption
  • πŸ“Š SSO Administration - Permission sets, assignments, and federation
  • 🏷️ ARN System - Unified resource naming with multi-tenant and multi-cloud support
  • πŸ”’ Opaque Tenant IDs - Numeric tenant IDs (u64) for security and scalability
  • πŸ¦€ 100% Rust - Type-safe, async-first, zero-cost abstractions
  • βœ… Well-tested - 539 unit tests with 89.43% code coverage (all passing)

πŸ“š Documentation

Getting Started

Core Concepts

Feature Guides

Advanced Topics

Project Information


Quick Start

Installation

Add this to your Cargo.toml:

[dependencies]
wami = "0.11.0"
tokio = { version = "1.0", features = ["full"] }

Note: WAMI is organized as a workspace of crates for better modularity. The main wami crate re-exports everything, so you can use it exactly as before. For details, see Workspace Structure.

Your First Example

use wami::arn::{TenantPath, WamiArn};
use wami::context::WamiContext;
use wami::store::memory::InMemoryStore;
use wami::store::traits::UserStore;
use wami::wami::identity::user::builder::build_user;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize storage
    let mut store = InMemoryStore::default();
    
    // Create WAMI context with ARN (using numeric tenant IDs)
    let context = WamiContext::builder()
        .instance_id("123456789012")
        .tenant_path(TenantPath::single(0)) // Root tenant uses ID 0
        .caller_arn(
            WamiArn::builder()
                .service(wami::arn::Service::Iam)
                .tenant_path(TenantPath::single(0))
                .wami_instance("123456789012")
                .resource("user", "admin")
                .build()?,
        )
        .is_root(false)
        .build()?;
    
    // Build a user (pure function with ARN support)
    let user = build_user(
        "alice".to_string(),
        Some("/engineering/".to_string()),
        &context,
    )?;
    
    // Store it
    let created = store.create_user(user).await?;
    println!("βœ… Created user: {}", created.user_name);
    println!("βœ… WAMI ARN: {}", created.wami_arn);
    
    // Retrieve it
    let retrieved = store.get_user("alice").await?;
    println!("βœ… Retrieved: {:?}", retrieved.unwrap().user_name);
    
    Ok(())
}

Output:

βœ… Created user: alice
βœ… WAMI ARN: arn:wami:iam:0:wami:123456789012:user/...
βœ… Retrieved: "alice"

See Getting Started Guide for more examples.

🎯 Example Programs

WAMI includes 24 runnable examples demonstrating all major features:

Category Examples Status
Getting Started 01-03: Hello World, CRUD, Service Layer βœ… All Working
Multi-Tenancy 04-08: Tenants, Hierarchy, Quotas, Cross-Tenant Access, Migration βœ… All Working
Multi-Cloud 09-13: User Sync, Provider Switching, Hybrid Cloud, DR βœ… All Working
Policies & RBAC 14-17, 23: Policy Basics, Evaluation, RBAC, ABAC, Boundaries βœ… All Working
STS & Federation 18-20: Session Tokens, Role Assumption, Federation βœ… All Working
SSO & Federation 21-22: SSO Setup, Identity Providers βœ… All Working
ARN System 25: ARN Usage (Building, Parsing, Transforming) βœ… All Working

Run any example with:

cargo run --example 01_hello_wami

See examples/README.md for complete documentation.


Architecture Overview

WAMI follows a clean 3-layer architecture:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚         Application Layer (Your Code)           β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Domain Layer    β”‚  Pure Functions            β”‚
β”‚                    β”‚  (wami::*)                 β”‚
β”‚  β€’ Identity        β”‚  No storage dependencies   β”‚
β”‚  β€’ Credentials     β”‚  Pure business logic       β”‚
β”‚  β€’ Policies        β”‚  Builders & validators     β”‚
β”‚  β€’ STS Sessions    β”‚                            β”‚
β”‚  β€’ Tenants         β”‚                            β”‚
β”‚  β€’ ARN System      β”‚                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                     β”‚
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚    Storage Layer   β”‚  Traits & Implementations  β”‚
β”‚  WamiStore         β”‚  In-memory, SQL, custom    β”‚
β”‚  StsStore          β”‚  Pluggable backends        β”‚
β”‚  TenantStore       β”‚                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Key Benefits:

  • βœ… Separation of Concerns - Domain logic independent from storage
  • βœ… Testability - Pure functions are easy to test
  • βœ… Flexibility - Use any storage backend (memory, SQL, NoSQL)
  • βœ… Type Safety - Rust's type system prevents common errors

Read more in Architecture Guide.


Core Features

πŸ” Identity Management

use wami::arn::{TenantPath, WamiArn};
use wami::context::WamiContext;
use wami::wami::identity::{user, group, role};

// Create WAMI context
let context = WamiContext::builder()
    .instance_id("123456789012")
    .tenant_path(TenantPath::single(0)) // Root tenant uses ID 0
    .caller_arn(
        WamiArn::builder()
            .service(wami::arn::Service::Iam)
            .tenant_path(TenantPath::single(0))
            .wami_instance("123456789012")
            .resource("user", "admin")
            .build()?,
    )
    .is_root(false)
    .build()?;

// Create user
let user = user::builder::build_user("alice".into(), None, &context)?;
store.create_user(user).await?;

// Create group and add user
let group = group::builder::build_group("admins".into(), None, &context)?;
store.create_group(group).await?;
store.add_user_to_group("admins", "alice").await?;

// Create role with trust policy
let trust_policy = r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}"#;
let role = role::builder::build_role(
    "AdminRole".into(),
    trust_policy.to_string(),
    None,
    None,
    None,
    &context,
)?;
store.create_role(role).await?;

πŸ”‘ Credentials & STS

use wami::arn::{TenantPath, WamiArn};
use wami::context::WamiContext;
use wami::wami::credentials::access_key::builder::build_access_key;
use wami::service::{SessionTokenService, AssumeRoleService};
use wami::wami::sts::session_token::requests::GetSessionTokenRequest;

// Create WAMI context (using numeric tenant IDs)
let context = WamiContext::builder()
    .instance_id("123456789012")
    .tenant_path(TenantPath::single(0)) // Root tenant uses ID 0
    .caller_arn(
        WamiArn::builder()
            .service(wami::arn::Service::Iam)
            .tenant_path(TenantPath::single(0))
            .wami_instance("123456789012")
            .resource("user", "alice")
            .build()?,
    )
    .is_root(false)
    .build()?;

// Create access keys (uses context)
let key = build_access_key("alice".to_string(), &context)?;
store.create_access_key(key).await?;

// Create temporary session (via service layer)
let sts_service = SessionTokenService::new(store.clone());
let token_req = GetSessionTokenRequest {
    duration_seconds: Some(3600),
    serial_number: None,
    token_code: None,
};
let session = sts_service
    .get_session_token(&context, token_req, &user_arn)
    .await?;

🏷️ ARN System

use wami::arn::{WamiArn, Service, TenantPath};

// Build a WAMI native ARN (using numeric tenant IDs)
let arn = WamiArn::builder()
    .service(Service::Iam)
    .tenant_hierarchy(vec![12345678, 87654321, 99999999]) // Opaque numeric IDs
    .wami_instance("999888777")
    .resource("user", "77557755")
    .build()?;

println!("{}", arn);
// Output: arn:wami:iam:12345678/87654321/99999999:wami:999888777:user/77557755

// Build a cloud-synced ARN
let cloud_arn = WamiArn::builder()
    .service(Service::Iam)
    .tenant(12345678) // Numeric tenant ID
    .wami_instance("999888777")
    .cloud_provider("aws", "223344556677")
    .resource("user", "77557755")
    .build()?;

println!("{}", cloud_arn);
// Output: arn:wami:iam:12345678:wami:999888777:aws:223344556677:global:user/77557755

// Parse an ARN
let parsed = WamiArn::from_str("arn:wami:iam:12345678:wami:999888777:user/77557755")?;
println!("Resource type: {}", parsed.resource_type());

🏒 Multi-tenant Support

use wami::wami::tenant::{Tenant, TenantId};

// Create parent tenant (service generates unique numeric ID)
let parent = tenant_service
    .create_tenant(
        &context,
        "acme-corp".to_string(),
        Some("ACME Corp".to_string()),
        None, // No parent, this is a root tenant
    )
    .await?;
let parent_id = parent.id.clone();

// Create child tenant
let child = tenant_service
    .create_tenant(
        &context,
        "engineering".to_string(),
        Some("Engineering Dept".to_string()),
        Some(parent_id.clone()),
    )
    .await?;
let child_id = child.id.clone();

// Query hierarchy
let descendants = store.get_descendants(&parent_id).await?;

Project Structure

wami/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ wami/              # Domain layer (pure functions)
β”‚   β”‚   β”œβ”€β”€ identity/      # Users, groups, roles
β”‚   β”‚   β”œβ”€β”€ credentials/   # Access keys, MFA, certificates
β”‚   β”‚   β”œβ”€β”€ policies/      # IAM policies
β”‚   β”‚   β”œβ”€β”€ sts/          # Sessions, temporary credentials
β”‚   β”‚   β”œβ”€β”€ sso_admin/    # SSO configuration
β”‚   β”‚   └── tenant/       # Multi-tenant models
β”‚   β”‚
β”‚   β”œβ”€β”€ arn/              # ARN system (WAMI resource naming)
β”‚   β”‚   β”œβ”€β”€ types.rs      # Core ARN types
β”‚   β”‚   β”œβ”€β”€ builder.rs     # Fluent ARN builder
β”‚   β”‚   β”œβ”€β”€ parser.rs      # ARN parsing
β”‚   β”‚   └── transformer.rs # Provider-specific transformations
β”‚   β”‚
β”‚   β”œβ”€β”€ store/            # Storage layer
β”‚   β”‚   β”œβ”€β”€ traits/       # Storage trait definitions
β”‚   β”‚   └── memory/       # In-memory implementations
β”‚   β”‚
β”‚   β”œβ”€β”€ provider/         # Cloud provider abstractions
β”‚   β”‚   β”œβ”€β”€ aws.rs
β”‚   β”‚   β”œβ”€β”€ gcp.rs
β”‚   β”‚   └── azure.rs
β”‚   β”‚
β”‚   └── error.rs          # Error types
β”‚
β”œβ”€β”€ docs/                 # πŸ“š All documentation
β”œβ”€β”€ examples/             # Working code examples
└── tests/                # Integration tests

Testing

Run the full test suite:

cargo test

WAMI has 539 tests (all passing βœ…) covering:

  • βœ… Domain logic (pure functions)
  • βœ… Store implementations (CRUD, queries, concurrency)
  • βœ… Multi-tenant isolation
  • βœ… Resource enumeration and downcasting
  • βœ… ARN building, parsing, and transformation

Contributing

Contributions are welcome! Please:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Add tests for your changes
  4. Ensure all tests pass (cargo test)
  5. Run cargo clippy and cargo fmt
  6. Submit a pull request

See Contributing Guide for more details.


Roadmap

In Planning

Future Enhancements

  • SQL store implementations (PostgreSQL, MySQL)
  • Advanced policy evaluation engine
  • Identity Provider Support - SAML and OIDC federation (βœ… Completed in v0.8.0)
  • ARN System - Unified resource naming with multi-tenant and multi-cloud support (βœ… Completed in v0.11.0)
  • Opaque Numeric Tenant IDs - Secure tenant identification with u64-based IDs (βœ… Completed in v0.11.0)
  • Audit logging and compliance
  • Service/orchestration layer

See Issues Tracker for details.


License

This project is licensed under the MIT License - see the LICENSE file for details.


Security

Found a security issue? Please see Security Policy for reporting guidelines.


Links


Built with ❀️ in Rust
Multi-cloud IAM made simple

About

IAM capabilities

Resources

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages