12_provider_specific_features/
12_provider_specific_features.rs1use std::sync::Arc;
14use tokio::sync::RwLock;
15use wami::arn::{TenantPath, WamiArn};
16use wami::context::WamiContext;
17use wami::service::RoleService;
18use wami::store::memory::InMemoryWamiStore;
19use wami::wami::identity::role::requests::{CreateRoleRequest, ListRolesRequest};
20
21#[tokio::main]
22async fn main() -> Result<(), Box<dyn std::error::Error>> {
23 println!("=== Provider-Specific Features ===\n");
24
25 let store = Arc::new(RwLock::new(InMemoryWamiStore::default()));
26
27 let aws_context = WamiContext::builder()
29 .instance_id("123456789012")
30 .tenant_path(TenantPath::single(10000001)) .caller_arn(
32 WamiArn::builder()
33 .service(wami::arn::Service::Iam)
34 .tenant_path(TenantPath::single(10000001))
35 .wami_instance("123456789012")
36 .resource("user", "admin")
37 .build()?,
38 )
39 .is_root(false)
40 .build()?;
41
42 let gcp_context = WamiContext::builder()
44 .instance_id("my-gcp-project")
45 .tenant_path(TenantPath::single(20000001)) .caller_arn(
47 WamiArn::builder()
48 .service(wami::arn::Service::Iam)
49 .tenant_path(TenantPath::single(20000001))
50 .wami_instance("my-gcp-project")
51 .resource("user", "admin")
52 .build()?,
53 )
54 .is_root(false)
55 .build()?;
56
57 let azure_context = WamiContext::builder()
59 .instance_id("my-subscription")
60 .tenant_path(TenantPath::single(30000001)) .caller_arn(
62 WamiArn::builder()
63 .service(wami::arn::Service::Iam)
64 .tenant_path(TenantPath::single(30000001))
65 .wami_instance("my-subscription")
66 .resource("user", "admin")
67 .build()?,
68 )
69 .is_root(false)
70 .build()?;
71
72 let role_service = RoleService::new(store.clone());
73
74 println!("Step 1: AWS IAM Role with Trust Policy...\n");
76
77 let aws_trust_policy = r#"{
78 "Version": "2012-10-17",
79 "Statement": [{
80 "Effect": "Allow",
81 "Principal": {"Service": "lambda.amazonaws.com"},
82 "Action": "sts:AssumeRole"
83 }]
84}"#;
85
86 let aws_role_req = CreateRoleRequest {
87 role_name: "lambda-execution-role".to_string(),
88 path: Some("/service-roles/".to_string()),
89 assume_role_policy_document: aws_trust_policy.to_string(),
90 description: Some("Role for Lambda function execution".to_string()),
91 max_session_duration: Some(3600),
92 permissions_boundary: None,
93 tags: None,
94 };
95
96 let aws_role = role_service.create_role(&aws_context, aws_role_req).await?;
97 println!("✓ Created AWS Lambda execution role:");
98 println!(" - ARN: {}", aws_role.arn);
99 println!(" - WAMI ARN: {}", aws_role.wami_arn);
100 println!(" - Trust Policy: Allows lambda.amazonaws.com to assume");
101 println!(" - Use case: Serverless function execution");
102
103 println!("\n\nStep 2: GCP Service Account Pattern...\n");
105
106 let gcp_trust_policy = r#"{
107 "bindings": [{
108 "role": "roles/iam.serviceAccountUser",
109 "members": ["serviceAccount:compute@my-gcp-project.iam.gserviceaccount.com"]
110 }]
111}"#;
112
113 let gcp_role_req = CreateRoleRequest {
114 role_name: "compute-service-account".to_string(),
115 path: Some("/service-accounts/".to_string()),
116 assume_role_policy_document: gcp_trust_policy.to_string(),
117 description: Some("Service account for Compute Engine".to_string()),
118 max_session_duration: Some(3600),
119 permissions_boundary: None,
120 tags: None,
121 };
122
123 let gcp_role = role_service.create_role(&gcp_context, gcp_role_req).await?;
124 println!("✓ Created GCP service account:");
125 println!(" - ARN: {}", gcp_role.arn);
126 println!(" - WAMI ARN: {}", gcp_role.wami_arn);
127 println!(" - Bindings: Compute Engine service usage");
128 println!(" - Use case: VM instance identity");
129
130 println!("\n\nStep 3: Azure Managed Identity Pattern...\n");
132
133 let azure_trust_policy = r#"{
134 "properties": {
135 "principalType": "ServicePrincipal",
136 "tenantId": "tenant-id",
137 "type": "SystemAssigned"
138 }
139}"#;
140
141 let azure_role_req = CreateRoleRequest {
142 role_name: "app-managed-identity".to_string(),
143 path: Some("/managed-identities/".to_string()),
144 assume_role_policy_document: azure_trust_policy.to_string(),
145 description: Some("Managed identity for App Service".to_string()),
146 max_session_duration: Some(3600),
147 permissions_boundary: None,
148 tags: None,
149 };
150
151 let azure_role = role_service
152 .create_role(&azure_context, azure_role_req)
153 .await?;
154 println!("✓ Created Azure managed identity:");
155 println!(" - ARN: {}", azure_role.arn);
156 println!(" - Type: System-assigned managed identity");
157 println!(" - Use case: App Service authentication");
158
159 println!("\n\nStep 4: Comparing provider identity patterns...\n");
161
162 println!("AWS IAM Roles:");
163 println!("- Trust policies define who can assume the role");
164 println!("- Used for cross-account and service-to-service access");
165 println!("- Temporary credentials via STS");
166 println!();
167 println!("GCP Service Accounts:");
168 println!("- Special type of account for applications");
169 println!("- IAM bindings control permissions");
170 println!("- Can be impersonated by other principals");
171 println!();
172 println!("Azure Managed Identities:");
173 println!("- Automatically managed by Azure");
174 println!("- System-assigned (bound to resource) or User-assigned");
175 println!("- No credential management required");
176
177 println!("\n\nStep 5: Unified view across providers...\n");
179
180 let (all_roles, _, _) = role_service
181 .list_roles(
182 &aws_context,
183 ListRolesRequest {
184 path_prefix: None,
185 pagination: None,
186 },
187 )
188 .await?;
189 println!(
190 "✓ Total roles/identities across all providers: {}",
191 all_roles.len()
192 );
193 for role in &all_roles {
194 let provider = if role.wami_arn.to_string().contains("aws") {
195 "AWS"
196 } else if role.wami_arn.to_string().contains("gcp") {
197 "GCP"
198 } else {
199 "Azure"
200 };
201 println!(" - {} ({}) → {}", role.role_name, provider, role.wami_arn);
202 }
203
204 println!("\n✅ Example completed successfully!");
205 println!("Key takeaways:");
206 println!("- Each provider has unique identity patterns");
207 println!("- WAMI abstracts differences while preserving provider semantics");
208 println!("- Trust policies define security boundaries");
209 println!("- Choose patterns based on provider strengths");
210
211 Ok(())
212}