pub struct ArnBuilder { /* private fields */ }Expand description
A fluent builder for constructing WAMI ARNs.
§Examples
§Building a WAMI-native ARN
use wami_core::arn::{WamiArn, Service};
let arn = WamiArn::builder()
.service(Service::Iam)
.tenant_hierarchy(vec![12345678, 87654321, 99999999])
.wami_instance("999888777")
.resource("user", "77557755")
.build()
.unwrap();
assert_eq!(
arn.to_string(),
"arn:wami:iam:12345678/87654321/99999999:wami:999888777:user/77557755"
);§Building a cloud-synced ARN
use wami_core::arn::{WamiArn, Service};
let arn = WamiArn::builder()
.service(Service::Iam)
.tenant_hierarchy(vec![12345678, 87654321, 99999999])
.wami_instance("999888777")
.cloud_provider("aws", "223344556677")
.resource("user", "77557755")
.build()
.unwrap();
assert_eq!(
arn.to_string(),
"arn:wami:iam:12345678/87654321/99999999:wami:999888777:aws:223344556677:global:user/77557755"
);Implementations§
Source§impl ArnBuilder
impl ArnBuilder
Sourcepub fn new() -> ArnBuilder
pub fn new() -> ArnBuilder
Creates a new ARN builder.
Sourcepub fn service(self, service: Service) -> ArnBuilder
pub fn service(self, service: Service) -> ArnBuilder
Sets the service.
§Examples
use wami_core::arn::{WamiArn, Service};
let builder = WamiArn::builder().service(Service::Iam);Examples found in repository?
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Session Tokens ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create user
43 let user_service = UserService::new(store.clone());
44 let alice_req = CreateUserRequest {
45 user_name: "alice".to_string(),
46 path: Some("/".to_string()),
47 permissions_boundary: None,
48 tags: None,
49 };
50 let alice = user_service.create_user(&context, alice_req).await?;
51 println!("Step 1: Created user alice");
52 println!(" ARN: {}\n", alice.arn);
53
54 // Generate session token
55 let sts_service = SessionTokenService::new(store.clone());
56
57 let token_req = GetSessionTokenRequest {
58 duration_seconds: Some(3600),
59 serial_number: None,
60 token_code: None,
61 };
62
63 let response = sts_service
64 .get_session_token(&context, token_req, &alice.arn)
65 .await?;
66
67 println!("Step 2: Generated session token");
68 println!(" Access Key: {}", response.credentials.access_key_id);
69 println!(
70 " Secret Key: {}...",
71 &response.credentials.secret_access_key[..20]
72 );
73 println!(
74 " Session Token: {}...",
75 &response.credentials.session_token[..30]
76 );
77 println!(" Expiration: {}", response.credentials.expiration);
78
79 println!("\n✅ Example completed successfully!");
80 println!("Key takeaways:");
81 println!("- Session tokens provide temporary credentials");
82 println!("- Credentials expire after specified duration");
83 println!("- Useful for temporary or delegated access");
84
85 Ok(())
86}More examples
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Federated Access ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create admin user who will generate federation tokens
43 let user_service = UserService::new(store.clone());
44 let admin = user_service
45 .create_user(
46 &context,
47 CreateUserRequest {
48 user_name: "admin".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 },
53 )
54 .await?;
55
56 let fed_service = FederationService::new(store.clone());
57
58 println!("Step 1: Generating federation token for external user...\n");
59
60 let fed_req = GetFederationTokenRequest {
61 name: "partner-user".to_string(),
62 duration_seconds: Some(3600),
63 policy: Some(r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"*"}]}"#.to_string()),
64 };
65
66 let response = fed_service
67 .get_federation_token(&context, fed_req, &admin.arn)
68 .await?;
69
70 println!("✓ Generated federation token:");
71 println!(" Federated User ARN: {}", response.federated_user.arn);
72 println!(" Access Key: {}", response.credentials.access_key_id);
73 println!(" Expiration: {}", response.credentials.expiration);
74
75 println!("\n✅ Example completed successfully!");
76 println!("Key takeaways:");
77 println!("- Federation enables external user access");
78 println!("- Temporary credentials with limited permissions");
79 println!("- Useful for partner integrations");
80
81 Ok(())
82}19async fn main() -> Result<(), Box<dyn std::error::Error>> {
20 println!("=== Hello WAMI ===\n");
21
22 // Step 1: Initialize the store
23 println!("Step 1: Initializing in-memory store...");
24 let mut store = InMemoryWamiStore::default();
25 println!("✓ Store initialized");
26
27 // Step 2: Create a WamiContext for operations
28 println!("\nStep 2: Creating WAMI context...");
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0)) // Root tenant ID is 0
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42 println!("✓ Context created");
43
44 // Step 3: Build a user using pure functions
45 println!("\nStep 3: Building user 'alice'...");
46 let user = build_user("alice".to_string(), Some("/".to_string()), &context)?;
47 println!("✓ User built with ARN: {}", user.wami_arn);
48
49 // Step 4: Store the user
50 println!("\nStep 4: Storing user in the store...");
51 let created_user = store.create_user(user).await?;
52 println!("✓ User stored successfully");
53 println!(" - Name: {}", created_user.user_name);
54 println!(" - User ID: {}", created_user.user_id);
55 println!(" - ARN: {}", created_user.wami_arn);
56
57 // Step 5: Retrieve the user
58 println!("\nStep 5: Retrieving user from store...");
59 let retrieved = store.get_user("alice").await?;
60 match retrieved {
61 Some(user) => {
62 println!("✓ User retrieved successfully");
63 println!(" - Name: {}", user.user_name);
64 println!(" - Path: {}", user.path);
65 }
66 None => println!("✗ User not found"),
67 }
68
69 println!("\n✅ Example completed successfully!");
70 println!("Key takeaways:");
71 println!("- InMemoryWamiStore provides a simple storage backend");
72 println!("- Providers (AWS, GCP, Azure) handle platform-specific details");
73 println!("- Pure functions create domain objects without side effects");
74
75 Ok(())
76}22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Policy Evaluation Simulation ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 let eval_service = EvaluationService::new(store.clone(), "123456789012".to_string());
43 let user_service = UserService::new(store.clone());
44
45 // Create user
46 println!("Step 1: Creating user...\n");
47 let req = CreateUserRequest {
48 user_name: "alice".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 };
53 let alice = user_service.create_user(&context, req).await?;
54 println!("✓ Created alice: {}", alice.arn);
55
56 // === SIMULATE POLICY ===
57 println!("\n\nStep 2: Simulating custom policy...\n");
58
59 let policy_doc = r#"{
60 "Version": "2012-10-17",
61 "Statement": [{
62 "Effect": "Allow",
63 "Action": ["s3:GetObject", "s3:PutObject"],
64 "Resource": "arn:aws:s3:::my-bucket/*"
65 }]
66}"#;
67
68 // Test allowed action
69 let sim_req = SimulateCustomPolicyRequest {
70 policy_input_list: vec![policy_doc.to_string()],
71 action_names: vec!["s3:GetObject".to_string()],
72 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
73 context_entries: None,
74 };
75
76 let result = eval_service.simulate_custom_policy(sim_req).await?;
77 println!("✓ Simulation: s3:GetObject on my-bucket/file.txt");
78 println!(" Decision: {}", result.evaluation_results[0].eval_decision);
79
80 // Test denied action
81 let denied_req = SimulateCustomPolicyRequest {
82 policy_input_list: vec![policy_doc.to_string()],
83 action_names: vec!["s3:DeleteObject".to_string()],
84 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
85 context_entries: None,
86 };
87
88 let denied_result = eval_service.simulate_custom_policy(denied_req).await?;
89 println!("\n✓ Simulation: s3:DeleteObject on my-bucket/file.txt");
90 println!(
91 " Decision: {}",
92 denied_result.evaluation_results[0].eval_decision
93 );
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- Policy simulation helps test before deployment");
98 println!("- Simulate custom policies or principal policies");
99 println!("- Understand allow/deny decisions");
100 println!("- Identify missing permissions");
101
102 Ok(())
103}23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24 println!("=== Role Assumption Workflow ===\n");
25
26 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
27
28 // Create context
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0))
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42
43 let user_service = UserService::new(store.clone());
44 let role_service = RoleService::new(store.clone());
45 let sts_service = AssumeRoleService::new(store.clone());
46
47 // Create user
48 println!("Step 1: Creating user...\n");
49 let alice = user_service
50 .create_user(
51 &context,
52 CreateUserRequest {
53 user_name: "alice".to_string(),
54 path: Some("/".to_string()),
55 permissions_boundary: None,
56 tags: None,
57 },
58 )
59 .await?;
60 println!("✓ Created alice: {}", alice.arn);
61
62 // Create elevated role
63 println!("\nStep 2: Creating admin role...\n");
64 let trust_policy = r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}"#;
65 let role = role_service
66 .create_role(
67 &context,
68 CreateRoleRequest {
69 role_name: "AdminRole".to_string(),
70 path: Some("/".to_string()),
71 assume_role_policy_document: trust_policy.to_string(),
72 description: Some("Admin role for elevated access".to_string()),
73 max_session_duration: Some(3600),
74 permissions_boundary: None,
75 tags: None,
76 },
77 )
78 .await?;
79 println!("✓ Created AdminRole: {}", role.arn);
80
81 // Assume role
82 println!("\nStep 3: Alice assuming AdminRole...\n");
83 let assume_req = AssumeRoleRequest {
84 role_arn: role.arn.clone(),
85 role_session_name: "alice-admin-session".to_string(),
86 duration_seconds: Some(3600),
87 external_id: None,
88 policy: None,
89 };
90
91 let response = sts_service
92 .assume_role(&context, assume_req, &alice.arn)
93 .await?;
94 println!("✓ Successfully assumed role!");
95 println!(" Assumed Role ARN: {}", response.assumed_role_user.arn);
96 println!(" Access Key: {}", response.credentials.access_key_id);
97 println!(" Expiration: {}", response.credentials.expiration);
98
99 println!("\n✅ Example completed successfully!");
100 println!("Key takeaways:");
101 println!("- AssumeRole provides temporary elevated permissions");
102 println!("- Trust policies control who can assume roles");
103 println!("- Session credentials expire automatically");
104
105 Ok(())
106}21async fn main() -> Result<(), Box<dyn std::error::Error>> {
22 println!("=== Multi-Cloud User Sync ===\n");
23
24 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
25
26 // Create context for operations
27 let context = WamiContext::builder()
28 .instance_id("123456789012")
29 .tenant_path(TenantPath::single(0))
30 .caller_arn(
31 WamiArn::builder()
32 .service(wami::arn::Service::Iam)
33 .tenant_path(TenantPath::single(0))
34 .wami_instance("123456789012")
35 .resource("user", "admin")
36 .build()?,
37 )
38 .is_root(false)
39 .build()?;
40
41 println!("✓ Using unified context for all operations");
42
43 // === CREATE USER ===
44 println!("\n\nStep 1: Creating alice user...\n");
45
46 let user_service = UserService::new(store.clone());
47
48 let user_req = CreateUserRequest {
49 user_name: "alice".to_string(),
50 path: Some("/cloud-sync/".to_string()),
51 permissions_boundary: None,
52 tags: Some(vec![
53 wami::types::Tag {
54 key: "Email".to_string(),
55 value: "alice@company.com".to_string(),
56 },
57 wami::types::Tag {
58 key: "MultiCloud".to_string(),
59 value: "true".to_string(),
60 },
61 ]),
62 };
63
64 let user = user_service.create_user(&context, user_req).await?;
65 println!("✓ Created alice:");
66 println!(" - ARN: {}", user.arn);
67 println!(" - User ID: {}", user.user_id);
68 println!(" - WAMI ARN: {}", user.wami_arn);
69
70 // === COMPARE ARN FORMATS ===
71 println!("\n\nStep 2: Understanding WAMI ARN format...\n");
72
73 println!("WAMI unified ARN:");
74 println!(" {}", user.wami_arn);
75 println!("\nThis ARN can be transformed to provider-specific formats:");
76 println!(" - AWS ARN format for AWS API calls");
77 println!(" - GCP resource name format for GCP API calls");
78 println!(" - Azure resource ID format for Azure API calls");
79
80 // === DEMONSTRATE PROVIDER METADATA ===
81 println!("\n\nStep 3: Understanding WAMI architecture...\n");
82
83 println!("WAMI provides:");
84 println!("- Unified WAMI ARN format (for internal operations)");
85 println!("- Provider-specific ARN transformation when needed");
86 println!("- Consistent resource identification across clouds");
87 println!("- Tags for categorization and metadata");
88
89 println!("\nBenefits:");
90 println!("- Unified identity management across clouds");
91 println!("- Provider-agnostic operations with context");
92 println!("- Cross-cloud audit trails with WAMI ARNs");
93 println!("- Multi-cloud resource tracking");
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- WAMI uses a unified ARN format internally");
98 println!("- Provider-specific ARNs can be generated when needed");
99 println!("- Context-based operations work across all providers");
100 println!("- Use tags to track cross-cloud relationships");
101
102 Ok(())
103}- examples/10_provider_switching.rs
- examples/17_attribute_based_access_control.rs
- examples/02_basic_crud_operations.rs
- examples/03_service_layer_intro.rs
- examples/05_tenant_hierarchy.rs
- examples/24_policy_attachment.rs
- examples/06_tenant_quotas_and_limits.rs
- examples/14_policy_basics.rs
- examples/11_hybrid_cloud_setup.rs
- examples/07_cross_tenant_role_assumption.rs
- examples/16_role_based_access_control.rs
- examples/12_provider_specific_features.rs
- examples/04_simple_multi_tenant.rs
- examples/08_tenant_migration.rs
- examples/13_disaster_recovery_multi_cloud.rs
- examples/23_permissions_boundaries.rs
- examples/22_identity_providers_federation.rs
Sourcepub fn service_str(self, service: impl Into<String>) -> ArnBuilder
pub fn service_str(self, service: impl Into<String>) -> ArnBuilder
Sets the service from a string.
§Examples
use wami_core::arn::WamiArn;
let builder = WamiArn::builder().service_str("iam");Sourcepub fn tenant_path(self, path: TenantPath) -> ArnBuilder
pub fn tenant_path(self, path: TenantPath) -> ArnBuilder
Sets the tenant path.
§Examples
use wami_core::arn::{WamiArn, TenantPath};
let path = TenantPath::new(vec![12345678, 87654321]);
let builder = WamiArn::builder().tenant_path(path);Examples found in repository?
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Session Tokens ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create user
43 let user_service = UserService::new(store.clone());
44 let alice_req = CreateUserRequest {
45 user_name: "alice".to_string(),
46 path: Some("/".to_string()),
47 permissions_boundary: None,
48 tags: None,
49 };
50 let alice = user_service.create_user(&context, alice_req).await?;
51 println!("Step 1: Created user alice");
52 println!(" ARN: {}\n", alice.arn);
53
54 // Generate session token
55 let sts_service = SessionTokenService::new(store.clone());
56
57 let token_req = GetSessionTokenRequest {
58 duration_seconds: Some(3600),
59 serial_number: None,
60 token_code: None,
61 };
62
63 let response = sts_service
64 .get_session_token(&context, token_req, &alice.arn)
65 .await?;
66
67 println!("Step 2: Generated session token");
68 println!(" Access Key: {}", response.credentials.access_key_id);
69 println!(
70 " Secret Key: {}...",
71 &response.credentials.secret_access_key[..20]
72 );
73 println!(
74 " Session Token: {}...",
75 &response.credentials.session_token[..30]
76 );
77 println!(" Expiration: {}", response.credentials.expiration);
78
79 println!("\n✅ Example completed successfully!");
80 println!("Key takeaways:");
81 println!("- Session tokens provide temporary credentials");
82 println!("- Credentials expire after specified duration");
83 println!("- Useful for temporary or delegated access");
84
85 Ok(())
86}More examples
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Federated Access ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create admin user who will generate federation tokens
43 let user_service = UserService::new(store.clone());
44 let admin = user_service
45 .create_user(
46 &context,
47 CreateUserRequest {
48 user_name: "admin".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 },
53 )
54 .await?;
55
56 let fed_service = FederationService::new(store.clone());
57
58 println!("Step 1: Generating federation token for external user...\n");
59
60 let fed_req = GetFederationTokenRequest {
61 name: "partner-user".to_string(),
62 duration_seconds: Some(3600),
63 policy: Some(r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"*"}]}"#.to_string()),
64 };
65
66 let response = fed_service
67 .get_federation_token(&context, fed_req, &admin.arn)
68 .await?;
69
70 println!("✓ Generated federation token:");
71 println!(" Federated User ARN: {}", response.federated_user.arn);
72 println!(" Access Key: {}", response.credentials.access_key_id);
73 println!(" Expiration: {}", response.credentials.expiration);
74
75 println!("\n✅ Example completed successfully!");
76 println!("Key takeaways:");
77 println!("- Federation enables external user access");
78 println!("- Temporary credentials with limited permissions");
79 println!("- Useful for partner integrations");
80
81 Ok(())
82}19async fn main() -> Result<(), Box<dyn std::error::Error>> {
20 println!("=== Hello WAMI ===\n");
21
22 // Step 1: Initialize the store
23 println!("Step 1: Initializing in-memory store...");
24 let mut store = InMemoryWamiStore::default();
25 println!("✓ Store initialized");
26
27 // Step 2: Create a WamiContext for operations
28 println!("\nStep 2: Creating WAMI context...");
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0)) // Root tenant ID is 0
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42 println!("✓ Context created");
43
44 // Step 3: Build a user using pure functions
45 println!("\nStep 3: Building user 'alice'...");
46 let user = build_user("alice".to_string(), Some("/".to_string()), &context)?;
47 println!("✓ User built with ARN: {}", user.wami_arn);
48
49 // Step 4: Store the user
50 println!("\nStep 4: Storing user in the store...");
51 let created_user = store.create_user(user).await?;
52 println!("✓ User stored successfully");
53 println!(" - Name: {}", created_user.user_name);
54 println!(" - User ID: {}", created_user.user_id);
55 println!(" - ARN: {}", created_user.wami_arn);
56
57 // Step 5: Retrieve the user
58 println!("\nStep 5: Retrieving user from store...");
59 let retrieved = store.get_user("alice").await?;
60 match retrieved {
61 Some(user) => {
62 println!("✓ User retrieved successfully");
63 println!(" - Name: {}", user.user_name);
64 println!(" - Path: {}", user.path);
65 }
66 None => println!("✗ User not found"),
67 }
68
69 println!("\n✅ Example completed successfully!");
70 println!("Key takeaways:");
71 println!("- InMemoryWamiStore provides a simple storage backend");
72 println!("- Providers (AWS, GCP, Azure) handle platform-specific details");
73 println!("- Pure functions create domain objects without side effects");
74
75 Ok(())
76}22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Policy Evaluation Simulation ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 let eval_service = EvaluationService::new(store.clone(), "123456789012".to_string());
43 let user_service = UserService::new(store.clone());
44
45 // Create user
46 println!("Step 1: Creating user...\n");
47 let req = CreateUserRequest {
48 user_name: "alice".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 };
53 let alice = user_service.create_user(&context, req).await?;
54 println!("✓ Created alice: {}", alice.arn);
55
56 // === SIMULATE POLICY ===
57 println!("\n\nStep 2: Simulating custom policy...\n");
58
59 let policy_doc = r#"{
60 "Version": "2012-10-17",
61 "Statement": [{
62 "Effect": "Allow",
63 "Action": ["s3:GetObject", "s3:PutObject"],
64 "Resource": "arn:aws:s3:::my-bucket/*"
65 }]
66}"#;
67
68 // Test allowed action
69 let sim_req = SimulateCustomPolicyRequest {
70 policy_input_list: vec![policy_doc.to_string()],
71 action_names: vec!["s3:GetObject".to_string()],
72 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
73 context_entries: None,
74 };
75
76 let result = eval_service.simulate_custom_policy(sim_req).await?;
77 println!("✓ Simulation: s3:GetObject on my-bucket/file.txt");
78 println!(" Decision: {}", result.evaluation_results[0].eval_decision);
79
80 // Test denied action
81 let denied_req = SimulateCustomPolicyRequest {
82 policy_input_list: vec![policy_doc.to_string()],
83 action_names: vec!["s3:DeleteObject".to_string()],
84 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
85 context_entries: None,
86 };
87
88 let denied_result = eval_service.simulate_custom_policy(denied_req).await?;
89 println!("\n✓ Simulation: s3:DeleteObject on my-bucket/file.txt");
90 println!(
91 " Decision: {}",
92 denied_result.evaluation_results[0].eval_decision
93 );
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- Policy simulation helps test before deployment");
98 println!("- Simulate custom policies or principal policies");
99 println!("- Understand allow/deny decisions");
100 println!("- Identify missing permissions");
101
102 Ok(())
103}23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24 println!("=== Role Assumption Workflow ===\n");
25
26 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
27
28 // Create context
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0))
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42
43 let user_service = UserService::new(store.clone());
44 let role_service = RoleService::new(store.clone());
45 let sts_service = AssumeRoleService::new(store.clone());
46
47 // Create user
48 println!("Step 1: Creating user...\n");
49 let alice = user_service
50 .create_user(
51 &context,
52 CreateUserRequest {
53 user_name: "alice".to_string(),
54 path: Some("/".to_string()),
55 permissions_boundary: None,
56 tags: None,
57 },
58 )
59 .await?;
60 println!("✓ Created alice: {}", alice.arn);
61
62 // Create elevated role
63 println!("\nStep 2: Creating admin role...\n");
64 let trust_policy = r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}"#;
65 let role = role_service
66 .create_role(
67 &context,
68 CreateRoleRequest {
69 role_name: "AdminRole".to_string(),
70 path: Some("/".to_string()),
71 assume_role_policy_document: trust_policy.to_string(),
72 description: Some("Admin role for elevated access".to_string()),
73 max_session_duration: Some(3600),
74 permissions_boundary: None,
75 tags: None,
76 },
77 )
78 .await?;
79 println!("✓ Created AdminRole: {}", role.arn);
80
81 // Assume role
82 println!("\nStep 3: Alice assuming AdminRole...\n");
83 let assume_req = AssumeRoleRequest {
84 role_arn: role.arn.clone(),
85 role_session_name: "alice-admin-session".to_string(),
86 duration_seconds: Some(3600),
87 external_id: None,
88 policy: None,
89 };
90
91 let response = sts_service
92 .assume_role(&context, assume_req, &alice.arn)
93 .await?;
94 println!("✓ Successfully assumed role!");
95 println!(" Assumed Role ARN: {}", response.assumed_role_user.arn);
96 println!(" Access Key: {}", response.credentials.access_key_id);
97 println!(" Expiration: {}", response.credentials.expiration);
98
99 println!("\n✅ Example completed successfully!");
100 println!("Key takeaways:");
101 println!("- AssumeRole provides temporary elevated permissions");
102 println!("- Trust policies control who can assume roles");
103 println!("- Session credentials expire automatically");
104
105 Ok(())
106}21async fn main() -> Result<(), Box<dyn std::error::Error>> {
22 println!("=== Multi-Cloud User Sync ===\n");
23
24 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
25
26 // Create context for operations
27 let context = WamiContext::builder()
28 .instance_id("123456789012")
29 .tenant_path(TenantPath::single(0))
30 .caller_arn(
31 WamiArn::builder()
32 .service(wami::arn::Service::Iam)
33 .tenant_path(TenantPath::single(0))
34 .wami_instance("123456789012")
35 .resource("user", "admin")
36 .build()?,
37 )
38 .is_root(false)
39 .build()?;
40
41 println!("✓ Using unified context for all operations");
42
43 // === CREATE USER ===
44 println!("\n\nStep 1: Creating alice user...\n");
45
46 let user_service = UserService::new(store.clone());
47
48 let user_req = CreateUserRequest {
49 user_name: "alice".to_string(),
50 path: Some("/cloud-sync/".to_string()),
51 permissions_boundary: None,
52 tags: Some(vec![
53 wami::types::Tag {
54 key: "Email".to_string(),
55 value: "alice@company.com".to_string(),
56 },
57 wami::types::Tag {
58 key: "MultiCloud".to_string(),
59 value: "true".to_string(),
60 },
61 ]),
62 };
63
64 let user = user_service.create_user(&context, user_req).await?;
65 println!("✓ Created alice:");
66 println!(" - ARN: {}", user.arn);
67 println!(" - User ID: {}", user.user_id);
68 println!(" - WAMI ARN: {}", user.wami_arn);
69
70 // === COMPARE ARN FORMATS ===
71 println!("\n\nStep 2: Understanding WAMI ARN format...\n");
72
73 println!("WAMI unified ARN:");
74 println!(" {}", user.wami_arn);
75 println!("\nThis ARN can be transformed to provider-specific formats:");
76 println!(" - AWS ARN format for AWS API calls");
77 println!(" - GCP resource name format for GCP API calls");
78 println!(" - Azure resource ID format for Azure API calls");
79
80 // === DEMONSTRATE PROVIDER METADATA ===
81 println!("\n\nStep 3: Understanding WAMI architecture...\n");
82
83 println!("WAMI provides:");
84 println!("- Unified WAMI ARN format (for internal operations)");
85 println!("- Provider-specific ARN transformation when needed");
86 println!("- Consistent resource identification across clouds");
87 println!("- Tags for categorization and metadata");
88
89 println!("\nBenefits:");
90 println!("- Unified identity management across clouds");
91 println!("- Provider-agnostic operations with context");
92 println!("- Cross-cloud audit trails with WAMI ARNs");
93 println!("- Multi-cloud resource tracking");
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- WAMI uses a unified ARN format internally");
98 println!("- Provider-specific ARNs can be generated when needed");
99 println!("- Context-based operations work across all providers");
100 println!("- Use tags to track cross-cloud relationships");
101
102 Ok(())
103}- examples/10_provider_switching.rs
- examples/17_attribute_based_access_control.rs
- examples/02_basic_crud_operations.rs
- examples/03_service_layer_intro.rs
- examples/05_tenant_hierarchy.rs
- examples/24_policy_attachment.rs
- examples/06_tenant_quotas_and_limits.rs
- examples/14_policy_basics.rs
- examples/11_hybrid_cloud_setup.rs
- examples/07_cross_tenant_role_assumption.rs
- examples/16_role_based_access_control.rs
- examples/12_provider_specific_features.rs
- examples/04_simple_multi_tenant.rs
- examples/08_tenant_migration.rs
- examples/13_disaster_recovery_multi_cloud.rs
- examples/23_permissions_boundaries.rs
- examples/22_identity_providers_federation.rs
Sourcepub fn tenant_hierarchy(self, segments: Vec<u64>) -> ArnBuilder
pub fn tenant_hierarchy(self, segments: Vec<u64>) -> ArnBuilder
Sets the tenant hierarchy from a vector of numeric tenant ID segments.
§Examples
use wami_core::arn::WamiArn;
let builder = WamiArn::builder()
.tenant_hierarchy(vec![12345678, 87654321, 99999999]);Sourcepub fn tenant(self, tenant_id: u64) -> ArnBuilder
pub fn tenant(self, tenant_id: u64) -> ArnBuilder
Sets a single tenant (non-hierarchical) using a numeric tenant ID.
§Examples
use wami_core::arn::WamiArn;
let builder = WamiArn::builder().tenant(12345678);Sourcepub fn wami_instance(self, instance_id: impl Into<String>) -> ArnBuilder
pub fn wami_instance(self, instance_id: impl Into<String>) -> ArnBuilder
Sets the WAMI instance ID.
§Examples
use wami_core::arn::WamiArn;
let builder = WamiArn::builder().wami_instance("999888777");Examples found in repository?
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Session Tokens ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create user
43 let user_service = UserService::new(store.clone());
44 let alice_req = CreateUserRequest {
45 user_name: "alice".to_string(),
46 path: Some("/".to_string()),
47 permissions_boundary: None,
48 tags: None,
49 };
50 let alice = user_service.create_user(&context, alice_req).await?;
51 println!("Step 1: Created user alice");
52 println!(" ARN: {}\n", alice.arn);
53
54 // Generate session token
55 let sts_service = SessionTokenService::new(store.clone());
56
57 let token_req = GetSessionTokenRequest {
58 duration_seconds: Some(3600),
59 serial_number: None,
60 token_code: None,
61 };
62
63 let response = sts_service
64 .get_session_token(&context, token_req, &alice.arn)
65 .await?;
66
67 println!("Step 2: Generated session token");
68 println!(" Access Key: {}", response.credentials.access_key_id);
69 println!(
70 " Secret Key: {}...",
71 &response.credentials.secret_access_key[..20]
72 );
73 println!(
74 " Session Token: {}...",
75 &response.credentials.session_token[..30]
76 );
77 println!(" Expiration: {}", response.credentials.expiration);
78
79 println!("\n✅ Example completed successfully!");
80 println!("Key takeaways:");
81 println!("- Session tokens provide temporary credentials");
82 println!("- Credentials expire after specified duration");
83 println!("- Useful for temporary or delegated access");
84
85 Ok(())
86}More examples
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Federated Access ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create admin user who will generate federation tokens
43 let user_service = UserService::new(store.clone());
44 let admin = user_service
45 .create_user(
46 &context,
47 CreateUserRequest {
48 user_name: "admin".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 },
53 )
54 .await?;
55
56 let fed_service = FederationService::new(store.clone());
57
58 println!("Step 1: Generating federation token for external user...\n");
59
60 let fed_req = GetFederationTokenRequest {
61 name: "partner-user".to_string(),
62 duration_seconds: Some(3600),
63 policy: Some(r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"*"}]}"#.to_string()),
64 };
65
66 let response = fed_service
67 .get_federation_token(&context, fed_req, &admin.arn)
68 .await?;
69
70 println!("✓ Generated federation token:");
71 println!(" Federated User ARN: {}", response.federated_user.arn);
72 println!(" Access Key: {}", response.credentials.access_key_id);
73 println!(" Expiration: {}", response.credentials.expiration);
74
75 println!("\n✅ Example completed successfully!");
76 println!("Key takeaways:");
77 println!("- Federation enables external user access");
78 println!("- Temporary credentials with limited permissions");
79 println!("- Useful for partner integrations");
80
81 Ok(())
82}19async fn main() -> Result<(), Box<dyn std::error::Error>> {
20 println!("=== Hello WAMI ===\n");
21
22 // Step 1: Initialize the store
23 println!("Step 1: Initializing in-memory store...");
24 let mut store = InMemoryWamiStore::default();
25 println!("✓ Store initialized");
26
27 // Step 2: Create a WamiContext for operations
28 println!("\nStep 2: Creating WAMI context...");
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0)) // Root tenant ID is 0
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42 println!("✓ Context created");
43
44 // Step 3: Build a user using pure functions
45 println!("\nStep 3: Building user 'alice'...");
46 let user = build_user("alice".to_string(), Some("/".to_string()), &context)?;
47 println!("✓ User built with ARN: {}", user.wami_arn);
48
49 // Step 4: Store the user
50 println!("\nStep 4: Storing user in the store...");
51 let created_user = store.create_user(user).await?;
52 println!("✓ User stored successfully");
53 println!(" - Name: {}", created_user.user_name);
54 println!(" - User ID: {}", created_user.user_id);
55 println!(" - ARN: {}", created_user.wami_arn);
56
57 // Step 5: Retrieve the user
58 println!("\nStep 5: Retrieving user from store...");
59 let retrieved = store.get_user("alice").await?;
60 match retrieved {
61 Some(user) => {
62 println!("✓ User retrieved successfully");
63 println!(" - Name: {}", user.user_name);
64 println!(" - Path: {}", user.path);
65 }
66 None => println!("✗ User not found"),
67 }
68
69 println!("\n✅ Example completed successfully!");
70 println!("Key takeaways:");
71 println!("- InMemoryWamiStore provides a simple storage backend");
72 println!("- Providers (AWS, GCP, Azure) handle platform-specific details");
73 println!("- Pure functions create domain objects without side effects");
74
75 Ok(())
76}22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Policy Evaluation Simulation ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 let eval_service = EvaluationService::new(store.clone(), "123456789012".to_string());
43 let user_service = UserService::new(store.clone());
44
45 // Create user
46 println!("Step 1: Creating user...\n");
47 let req = CreateUserRequest {
48 user_name: "alice".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 };
53 let alice = user_service.create_user(&context, req).await?;
54 println!("✓ Created alice: {}", alice.arn);
55
56 // === SIMULATE POLICY ===
57 println!("\n\nStep 2: Simulating custom policy...\n");
58
59 let policy_doc = r#"{
60 "Version": "2012-10-17",
61 "Statement": [{
62 "Effect": "Allow",
63 "Action": ["s3:GetObject", "s3:PutObject"],
64 "Resource": "arn:aws:s3:::my-bucket/*"
65 }]
66}"#;
67
68 // Test allowed action
69 let sim_req = SimulateCustomPolicyRequest {
70 policy_input_list: vec![policy_doc.to_string()],
71 action_names: vec!["s3:GetObject".to_string()],
72 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
73 context_entries: None,
74 };
75
76 let result = eval_service.simulate_custom_policy(sim_req).await?;
77 println!("✓ Simulation: s3:GetObject on my-bucket/file.txt");
78 println!(" Decision: {}", result.evaluation_results[0].eval_decision);
79
80 // Test denied action
81 let denied_req = SimulateCustomPolicyRequest {
82 policy_input_list: vec![policy_doc.to_string()],
83 action_names: vec!["s3:DeleteObject".to_string()],
84 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
85 context_entries: None,
86 };
87
88 let denied_result = eval_service.simulate_custom_policy(denied_req).await?;
89 println!("\n✓ Simulation: s3:DeleteObject on my-bucket/file.txt");
90 println!(
91 " Decision: {}",
92 denied_result.evaluation_results[0].eval_decision
93 );
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- Policy simulation helps test before deployment");
98 println!("- Simulate custom policies or principal policies");
99 println!("- Understand allow/deny decisions");
100 println!("- Identify missing permissions");
101
102 Ok(())
103}23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24 println!("=== Role Assumption Workflow ===\n");
25
26 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
27
28 // Create context
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0))
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42
43 let user_service = UserService::new(store.clone());
44 let role_service = RoleService::new(store.clone());
45 let sts_service = AssumeRoleService::new(store.clone());
46
47 // Create user
48 println!("Step 1: Creating user...\n");
49 let alice = user_service
50 .create_user(
51 &context,
52 CreateUserRequest {
53 user_name: "alice".to_string(),
54 path: Some("/".to_string()),
55 permissions_boundary: None,
56 tags: None,
57 },
58 )
59 .await?;
60 println!("✓ Created alice: {}", alice.arn);
61
62 // Create elevated role
63 println!("\nStep 2: Creating admin role...\n");
64 let trust_policy = r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}"#;
65 let role = role_service
66 .create_role(
67 &context,
68 CreateRoleRequest {
69 role_name: "AdminRole".to_string(),
70 path: Some("/".to_string()),
71 assume_role_policy_document: trust_policy.to_string(),
72 description: Some("Admin role for elevated access".to_string()),
73 max_session_duration: Some(3600),
74 permissions_boundary: None,
75 tags: None,
76 },
77 )
78 .await?;
79 println!("✓ Created AdminRole: {}", role.arn);
80
81 // Assume role
82 println!("\nStep 3: Alice assuming AdminRole...\n");
83 let assume_req = AssumeRoleRequest {
84 role_arn: role.arn.clone(),
85 role_session_name: "alice-admin-session".to_string(),
86 duration_seconds: Some(3600),
87 external_id: None,
88 policy: None,
89 };
90
91 let response = sts_service
92 .assume_role(&context, assume_req, &alice.arn)
93 .await?;
94 println!("✓ Successfully assumed role!");
95 println!(" Assumed Role ARN: {}", response.assumed_role_user.arn);
96 println!(" Access Key: {}", response.credentials.access_key_id);
97 println!(" Expiration: {}", response.credentials.expiration);
98
99 println!("\n✅ Example completed successfully!");
100 println!("Key takeaways:");
101 println!("- AssumeRole provides temporary elevated permissions");
102 println!("- Trust policies control who can assume roles");
103 println!("- Session credentials expire automatically");
104
105 Ok(())
106}21async fn main() -> Result<(), Box<dyn std::error::Error>> {
22 println!("=== Multi-Cloud User Sync ===\n");
23
24 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
25
26 // Create context for operations
27 let context = WamiContext::builder()
28 .instance_id("123456789012")
29 .tenant_path(TenantPath::single(0))
30 .caller_arn(
31 WamiArn::builder()
32 .service(wami::arn::Service::Iam)
33 .tenant_path(TenantPath::single(0))
34 .wami_instance("123456789012")
35 .resource("user", "admin")
36 .build()?,
37 )
38 .is_root(false)
39 .build()?;
40
41 println!("✓ Using unified context for all operations");
42
43 // === CREATE USER ===
44 println!("\n\nStep 1: Creating alice user...\n");
45
46 let user_service = UserService::new(store.clone());
47
48 let user_req = CreateUserRequest {
49 user_name: "alice".to_string(),
50 path: Some("/cloud-sync/".to_string()),
51 permissions_boundary: None,
52 tags: Some(vec![
53 wami::types::Tag {
54 key: "Email".to_string(),
55 value: "alice@company.com".to_string(),
56 },
57 wami::types::Tag {
58 key: "MultiCloud".to_string(),
59 value: "true".to_string(),
60 },
61 ]),
62 };
63
64 let user = user_service.create_user(&context, user_req).await?;
65 println!("✓ Created alice:");
66 println!(" - ARN: {}", user.arn);
67 println!(" - User ID: {}", user.user_id);
68 println!(" - WAMI ARN: {}", user.wami_arn);
69
70 // === COMPARE ARN FORMATS ===
71 println!("\n\nStep 2: Understanding WAMI ARN format...\n");
72
73 println!("WAMI unified ARN:");
74 println!(" {}", user.wami_arn);
75 println!("\nThis ARN can be transformed to provider-specific formats:");
76 println!(" - AWS ARN format for AWS API calls");
77 println!(" - GCP resource name format for GCP API calls");
78 println!(" - Azure resource ID format for Azure API calls");
79
80 // === DEMONSTRATE PROVIDER METADATA ===
81 println!("\n\nStep 3: Understanding WAMI architecture...\n");
82
83 println!("WAMI provides:");
84 println!("- Unified WAMI ARN format (for internal operations)");
85 println!("- Provider-specific ARN transformation when needed");
86 println!("- Consistent resource identification across clouds");
87 println!("- Tags for categorization and metadata");
88
89 println!("\nBenefits:");
90 println!("- Unified identity management across clouds");
91 println!("- Provider-agnostic operations with context");
92 println!("- Cross-cloud audit trails with WAMI ARNs");
93 println!("- Multi-cloud resource tracking");
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- WAMI uses a unified ARN format internally");
98 println!("- Provider-specific ARNs can be generated when needed");
99 println!("- Context-based operations work across all providers");
100 println!("- Use tags to track cross-cloud relationships");
101
102 Ok(())
103}- examples/10_provider_switching.rs
- examples/17_attribute_based_access_control.rs
- examples/02_basic_crud_operations.rs
- examples/03_service_layer_intro.rs
- examples/05_tenant_hierarchy.rs
- examples/24_policy_attachment.rs
- examples/06_tenant_quotas_and_limits.rs
- examples/14_policy_basics.rs
- examples/11_hybrid_cloud_setup.rs
- examples/07_cross_tenant_role_assumption.rs
- examples/16_role_based_access_control.rs
- examples/12_provider_specific_features.rs
- examples/04_simple_multi_tenant.rs
- examples/08_tenant_migration.rs
- examples/13_disaster_recovery_multi_cloud.rs
- examples/23_permissions_boundaries.rs
- examples/22_identity_providers_federation.rs
Sourcepub fn cloud_provider(
self,
provider: impl Into<String>,
account_id: impl Into<String>,
) -> ArnBuilder
pub fn cloud_provider( self, provider: impl Into<String>, account_id: impl Into<String>, ) -> ArnBuilder
Sets the cloud provider mapping without a region (global resource).
§Examples
use wami_core::arn::WamiArn;
let builder = WamiArn::builder()
.cloud_provider("aws", "223344556677");Sourcepub fn cloud_provider_with_region(
self,
provider: impl Into<String>,
account_id: impl Into<String>,
region: impl Into<String>,
) -> ArnBuilder
pub fn cloud_provider_with_region( self, provider: impl Into<String>, account_id: impl Into<String>, region: impl Into<String>, ) -> ArnBuilder
Sets the cloud provider mapping with a specific region.
§Examples
use wami_core::arn::WamiArn;
let builder = WamiArn::builder()
.cloud_provider_with_region("aws", "223344556677", "us-east-1");Sourcepub fn region(self, region: impl Into<String>) -> ArnBuilder
pub fn region(self, region: impl Into<String>) -> ArnBuilder
Sets the region for the current cloud mapping. If no cloud mapping exists, this does nothing.
§Examples
use wami_core::arn::WamiArn;
let builder = WamiArn::builder()
.cloud_provider("aws", "223344556677")
.region("us-east-1");Sourcepub fn cloud_mapping(self, mapping: CloudMapping) -> ArnBuilder
pub fn cloud_mapping(self, mapping: CloudMapping) -> ArnBuilder
Sets the cloud mapping directly.
§Examples
use wami_core::arn::{WamiArn, CloudMapping};
let mapping = CloudMapping::new("gcp", "554433221");
let builder = WamiArn::builder().cloud_mapping(mapping);Sourcepub fn no_cloud_mapping(self) -> ArnBuilder
pub fn no_cloud_mapping(self) -> ArnBuilder
Removes any cloud mapping (creates a WAMI-native ARN).
§Examples
use wami_core::arn::WamiArn;
let builder = WamiArn::builder()
.cloud_provider("aws", "123456")
.no_cloud_mapping();Sourcepub fn resource_obj(self, resource: Resource) -> ArnBuilder
pub fn resource_obj(self, resource: Resource) -> ArnBuilder
Sets the resource.
§Examples
use wami_core::arn::{WamiArn, Resource};
let resource = Resource::new("user", "77557755");
let builder = WamiArn::builder().resource_obj(resource);Sourcepub fn resource(
self,
resource_type: impl Into<String>,
resource_id: impl Into<String>,
) -> ArnBuilder
pub fn resource( self, resource_type: impl Into<String>, resource_id: impl Into<String>, ) -> ArnBuilder
Sets the resource from type and ID.
§Examples
use wami_core::arn::WamiArn;
let builder = WamiArn::builder().resource("user", "77557755");Examples found in repository?
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Session Tokens ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create user
43 let user_service = UserService::new(store.clone());
44 let alice_req = CreateUserRequest {
45 user_name: "alice".to_string(),
46 path: Some("/".to_string()),
47 permissions_boundary: None,
48 tags: None,
49 };
50 let alice = user_service.create_user(&context, alice_req).await?;
51 println!("Step 1: Created user alice");
52 println!(" ARN: {}\n", alice.arn);
53
54 // Generate session token
55 let sts_service = SessionTokenService::new(store.clone());
56
57 let token_req = GetSessionTokenRequest {
58 duration_seconds: Some(3600),
59 serial_number: None,
60 token_code: None,
61 };
62
63 let response = sts_service
64 .get_session_token(&context, token_req, &alice.arn)
65 .await?;
66
67 println!("Step 2: Generated session token");
68 println!(" Access Key: {}", response.credentials.access_key_id);
69 println!(
70 " Secret Key: {}...",
71 &response.credentials.secret_access_key[..20]
72 );
73 println!(
74 " Session Token: {}...",
75 &response.credentials.session_token[..30]
76 );
77 println!(" Expiration: {}", response.credentials.expiration);
78
79 println!("\n✅ Example completed successfully!");
80 println!("Key takeaways:");
81 println!("- Session tokens provide temporary credentials");
82 println!("- Credentials expire after specified duration");
83 println!("- Useful for temporary or delegated access");
84
85 Ok(())
86}More examples
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Federated Access ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create admin user who will generate federation tokens
43 let user_service = UserService::new(store.clone());
44 let admin = user_service
45 .create_user(
46 &context,
47 CreateUserRequest {
48 user_name: "admin".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 },
53 )
54 .await?;
55
56 let fed_service = FederationService::new(store.clone());
57
58 println!("Step 1: Generating federation token for external user...\n");
59
60 let fed_req = GetFederationTokenRequest {
61 name: "partner-user".to_string(),
62 duration_seconds: Some(3600),
63 policy: Some(r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"*"}]}"#.to_string()),
64 };
65
66 let response = fed_service
67 .get_federation_token(&context, fed_req, &admin.arn)
68 .await?;
69
70 println!("✓ Generated federation token:");
71 println!(" Federated User ARN: {}", response.federated_user.arn);
72 println!(" Access Key: {}", response.credentials.access_key_id);
73 println!(" Expiration: {}", response.credentials.expiration);
74
75 println!("\n✅ Example completed successfully!");
76 println!("Key takeaways:");
77 println!("- Federation enables external user access");
78 println!("- Temporary credentials with limited permissions");
79 println!("- Useful for partner integrations");
80
81 Ok(())
82}19async fn main() -> Result<(), Box<dyn std::error::Error>> {
20 println!("=== Hello WAMI ===\n");
21
22 // Step 1: Initialize the store
23 println!("Step 1: Initializing in-memory store...");
24 let mut store = InMemoryWamiStore::default();
25 println!("✓ Store initialized");
26
27 // Step 2: Create a WamiContext for operations
28 println!("\nStep 2: Creating WAMI context...");
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0)) // Root tenant ID is 0
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42 println!("✓ Context created");
43
44 // Step 3: Build a user using pure functions
45 println!("\nStep 3: Building user 'alice'...");
46 let user = build_user("alice".to_string(), Some("/".to_string()), &context)?;
47 println!("✓ User built with ARN: {}", user.wami_arn);
48
49 // Step 4: Store the user
50 println!("\nStep 4: Storing user in the store...");
51 let created_user = store.create_user(user).await?;
52 println!("✓ User stored successfully");
53 println!(" - Name: {}", created_user.user_name);
54 println!(" - User ID: {}", created_user.user_id);
55 println!(" - ARN: {}", created_user.wami_arn);
56
57 // Step 5: Retrieve the user
58 println!("\nStep 5: Retrieving user from store...");
59 let retrieved = store.get_user("alice").await?;
60 match retrieved {
61 Some(user) => {
62 println!("✓ User retrieved successfully");
63 println!(" - Name: {}", user.user_name);
64 println!(" - Path: {}", user.path);
65 }
66 None => println!("✗ User not found"),
67 }
68
69 println!("\n✅ Example completed successfully!");
70 println!("Key takeaways:");
71 println!("- InMemoryWamiStore provides a simple storage backend");
72 println!("- Providers (AWS, GCP, Azure) handle platform-specific details");
73 println!("- Pure functions create domain objects without side effects");
74
75 Ok(())
76}22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Policy Evaluation Simulation ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 let eval_service = EvaluationService::new(store.clone(), "123456789012".to_string());
43 let user_service = UserService::new(store.clone());
44
45 // Create user
46 println!("Step 1: Creating user...\n");
47 let req = CreateUserRequest {
48 user_name: "alice".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 };
53 let alice = user_service.create_user(&context, req).await?;
54 println!("✓ Created alice: {}", alice.arn);
55
56 // === SIMULATE POLICY ===
57 println!("\n\nStep 2: Simulating custom policy...\n");
58
59 let policy_doc = r#"{
60 "Version": "2012-10-17",
61 "Statement": [{
62 "Effect": "Allow",
63 "Action": ["s3:GetObject", "s3:PutObject"],
64 "Resource": "arn:aws:s3:::my-bucket/*"
65 }]
66}"#;
67
68 // Test allowed action
69 let sim_req = SimulateCustomPolicyRequest {
70 policy_input_list: vec![policy_doc.to_string()],
71 action_names: vec!["s3:GetObject".to_string()],
72 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
73 context_entries: None,
74 };
75
76 let result = eval_service.simulate_custom_policy(sim_req).await?;
77 println!("✓ Simulation: s3:GetObject on my-bucket/file.txt");
78 println!(" Decision: {}", result.evaluation_results[0].eval_decision);
79
80 // Test denied action
81 let denied_req = SimulateCustomPolicyRequest {
82 policy_input_list: vec![policy_doc.to_string()],
83 action_names: vec!["s3:DeleteObject".to_string()],
84 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
85 context_entries: None,
86 };
87
88 let denied_result = eval_service.simulate_custom_policy(denied_req).await?;
89 println!("\n✓ Simulation: s3:DeleteObject on my-bucket/file.txt");
90 println!(
91 " Decision: {}",
92 denied_result.evaluation_results[0].eval_decision
93 );
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- Policy simulation helps test before deployment");
98 println!("- Simulate custom policies or principal policies");
99 println!("- Understand allow/deny decisions");
100 println!("- Identify missing permissions");
101
102 Ok(())
103}23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24 println!("=== Role Assumption Workflow ===\n");
25
26 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
27
28 // Create context
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0))
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42
43 let user_service = UserService::new(store.clone());
44 let role_service = RoleService::new(store.clone());
45 let sts_service = AssumeRoleService::new(store.clone());
46
47 // Create user
48 println!("Step 1: Creating user...\n");
49 let alice = user_service
50 .create_user(
51 &context,
52 CreateUserRequest {
53 user_name: "alice".to_string(),
54 path: Some("/".to_string()),
55 permissions_boundary: None,
56 tags: None,
57 },
58 )
59 .await?;
60 println!("✓ Created alice: {}", alice.arn);
61
62 // Create elevated role
63 println!("\nStep 2: Creating admin role...\n");
64 let trust_policy = r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}"#;
65 let role = role_service
66 .create_role(
67 &context,
68 CreateRoleRequest {
69 role_name: "AdminRole".to_string(),
70 path: Some("/".to_string()),
71 assume_role_policy_document: trust_policy.to_string(),
72 description: Some("Admin role for elevated access".to_string()),
73 max_session_duration: Some(3600),
74 permissions_boundary: None,
75 tags: None,
76 },
77 )
78 .await?;
79 println!("✓ Created AdminRole: {}", role.arn);
80
81 // Assume role
82 println!("\nStep 3: Alice assuming AdminRole...\n");
83 let assume_req = AssumeRoleRequest {
84 role_arn: role.arn.clone(),
85 role_session_name: "alice-admin-session".to_string(),
86 duration_seconds: Some(3600),
87 external_id: None,
88 policy: None,
89 };
90
91 let response = sts_service
92 .assume_role(&context, assume_req, &alice.arn)
93 .await?;
94 println!("✓ Successfully assumed role!");
95 println!(" Assumed Role ARN: {}", response.assumed_role_user.arn);
96 println!(" Access Key: {}", response.credentials.access_key_id);
97 println!(" Expiration: {}", response.credentials.expiration);
98
99 println!("\n✅ Example completed successfully!");
100 println!("Key takeaways:");
101 println!("- AssumeRole provides temporary elevated permissions");
102 println!("- Trust policies control who can assume roles");
103 println!("- Session credentials expire automatically");
104
105 Ok(())
106}21async fn main() -> Result<(), Box<dyn std::error::Error>> {
22 println!("=== Multi-Cloud User Sync ===\n");
23
24 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
25
26 // Create context for operations
27 let context = WamiContext::builder()
28 .instance_id("123456789012")
29 .tenant_path(TenantPath::single(0))
30 .caller_arn(
31 WamiArn::builder()
32 .service(wami::arn::Service::Iam)
33 .tenant_path(TenantPath::single(0))
34 .wami_instance("123456789012")
35 .resource("user", "admin")
36 .build()?,
37 )
38 .is_root(false)
39 .build()?;
40
41 println!("✓ Using unified context for all operations");
42
43 // === CREATE USER ===
44 println!("\n\nStep 1: Creating alice user...\n");
45
46 let user_service = UserService::new(store.clone());
47
48 let user_req = CreateUserRequest {
49 user_name: "alice".to_string(),
50 path: Some("/cloud-sync/".to_string()),
51 permissions_boundary: None,
52 tags: Some(vec![
53 wami::types::Tag {
54 key: "Email".to_string(),
55 value: "alice@company.com".to_string(),
56 },
57 wami::types::Tag {
58 key: "MultiCloud".to_string(),
59 value: "true".to_string(),
60 },
61 ]),
62 };
63
64 let user = user_service.create_user(&context, user_req).await?;
65 println!("✓ Created alice:");
66 println!(" - ARN: {}", user.arn);
67 println!(" - User ID: {}", user.user_id);
68 println!(" - WAMI ARN: {}", user.wami_arn);
69
70 // === COMPARE ARN FORMATS ===
71 println!("\n\nStep 2: Understanding WAMI ARN format...\n");
72
73 println!("WAMI unified ARN:");
74 println!(" {}", user.wami_arn);
75 println!("\nThis ARN can be transformed to provider-specific formats:");
76 println!(" - AWS ARN format for AWS API calls");
77 println!(" - GCP resource name format for GCP API calls");
78 println!(" - Azure resource ID format for Azure API calls");
79
80 // === DEMONSTRATE PROVIDER METADATA ===
81 println!("\n\nStep 3: Understanding WAMI architecture...\n");
82
83 println!("WAMI provides:");
84 println!("- Unified WAMI ARN format (for internal operations)");
85 println!("- Provider-specific ARN transformation when needed");
86 println!("- Consistent resource identification across clouds");
87 println!("- Tags for categorization and metadata");
88
89 println!("\nBenefits:");
90 println!("- Unified identity management across clouds");
91 println!("- Provider-agnostic operations with context");
92 println!("- Cross-cloud audit trails with WAMI ARNs");
93 println!("- Multi-cloud resource tracking");
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- WAMI uses a unified ARN format internally");
98 println!("- Provider-specific ARNs can be generated when needed");
99 println!("- Context-based operations work across all providers");
100 println!("- Use tags to track cross-cloud relationships");
101
102 Ok(())
103}- examples/10_provider_switching.rs
- examples/17_attribute_based_access_control.rs
- examples/02_basic_crud_operations.rs
- examples/03_service_layer_intro.rs
- examples/05_tenant_hierarchy.rs
- examples/24_policy_attachment.rs
- examples/06_tenant_quotas_and_limits.rs
- examples/14_policy_basics.rs
- examples/11_hybrid_cloud_setup.rs
- examples/07_cross_tenant_role_assumption.rs
- examples/16_role_based_access_control.rs
- examples/12_provider_specific_features.rs
- examples/04_simple_multi_tenant.rs
- examples/08_tenant_migration.rs
- examples/13_disaster_recovery_multi_cloud.rs
- examples/23_permissions_boundaries.rs
- examples/22_identity_providers_federation.rs
Sourcepub fn build(self) -> Result<WamiArn, AmiError>
pub fn build(self) -> Result<WamiArn, AmiError>
Builds the ARN, returning an error if any required fields are missing.
§Errors
Returns an error if any of the following fields are not set:
- service
- tenant_path
- wami_instance_id
- resource
§Examples
use wami_core::arn::{WamiArn, Service};
let result = WamiArn::builder()
.service(Service::Iam)
.tenant(12345678)
.wami_instance("999888777")
.resource("user", "77557755")
.build();
assert!(result.is_ok());Examples found in repository?
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Session Tokens ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create user
43 let user_service = UserService::new(store.clone());
44 let alice_req = CreateUserRequest {
45 user_name: "alice".to_string(),
46 path: Some("/".to_string()),
47 permissions_boundary: None,
48 tags: None,
49 };
50 let alice = user_service.create_user(&context, alice_req).await?;
51 println!("Step 1: Created user alice");
52 println!(" ARN: {}\n", alice.arn);
53
54 // Generate session token
55 let sts_service = SessionTokenService::new(store.clone());
56
57 let token_req = GetSessionTokenRequest {
58 duration_seconds: Some(3600),
59 serial_number: None,
60 token_code: None,
61 };
62
63 let response = sts_service
64 .get_session_token(&context, token_req, &alice.arn)
65 .await?;
66
67 println!("Step 2: Generated session token");
68 println!(" Access Key: {}", response.credentials.access_key_id);
69 println!(
70 " Secret Key: {}...",
71 &response.credentials.secret_access_key[..20]
72 );
73 println!(
74 " Session Token: {}...",
75 &response.credentials.session_token[..30]
76 );
77 println!(" Expiration: {}", response.credentials.expiration);
78
79 println!("\n✅ Example completed successfully!");
80 println!("Key takeaways:");
81 println!("- Session tokens provide temporary credentials");
82 println!("- Credentials expire after specified duration");
83 println!("- Useful for temporary or delegated access");
84
85 Ok(())
86}More examples
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Federated Access ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 // Create admin user who will generate federation tokens
43 let user_service = UserService::new(store.clone());
44 let admin = user_service
45 .create_user(
46 &context,
47 CreateUserRequest {
48 user_name: "admin".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 },
53 )
54 .await?;
55
56 let fed_service = FederationService::new(store.clone());
57
58 println!("Step 1: Generating federation token for external user...\n");
59
60 let fed_req = GetFederationTokenRequest {
61 name: "partner-user".to_string(),
62 duration_seconds: Some(3600),
63 policy: Some(r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"s3:GetObject","Resource":"*"}]}"#.to_string()),
64 };
65
66 let response = fed_service
67 .get_federation_token(&context, fed_req, &admin.arn)
68 .await?;
69
70 println!("✓ Generated federation token:");
71 println!(" Federated User ARN: {}", response.federated_user.arn);
72 println!(" Access Key: {}", response.credentials.access_key_id);
73 println!(" Expiration: {}", response.credentials.expiration);
74
75 println!("\n✅ Example completed successfully!");
76 println!("Key takeaways:");
77 println!("- Federation enables external user access");
78 println!("- Temporary credentials with limited permissions");
79 println!("- Useful for partner integrations");
80
81 Ok(())
82}19async fn main() -> Result<(), Box<dyn std::error::Error>> {
20 println!("=== Hello WAMI ===\n");
21
22 // Step 1: Initialize the store
23 println!("Step 1: Initializing in-memory store...");
24 let mut store = InMemoryWamiStore::default();
25 println!("✓ Store initialized");
26
27 // Step 2: Create a WamiContext for operations
28 println!("\nStep 2: Creating WAMI context...");
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0)) // Root tenant ID is 0
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42 println!("✓ Context created");
43
44 // Step 3: Build a user using pure functions
45 println!("\nStep 3: Building user 'alice'...");
46 let user = build_user("alice".to_string(), Some("/".to_string()), &context)?;
47 println!("✓ User built with ARN: {}", user.wami_arn);
48
49 // Step 4: Store the user
50 println!("\nStep 4: Storing user in the store...");
51 let created_user = store.create_user(user).await?;
52 println!("✓ User stored successfully");
53 println!(" - Name: {}", created_user.user_name);
54 println!(" - User ID: {}", created_user.user_id);
55 println!(" - ARN: {}", created_user.wami_arn);
56
57 // Step 5: Retrieve the user
58 println!("\nStep 5: Retrieving user from store...");
59 let retrieved = store.get_user("alice").await?;
60 match retrieved {
61 Some(user) => {
62 println!("✓ User retrieved successfully");
63 println!(" - Name: {}", user.user_name);
64 println!(" - Path: {}", user.path);
65 }
66 None => println!("✗ User not found"),
67 }
68
69 println!("\n✅ Example completed successfully!");
70 println!("Key takeaways:");
71 println!("- InMemoryWamiStore provides a simple storage backend");
72 println!("- Providers (AWS, GCP, Azure) handle platform-specific details");
73 println!("- Pure functions create domain objects without side effects");
74
75 Ok(())
76}22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Policy Evaluation Simulation ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 // Create context
28 let context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(0))
31 .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(0))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 let eval_service = EvaluationService::new(store.clone(), "123456789012".to_string());
43 let user_service = UserService::new(store.clone());
44
45 // Create user
46 println!("Step 1: Creating user...\n");
47 let req = CreateUserRequest {
48 user_name: "alice".to_string(),
49 path: Some("/".to_string()),
50 permissions_boundary: None,
51 tags: None,
52 };
53 let alice = user_service.create_user(&context, req).await?;
54 println!("✓ Created alice: {}", alice.arn);
55
56 // === SIMULATE POLICY ===
57 println!("\n\nStep 2: Simulating custom policy...\n");
58
59 let policy_doc = r#"{
60 "Version": "2012-10-17",
61 "Statement": [{
62 "Effect": "Allow",
63 "Action": ["s3:GetObject", "s3:PutObject"],
64 "Resource": "arn:aws:s3:::my-bucket/*"
65 }]
66}"#;
67
68 // Test allowed action
69 let sim_req = SimulateCustomPolicyRequest {
70 policy_input_list: vec![policy_doc.to_string()],
71 action_names: vec!["s3:GetObject".to_string()],
72 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
73 context_entries: None,
74 };
75
76 let result = eval_service.simulate_custom_policy(sim_req).await?;
77 println!("✓ Simulation: s3:GetObject on my-bucket/file.txt");
78 println!(" Decision: {}", result.evaluation_results[0].eval_decision);
79
80 // Test denied action
81 let denied_req = SimulateCustomPolicyRequest {
82 policy_input_list: vec![policy_doc.to_string()],
83 action_names: vec!["s3:DeleteObject".to_string()],
84 resource_arns: Some(vec!["arn:aws:s3:::my-bucket/file.txt".to_string()]),
85 context_entries: None,
86 };
87
88 let denied_result = eval_service.simulate_custom_policy(denied_req).await?;
89 println!("\n✓ Simulation: s3:DeleteObject on my-bucket/file.txt");
90 println!(
91 " Decision: {}",
92 denied_result.evaluation_results[0].eval_decision
93 );
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- Policy simulation helps test before deployment");
98 println!("- Simulate custom policies or principal policies");
99 println!("- Understand allow/deny decisions");
100 println!("- Identify missing permissions");
101
102 Ok(())
103}23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24 println!("=== Role Assumption Workflow ===\n");
25
26 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
27
28 // Create context
29 let context = WamiContext::builder()
30 .instance_id("123456789012")
31 .tenant_path(TenantPath::single(0))
32 .caller_arn(
33 WamiArn::builder()
34 .service(wami::arn::Service::Iam)
35 .tenant_path(TenantPath::single(0))
36 .wami_instance("123456789012")
37 .resource("user", "admin")
38 .build()?,
39 )
40 .is_root(false)
41 .build()?;
42
43 let user_service = UserService::new(store.clone());
44 let role_service = RoleService::new(store.clone());
45 let sts_service = AssumeRoleService::new(store.clone());
46
47 // Create user
48 println!("Step 1: Creating user...\n");
49 let alice = user_service
50 .create_user(
51 &context,
52 CreateUserRequest {
53 user_name: "alice".to_string(),
54 path: Some("/".to_string()),
55 permissions_boundary: None,
56 tags: None,
57 },
58 )
59 .await?;
60 println!("✓ Created alice: {}", alice.arn);
61
62 // Create elevated role
63 println!("\nStep 2: Creating admin role...\n");
64 let trust_policy = r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}"#;
65 let role = role_service
66 .create_role(
67 &context,
68 CreateRoleRequest {
69 role_name: "AdminRole".to_string(),
70 path: Some("/".to_string()),
71 assume_role_policy_document: trust_policy.to_string(),
72 description: Some("Admin role for elevated access".to_string()),
73 max_session_duration: Some(3600),
74 permissions_boundary: None,
75 tags: None,
76 },
77 )
78 .await?;
79 println!("✓ Created AdminRole: {}", role.arn);
80
81 // Assume role
82 println!("\nStep 3: Alice assuming AdminRole...\n");
83 let assume_req = AssumeRoleRequest {
84 role_arn: role.arn.clone(),
85 role_session_name: "alice-admin-session".to_string(),
86 duration_seconds: Some(3600),
87 external_id: None,
88 policy: None,
89 };
90
91 let response = sts_service
92 .assume_role(&context, assume_req, &alice.arn)
93 .await?;
94 println!("✓ Successfully assumed role!");
95 println!(" Assumed Role ARN: {}", response.assumed_role_user.arn);
96 println!(" Access Key: {}", response.credentials.access_key_id);
97 println!(" Expiration: {}", response.credentials.expiration);
98
99 println!("\n✅ Example completed successfully!");
100 println!("Key takeaways:");
101 println!("- AssumeRole provides temporary elevated permissions");
102 println!("- Trust policies control who can assume roles");
103 println!("- Session credentials expire automatically");
104
105 Ok(())
106}21async fn main() -> Result<(), Box<dyn std::error::Error>> {
22 println!("=== Multi-Cloud User Sync ===\n");
23
24 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
25
26 // Create context for operations
27 let context = WamiContext::builder()
28 .instance_id("123456789012")
29 .tenant_path(TenantPath::single(0))
30 .caller_arn(
31 WamiArn::builder()
32 .service(wami::arn::Service::Iam)
33 .tenant_path(TenantPath::single(0))
34 .wami_instance("123456789012")
35 .resource("user", "admin")
36 .build()?,
37 )
38 .is_root(false)
39 .build()?;
40
41 println!("✓ Using unified context for all operations");
42
43 // === CREATE USER ===
44 println!("\n\nStep 1: Creating alice user...\n");
45
46 let user_service = UserService::new(store.clone());
47
48 let user_req = CreateUserRequest {
49 user_name: "alice".to_string(),
50 path: Some("/cloud-sync/".to_string()),
51 permissions_boundary: None,
52 tags: Some(vec![
53 wami::types::Tag {
54 key: "Email".to_string(),
55 value: "alice@company.com".to_string(),
56 },
57 wami::types::Tag {
58 key: "MultiCloud".to_string(),
59 value: "true".to_string(),
60 },
61 ]),
62 };
63
64 let user = user_service.create_user(&context, user_req).await?;
65 println!("✓ Created alice:");
66 println!(" - ARN: {}", user.arn);
67 println!(" - User ID: {}", user.user_id);
68 println!(" - WAMI ARN: {}", user.wami_arn);
69
70 // === COMPARE ARN FORMATS ===
71 println!("\n\nStep 2: Understanding WAMI ARN format...\n");
72
73 println!("WAMI unified ARN:");
74 println!(" {}", user.wami_arn);
75 println!("\nThis ARN can be transformed to provider-specific formats:");
76 println!(" - AWS ARN format for AWS API calls");
77 println!(" - GCP resource name format for GCP API calls");
78 println!(" - Azure resource ID format for Azure API calls");
79
80 // === DEMONSTRATE PROVIDER METADATA ===
81 println!("\n\nStep 3: Understanding WAMI architecture...\n");
82
83 println!("WAMI provides:");
84 println!("- Unified WAMI ARN format (for internal operations)");
85 println!("- Provider-specific ARN transformation when needed");
86 println!("- Consistent resource identification across clouds");
87 println!("- Tags for categorization and metadata");
88
89 println!("\nBenefits:");
90 println!("- Unified identity management across clouds");
91 println!("- Provider-agnostic operations with context");
92 println!("- Cross-cloud audit trails with WAMI ARNs");
93 println!("- Multi-cloud resource tracking");
94
95 println!("\n✅ Example completed successfully!");
96 println!("Key takeaways:");
97 println!("- WAMI uses a unified ARN format internally");
98 println!("- Provider-specific ARNs can be generated when needed");
99 println!("- Context-based operations work across all providers");
100 println!("- Use tags to track cross-cloud relationships");
101
102 Ok(())
103}- examples/10_provider_switching.rs
- examples/17_attribute_based_access_control.rs
- examples/02_basic_crud_operations.rs
- examples/03_service_layer_intro.rs
- examples/05_tenant_hierarchy.rs
- examples/24_policy_attachment.rs
- examples/06_tenant_quotas_and_limits.rs
- examples/14_policy_basics.rs
- examples/11_hybrid_cloud_setup.rs
- examples/07_cross_tenant_role_assumption.rs
- examples/16_role_based_access_control.rs
- examples/12_provider_specific_features.rs
- examples/04_simple_multi_tenant.rs
- examples/08_tenant_migration.rs
- examples/13_disaster_recovery_multi_cloud.rs
- examples/23_permissions_boundaries.rs
- examples/22_identity_providers_federation.rs