Skip to main content

15_policy_evaluation_simulation/
15_policy_evaluation_simulation.rs

1//! Policy Evaluation Simulation
2//!
3//! This example demonstrates:
4//! - Using EvaluationService to simulate policy evaluation
5//! - Testing permissions before deployment
6//! - Understanding policy decisions
7//!
8//! Scenario: Simulating whether alice can perform specific actions.
9//!
10//! Run with: `cargo run --example 15_policy_evaluation_simulation`
11
12use std::sync::Arc;
13use tokio::sync::RwLock;
14use wami::arn::{TenantPath, WamiArn};
15use wami::context::WamiContext;
16use wami::service::{EvaluationService, UserService};
17use wami::store::memory::InMemoryWamiStore;
18use wami::wami::identity::user::requests::CreateUserRequest;
19use wami::wami::policies::evaluation::requests::SimulateCustomPolicyRequest;
20
21#[tokio::main]
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}