Skip to main content

16_role_based_access_control/
16_role_based_access_control.rs

1//! Role-Based Access Control (RBAC)
2//!
3//! This example demonstrates:
4//! - Defining roles (admin, developer, viewer)
5//! - Assigning users to roles
6//! - Policy inheritance through roles
7//!
8//! Scenario: Setting up RBAC for a development team.
9//!
10//! Run with: `cargo run --example 16_role_based_access_control`
11
12use std::sync::Arc;
13use tokio::sync::RwLock;
14use wami::arn::{TenantPath, WamiArn};
15use wami::context::WamiContext;
16use wami::service::{PolicyService, RoleService, UserService};
17use wami::store::memory::InMemoryWamiStore;
18use wami::wami::identity::role::requests::CreateRoleRequest;
19use wami::wami::identity::user::requests::CreateUserRequest;
20use wami::wami::policies::policy::requests::CreatePolicyRequest;
21
22#[tokio::main]
23async fn main() -> Result<(), Box<dyn std::error::Error>> {
24    println!("=== Role-Based Access Control (RBAC) ===\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 policy_service = PolicyService::new(store.clone());
46
47    // === CREATE POLICIES ===
48    println!("Step 1: Creating role policies...\n");
49
50    let _admin_policy = policy_service.create_policy(&context, CreatePolicyRequest {
51        policy_name: "AdminPolicy".to_string(),
52        path: Some("/rbac/".to_string()),
53        policy_document: r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"*","Resource":"*"}]}"#.to_string(),
54        description: Some("Full admin access".to_string()),
55        tags: None,
56    }).await?;
57    println!("✓ Created AdminPolicy");
58
59    let _dev_policy = policy_service.create_policy(&context, CreatePolicyRequest {
60        policy_name: "DeveloperPolicy".to_string(),
61        path: Some("/rbac/".to_string()),
62        policy_document: r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:*","lambda:*"],"Resource":"*"}]}"#.to_string(),
63        description: Some("Developer access to S3 and Lambda".to_string()),
64        tags: None,
65    }).await?;
66    println!("✓ Created DeveloperPolicy");
67
68    let _viewer_policy = policy_service.create_policy(&context, CreatePolicyRequest {
69        policy_name: "ViewerPolicy".to_string(),
70        path: Some("/rbac/".to_string()),
71        policy_document: r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["s3:Get*","s3:List*"],"Resource":"*"}]}"#.to_string(),
72        description: Some("Read-only access".to_string()),
73        tags: None,
74    }).await?;
75    println!("✓ Created ViewerPolicy");
76
77    // === CREATE ROLES ===
78    println!("\n\nStep 2: Creating roles...\n");
79
80    let trust_policy = r#"{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"AWS":"*"},"Action":"sts:AssumeRole"}]}"#;
81
82    let admin_role = role_service
83        .create_role(
84            &context,
85            CreateRoleRequest {
86                role_name: "Admin".to_string(),
87                path: Some("/rbac/".to_string()),
88                assume_role_policy_document: trust_policy.to_string(),
89                description: Some("Administrator role".to_string()),
90                max_session_duration: Some(3600),
91                permissions_boundary: None,
92                tags: None,
93            },
94        )
95        .await?;
96    println!("✓ Created Admin role: {}", admin_role.arn);
97
98    let dev_role = role_service
99        .create_role(
100            &context,
101            CreateRoleRequest {
102                role_name: "Developer".to_string(),
103                path: Some("/rbac/".to_string()),
104                assume_role_policy_document: trust_policy.to_string(),
105                description: Some("Developer role".to_string()),
106                max_session_duration: Some(7200),
107                permissions_boundary: None,
108                tags: None,
109            },
110        )
111        .await?;
112    println!("✓ Created Developer role: {}", dev_role.arn);
113
114    let viewer_role = role_service
115        .create_role(
116            &context,
117            CreateRoleRequest {
118                role_name: "Viewer".to_string(),
119                path: Some("/rbac/".to_string()),
120                assume_role_policy_document: trust_policy.to_string(),
121                description: Some("Viewer role".to_string()),
122                max_session_duration: Some(3600),
123                permissions_boundary: None,
124                tags: None,
125            },
126        )
127        .await?;
128    println!("✓ Created Viewer role: {}", viewer_role.arn);
129
130    // === CREATE USERS ===
131    println!("\n\nStep 3: Creating users...\n");
132
133    user_service
134        .create_user(
135            &context,
136            CreateUserRequest {
137                user_name: "alice".to_string(),
138                path: Some("/team/".to_string()),
139                permissions_boundary: None,
140                tags: Some(vec![wami::types::Tag {
141                    key: "Role".to_string(),
142                    value: "Admin".to_string(),
143                }]),
144            },
145        )
146        .await?;
147    println!("✓ Created alice (will be assigned Admin role)");
148
149    user_service
150        .create_user(
151            &context,
152            CreateUserRequest {
153                user_name: "bob".to_string(),
154                path: Some("/team/".to_string()),
155                permissions_boundary: None,
156                tags: Some(vec![wami::types::Tag {
157                    key: "Role".to_string(),
158                    value: "Developer".to_string(),
159                }]),
160            },
161        )
162        .await?;
163    println!("✓ Created bob (will be assigned Developer role)");
164
165    user_service
166        .create_user(
167            &context,
168            CreateUserRequest {
169                user_name: "charlie".to_string(),
170                path: Some("/team/".to_string()),
171                permissions_boundary: None,
172                tags: Some(vec![wami::types::Tag {
173                    key: "Role".to_string(),
174                    value: "Viewer".to_string(),
175                }]),
176            },
177        )
178        .await?;
179    println!("✓ Created charlie (will be assigned Viewer role)");
180
181    // === DEMONSTRATE RBAC ===
182    println!("\n\nStep 4: Understanding RBAC pattern...\n");
183
184    println!("RBAC structure created:");
185    println!();
186    println!("Roles → Policies:");
187    println!("  Admin → AdminPolicy (full access)");
188    println!("  Developer → DeveloperPolicy (S3 + Lambda)");
189    println!("  Viewer → ViewerPolicy (read-only)");
190    println!();
191    println!("Users → Roles (via AssumeRole):");
192    println!("  alice → Admin");
193    println!("  bob → Developer");
194    println!("  charlie → Viewer");
195    println!();
196    println!("Benefits of RBAC:");
197    println!("- Centralized permission management");
198    println!("- Easy to add/remove users from roles");
199    println!("- Consistent permissions across teams");
200    println!("- Simplified auditing");
201
202    println!("\n✅ Example completed successfully!");
203
204    Ok(())
205}