16_role_based_access_control/
16_role_based_access_control.rs1use 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 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 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 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 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 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}