Multi-cloud Identity and Access Management Library for Rust
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)
- Getting Started Guide - Step-by-step tutorial for your first WAMI app
- Workspace Structure - Understanding the modular crate architecture
- Examples - 24 working examples demonstrating all major features
- Architecture - Design principles, components, and data flow
- API Reference - Detailed API documentation for all modules
- IAM Guide - Users, groups, roles, and policies
- STS Guide - Temporary credentials and sessions
- SSO Admin Guide - Permission sets and account assignments
- Multi-tenant Guide - Tenant isolation and hierarchy
- Store Implementation - Create custom storage backends
- Multi-cloud Providers - AWS, GCP, Azure provider details
- Permission Checking - Policy evaluation and authorization
- ARN Specification - Complete ARN format documentation and usage guide
- ARN Architecture - Resource naming across providers with multi-tenant and multi-cloud support
- Changelog - Version history and release notes
- Multi-cloud Status - Provider implementation status
- Security - Security policies and vulnerability reporting
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.
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.
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_wamiSee examples/README.md for complete documentation.
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.
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?;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?;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());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?;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
Run the full test suite:
cargo testWAMI 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
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Add tests for your changes
- Ensure all tests pass (
cargo test) - Run
cargo clippyandcargo fmt - Submit a pull request
See Contributing Guide for more details.
- Policy Condition Keys - 140+ condition keys and 91 operators for fine-grained access control (Summary)
- 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.
This project is licensed under the MIT License - see the LICENSE file for details.
Found a security issue? Please see Security Policy for reporting guidelines.
- Documentation - Complete documentation index
- Crates.io - Published crate
- Docs.rs - API documentation
- GitHub - Source code
- Issues - Bug reports and feature requests
Multi-cloud IAM made simple