pub struct Context {
pub data: HashMap<String, ContextValue>,
}
Expand description
Context for IAM evaluation containing key-value pairs
Fields§
§data: HashMap<String, ContextValue>
Context keys and their values
Implementations§
Source§impl Context
impl Context
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new empty context
Examples found in repository?
examples/evaluation_demo.rs (line 92)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 println!("=== IAM Policy Evaluation Engine Demo ===\n");
9
10 // Example 1: Simple Allow Policy
11 println!("1. Simple Allow Policy:");
12 let allow_policy = IAMPolicy::new()
13 .with_id("550e8400-e29b-41d4-a716-446655440000")
14 .add_statement(
15 IAMStatement::new(IAMEffect::Allow)
16 .with_sid("AllowS3Read")
17 .with_action(IAMAction::Single("s3:GetObject".to_string()))
18 .with_resource(IAMResource::Single("arn:aws:s3:::my-bucket/*".to_string())),
19 );
20
21 let request = IAMRequest::new(
22 Principal::Aws(PrincipalId::String(
23 "arn:aws:iam::123456789012:user/alice".to_string(),
24 )),
25 "s3:GetObject",
26 Arn::parse("arn:aws:s3:::my-bucket/file.txt").unwrap(),
27 );
28
29 match evaluate_policy(&allow_policy, &request)? {
30 Decision::Allow => println!("✓ Access ALLOWED"),
31 Decision::Deny => println!("✗ Access DENIED"),
32 Decision::NotApplicable => println!("? No applicable policy (implicit deny)"),
33 }
34 println!();
35
36 // Example 2: Simple Deny Policy
37 println!("2. Simple Deny Policy:");
38 let deny_policy = IAMPolicy::new()
39 .with_id("550e8400-e29b-41d4-a716-446655440001")
40 .add_statement(
41 IAMStatement::new(IAMEffect::Deny)
42 .with_sid("DenyS3Delete")
43 .with_action(IAMAction::Single("s3:DeleteObject".to_string()))
44 .with_resource(IAMResource::Single(
45 "arn:aws:s3:::protected-bucket/*".to_string(),
46 )),
47 );
48
49 let delete_request = IAMRequest::new(
50 Principal::Aws(PrincipalId::String(
51 "arn:aws:iam::123456789012:user/alice".to_string(),
52 )),
53 "s3:DeleteObject",
54 Arn::parse("arn:aws:s3:::protected-bucket/important.txt").unwrap(),
55 );
56
57 match evaluate_policy(&deny_policy, &delete_request)? {
58 Decision::Allow => println!("✓ Access ALLOWED"),
59 Decision::Deny => println!("✗ Access DENIED"),
60 Decision::NotApplicable => println!("? No applicable policy (implicit deny)"),
61 }
62 println!();
63
64 // Example 3: Wildcard Action Matching
65 println!("3. Wildcard Action Matching:");
66 let wildcard_policy = IAMPolicy::new()
67 .with_id("550e8400-e29b-41d4-a716-446655440002")
68 .add_statement(
69 IAMStatement::new(IAMEffect::Allow)
70 .with_sid("AllowAllS3")
71 .with_action(IAMAction::Single("s3:*".to_string()))
72 .with_resource(IAMResource::Single("arn:aws:s3:::my-bucket/*".to_string())),
73 );
74
75 let wildcard_request = IAMRequest::new(
76 Principal::Aws(PrincipalId::String(
77 "arn:aws:iam::123456789012:user/alice".to_string(),
78 )),
79 "s3:PutObject",
80 Arn::parse("arn:aws:s3:::my-bucket/new-file.txt").unwrap(),
81 );
82
83 match evaluate_policy(&wildcard_policy, &wildcard_request)? {
84 Decision::Allow => println!("✓ Wildcard action matched - Access ALLOWED"),
85 Decision::Deny => println!("✗ Access DENIED"),
86 Decision::NotApplicable => println!("? No applicable policy"),
87 }
88 println!();
89
90 // Example 4: Condition-Based Policy
91 println!("4. Condition-Based Policy:");
92 let mut context = Context::new();
93 context.insert(
94 "aws:userid".to_string(),
95 ContextValue::String("alice".to_string()),
96 );
97 context.insert(
98 "aws:CurrentTime".to_string(),
99 ContextValue::String("2024-01-15T10:00:00Z".to_string()),
100 );
101
102 let condition_policy = IAMPolicy::new()
103 .with_id("550e8400-e29b-41d4-a716-446655440003")
104 .add_statement(
105 IAMStatement::new(IAMEffect::Allow)
106 .with_sid("AllowWithCondition")
107 .with_action(IAMAction::Single("s3:GetObject".to_string()))
108 .with_resource(IAMResource::Single(
109 "arn:aws:s3:::private-bucket/*".to_string(),
110 ))
111 .with_condition(
112 IAMOperator::StringEquals,
113 "aws:userid".to_string(),
114 ConditionValue::String("alice".to_string()),
115 ),
116 );
117
118 let condition_request = IAMRequest::new_with_context(
119 Principal::Aws(PrincipalId::String(
120 "arn:aws:iam::123456789012:user/alice".to_string(),
121 )),
122 "s3:GetObject",
123 Arn::parse("arn:aws:s3:::private-bucket/personal.txt").unwrap(),
124 context,
125 );
126
127 match evaluate_policy(&condition_policy, &condition_request)? {
128 Decision::Allow => println!("✓ Condition satisfied - Access ALLOWED"),
129 Decision::Deny => println!("✗ Access DENIED"),
130 Decision::NotApplicable => println!("? Condition not satisfied"),
131 }
132 println!();
133
134 // Example 5: Failed Condition
135 println!("5. Failed Condition:");
136 let mut wrong_context = Context::new();
137 wrong_context.insert(
138 "aws:userid".to_string(),
139 ContextValue::String("bob".to_string()),
140 );
141
142 let failed_condition_request = IAMRequest::new_with_context(
143 Principal::Aws(PrincipalId::String(
144 "arn:aws:iam::123456789012:user/bob".to_string(),
145 )),
146 "s3:GetObject",
147 Arn::parse("arn:aws:s3:::private-bucket/personal.txt").unwrap(),
148 wrong_context,
149 );
150
151 match evaluate_policy(&condition_policy, &failed_condition_request)? {
152 Decision::Allow => println!("✓ Access ALLOWED"),
153 Decision::Deny => println!("✗ Access DENIED"),
154 Decision::NotApplicable => println!("? Condition failed - No applicable policy"),
155 }
156 println!();
157
158 // Example 6: Explicit Deny Overrides Allow
159 println!("6. Explicit Deny Overrides Allow:");
160 let combined_policies = vec![
161 IAMPolicy::new()
162 .with_id("550e8400-e29b-41d4-a716-446655440004")
163 .add_statement(
164 IAMStatement::new(IAMEffect::Allow)
165 .with_sid("AllowAll")
166 .with_action(IAMAction::Single("s3:*".to_string()))
167 .with_resource(IAMResource::Single("*".to_string())),
168 ),
169 IAMPolicy::new()
170 .with_id("550e8400-e29b-41d4-a716-446655440005")
171 .add_statement(
172 IAMStatement::new(IAMEffect::Deny)
173 .with_sid("DenyProtected")
174 .with_action(IAMAction::Single("s3:DeleteObject".to_string()))
175 .with_resource(IAMResource::Single(
176 "arn:aws:s3:::protected-bucket/*".to_string(),
177 )),
178 ),
179 ];
180
181 let evaluator = PolicyEvaluator::with_policies(combined_policies);
182 let protected_request = IAMRequest::new(
183 Principal::Aws(PrincipalId::String(
184 "arn:aws:iam::123456789012:user/alice".to_string(),
185 )),
186 "s3:DeleteObject",
187 Arn::parse("arn:aws:s3:::protected-bucket/critical.txt").unwrap(),
188 );
189
190 match evaluator.evaluate(&protected_request)?.decision {
191 Decision::Allow => println!("✓ Access ALLOWED"),
192 Decision::Deny => println!("✗ Explicit DENY overrides Allow"),
193 Decision::NotApplicable => println!("? No applicable policy"),
194 }
195 println!();
196
197 // Example 7: Numeric Condition
198 println!("7. Numeric Condition:");
199 let mut numeric_context = Context::new();
200 numeric_context.insert("aws:RequestCount".to_string(), ContextValue::Number(5.0));
201
202 let numeric_policy = IAMPolicy::new()
203 .with_id("550e8400-e29b-41d4-a716-446655440006")
204 .add_statement(
205 IAMStatement::new(IAMEffect::Allow)
206 .with_sid("AllowLimitedRequests")
207 .with_action(IAMAction::Single("s3:GetObject".to_string()))
208 .with_resource(IAMResource::Single("*".to_string()))
209 .with_condition(
210 IAMOperator::NumericLessThan,
211 "aws:RequestCount".to_string(),
212 ConditionValue::Number(10),
213 ),
214 );
215
216 let numeric_request = IAMRequest::new_with_context(
217 Principal::Aws(PrincipalId::String(
218 "arn:aws:iam::123456789012:user/alice".to_string(),
219 )),
220 "s3:GetObject",
221 Arn::parse("arn:aws:s3:::any-bucket/file.txt").unwrap(),
222 numeric_context,
223 );
224
225 match evaluate_policy(&numeric_policy, &numeric_request)? {
226 Decision::Allow => println!("✓ Numeric condition satisfied - Access ALLOWED"),
227 Decision::Deny => println!("✗ Access DENIED"),
228 Decision::NotApplicable => println!("? Numeric condition failed"),
229 }
230 println!();
231
232 // Example 8: Detailed Evaluation with Options
233 println!("8. Detailed Evaluation with Options:");
234 let detailed_evaluator = PolicyEvaluator::with_policies(vec![allow_policy.clone()])
235 .with_options(EvaluationOptions {
236 collect_match_details: true,
237 stop_on_explicit_deny: false,
238 max_statements: 100,
239 ignore_resource_constraints: false,
240 });
241
242 let detailed_result = detailed_evaluator.evaluate(&request)?;
243 println!("Decision: {:?}", detailed_result.decision);
244 println!("Matched Statements:");
245 for (i, statement_match) in detailed_result.matched_statements.iter().enumerate() {
246 println!(
247 " {}. SID: {:?}, Effect: {:?}, Satisfied: {}, Reason: {}",
248 i + 1,
249 statement_match.sid,
250 statement_match.effect,
251 statement_match.conditions_satisfied,
252 statement_match.reason
253 );
254 }
255 println!();
256
257 // Example 9: No Applicable Policy (Implicit Deny)
258 println!("9. No Applicable Policy (Implicit Deny):");
259 let unrelated_request = IAMRequest::new(
260 Principal::Aws(PrincipalId::String(
261 "arn:aws:iam::123456789012:user/alice".to_string(),
262 )),
263 "ec2:DescribeInstances",
264 Arn::parse("arn:aws:ec2:us-east-1:123456789012:instance/*").unwrap(),
265 );
266
267 match evaluate_policy(&allow_policy, &unrelated_request)? {
268 Decision::Allow => println!("✓ Access ALLOWED"),
269 Decision::Deny => println!("✗ Access DENIED"),
270 Decision::NotApplicable => println!("? No applicable policy - Implicit DENY"),
271 }
272 println!();
273
274 // Example 10: Resource Pattern Matching
275 println!("10. Resource Pattern Matching:");
276 let pattern_policy = IAMPolicy::new()
277 .with_id("550e8400-e29b-41d4-a716-446655440007")
278 .add_statement(
279 IAMStatement::new(IAMEffect::Allow)
280 .with_sid("AllowBucketAccess")
281 .with_action(IAMAction::Multiple(vec![
282 "s3:GetObject".to_string(),
283 "s3:PutObject".to_string(),
284 ]))
285 .with_resource(IAMResource::Single(
286 "arn:aws:s3:::user-data-*/*".to_string(),
287 )),
288 );
289
290 let pattern_request = IAMRequest::new(
291 Principal::Aws(PrincipalId::String(
292 "arn:aws:iam::123456789012:user/alice".to_string(),
293 )),
294 "s3:GetObject",
295 Arn::parse("arn:aws:s3:::user-data-alice/profile.json").unwrap(),
296 );
297
298 match evaluate_policy(&pattern_policy, &pattern_request)? {
299 Decision::Allow => println!("✓ Resource pattern matched - Access ALLOWED"),
300 Decision::Deny => println!("✗ Access DENIED"),
301 Decision::NotApplicable => println!("? Resource pattern didn't match"),
302 }
303
304 println!("\n=== Policy Evaluation Demo Complete ===");
305 println!("\nThe Policy Evaluation Engine successfully:");
306 println!("• ✅ Evaluates Allow/Deny effects");
307 println!("• ✅ Handles wildcard actions and resources");
308 println!("• ✅ Processes condition blocks with various operators");
309 println!("• ✅ Implements proper IAM logic (explicit deny overrides)");
310 println!("• ✅ Supports detailed evaluation with match information");
311 println!("• ✅ Handles multiple policies with complex interactions");
312 println!("• ✅ Provides clear Allow/Deny/NotApplicable decisions");
313
314 Ok(())
315}
Sourcepub fn with_data(data: HashMap<String, ContextValue>) -> Self
pub fn with_data(data: HashMap<String, ContextValue>) -> Self
Creates a context with initial data
Sourcepub fn get(&self, key: &str) -> Option<&ContextValue>
pub fn get(&self, key: &str) -> Option<&ContextValue>
Get a context value by key
Sourcepub fn insert(&mut self, key: String, value: ContextValue)
pub fn insert(&mut self, key: String, value: ContextValue)
Insert a context value
Examples found in repository?
examples/evaluation_demo.rs (lines 93-96)
7fn main() -> Result<(), Box<dyn std::error::Error>> {
8 println!("=== IAM Policy Evaluation Engine Demo ===\n");
9
10 // Example 1: Simple Allow Policy
11 println!("1. Simple Allow Policy:");
12 let allow_policy = IAMPolicy::new()
13 .with_id("550e8400-e29b-41d4-a716-446655440000")
14 .add_statement(
15 IAMStatement::new(IAMEffect::Allow)
16 .with_sid("AllowS3Read")
17 .with_action(IAMAction::Single("s3:GetObject".to_string()))
18 .with_resource(IAMResource::Single("arn:aws:s3:::my-bucket/*".to_string())),
19 );
20
21 let request = IAMRequest::new(
22 Principal::Aws(PrincipalId::String(
23 "arn:aws:iam::123456789012:user/alice".to_string(),
24 )),
25 "s3:GetObject",
26 Arn::parse("arn:aws:s3:::my-bucket/file.txt").unwrap(),
27 );
28
29 match evaluate_policy(&allow_policy, &request)? {
30 Decision::Allow => println!("✓ Access ALLOWED"),
31 Decision::Deny => println!("✗ Access DENIED"),
32 Decision::NotApplicable => println!("? No applicable policy (implicit deny)"),
33 }
34 println!();
35
36 // Example 2: Simple Deny Policy
37 println!("2. Simple Deny Policy:");
38 let deny_policy = IAMPolicy::new()
39 .with_id("550e8400-e29b-41d4-a716-446655440001")
40 .add_statement(
41 IAMStatement::new(IAMEffect::Deny)
42 .with_sid("DenyS3Delete")
43 .with_action(IAMAction::Single("s3:DeleteObject".to_string()))
44 .with_resource(IAMResource::Single(
45 "arn:aws:s3:::protected-bucket/*".to_string(),
46 )),
47 );
48
49 let delete_request = IAMRequest::new(
50 Principal::Aws(PrincipalId::String(
51 "arn:aws:iam::123456789012:user/alice".to_string(),
52 )),
53 "s3:DeleteObject",
54 Arn::parse("arn:aws:s3:::protected-bucket/important.txt").unwrap(),
55 );
56
57 match evaluate_policy(&deny_policy, &delete_request)? {
58 Decision::Allow => println!("✓ Access ALLOWED"),
59 Decision::Deny => println!("✗ Access DENIED"),
60 Decision::NotApplicable => println!("? No applicable policy (implicit deny)"),
61 }
62 println!();
63
64 // Example 3: Wildcard Action Matching
65 println!("3. Wildcard Action Matching:");
66 let wildcard_policy = IAMPolicy::new()
67 .with_id("550e8400-e29b-41d4-a716-446655440002")
68 .add_statement(
69 IAMStatement::new(IAMEffect::Allow)
70 .with_sid("AllowAllS3")
71 .with_action(IAMAction::Single("s3:*".to_string()))
72 .with_resource(IAMResource::Single("arn:aws:s3:::my-bucket/*".to_string())),
73 );
74
75 let wildcard_request = IAMRequest::new(
76 Principal::Aws(PrincipalId::String(
77 "arn:aws:iam::123456789012:user/alice".to_string(),
78 )),
79 "s3:PutObject",
80 Arn::parse("arn:aws:s3:::my-bucket/new-file.txt").unwrap(),
81 );
82
83 match evaluate_policy(&wildcard_policy, &wildcard_request)? {
84 Decision::Allow => println!("✓ Wildcard action matched - Access ALLOWED"),
85 Decision::Deny => println!("✗ Access DENIED"),
86 Decision::NotApplicable => println!("? No applicable policy"),
87 }
88 println!();
89
90 // Example 4: Condition-Based Policy
91 println!("4. Condition-Based Policy:");
92 let mut context = Context::new();
93 context.insert(
94 "aws:userid".to_string(),
95 ContextValue::String("alice".to_string()),
96 );
97 context.insert(
98 "aws:CurrentTime".to_string(),
99 ContextValue::String("2024-01-15T10:00:00Z".to_string()),
100 );
101
102 let condition_policy = IAMPolicy::new()
103 .with_id("550e8400-e29b-41d4-a716-446655440003")
104 .add_statement(
105 IAMStatement::new(IAMEffect::Allow)
106 .with_sid("AllowWithCondition")
107 .with_action(IAMAction::Single("s3:GetObject".to_string()))
108 .with_resource(IAMResource::Single(
109 "arn:aws:s3:::private-bucket/*".to_string(),
110 ))
111 .with_condition(
112 IAMOperator::StringEquals,
113 "aws:userid".to_string(),
114 ConditionValue::String("alice".to_string()),
115 ),
116 );
117
118 let condition_request = IAMRequest::new_with_context(
119 Principal::Aws(PrincipalId::String(
120 "arn:aws:iam::123456789012:user/alice".to_string(),
121 )),
122 "s3:GetObject",
123 Arn::parse("arn:aws:s3:::private-bucket/personal.txt").unwrap(),
124 context,
125 );
126
127 match evaluate_policy(&condition_policy, &condition_request)? {
128 Decision::Allow => println!("✓ Condition satisfied - Access ALLOWED"),
129 Decision::Deny => println!("✗ Access DENIED"),
130 Decision::NotApplicable => println!("? Condition not satisfied"),
131 }
132 println!();
133
134 // Example 5: Failed Condition
135 println!("5. Failed Condition:");
136 let mut wrong_context = Context::new();
137 wrong_context.insert(
138 "aws:userid".to_string(),
139 ContextValue::String("bob".to_string()),
140 );
141
142 let failed_condition_request = IAMRequest::new_with_context(
143 Principal::Aws(PrincipalId::String(
144 "arn:aws:iam::123456789012:user/bob".to_string(),
145 )),
146 "s3:GetObject",
147 Arn::parse("arn:aws:s3:::private-bucket/personal.txt").unwrap(),
148 wrong_context,
149 );
150
151 match evaluate_policy(&condition_policy, &failed_condition_request)? {
152 Decision::Allow => println!("✓ Access ALLOWED"),
153 Decision::Deny => println!("✗ Access DENIED"),
154 Decision::NotApplicable => println!("? Condition failed - No applicable policy"),
155 }
156 println!();
157
158 // Example 6: Explicit Deny Overrides Allow
159 println!("6. Explicit Deny Overrides Allow:");
160 let combined_policies = vec![
161 IAMPolicy::new()
162 .with_id("550e8400-e29b-41d4-a716-446655440004")
163 .add_statement(
164 IAMStatement::new(IAMEffect::Allow)
165 .with_sid("AllowAll")
166 .with_action(IAMAction::Single("s3:*".to_string()))
167 .with_resource(IAMResource::Single("*".to_string())),
168 ),
169 IAMPolicy::new()
170 .with_id("550e8400-e29b-41d4-a716-446655440005")
171 .add_statement(
172 IAMStatement::new(IAMEffect::Deny)
173 .with_sid("DenyProtected")
174 .with_action(IAMAction::Single("s3:DeleteObject".to_string()))
175 .with_resource(IAMResource::Single(
176 "arn:aws:s3:::protected-bucket/*".to_string(),
177 )),
178 ),
179 ];
180
181 let evaluator = PolicyEvaluator::with_policies(combined_policies);
182 let protected_request = IAMRequest::new(
183 Principal::Aws(PrincipalId::String(
184 "arn:aws:iam::123456789012:user/alice".to_string(),
185 )),
186 "s3:DeleteObject",
187 Arn::parse("arn:aws:s3:::protected-bucket/critical.txt").unwrap(),
188 );
189
190 match evaluator.evaluate(&protected_request)?.decision {
191 Decision::Allow => println!("✓ Access ALLOWED"),
192 Decision::Deny => println!("✗ Explicit DENY overrides Allow"),
193 Decision::NotApplicable => println!("? No applicable policy"),
194 }
195 println!();
196
197 // Example 7: Numeric Condition
198 println!("7. Numeric Condition:");
199 let mut numeric_context = Context::new();
200 numeric_context.insert("aws:RequestCount".to_string(), ContextValue::Number(5.0));
201
202 let numeric_policy = IAMPolicy::new()
203 .with_id("550e8400-e29b-41d4-a716-446655440006")
204 .add_statement(
205 IAMStatement::new(IAMEffect::Allow)
206 .with_sid("AllowLimitedRequests")
207 .with_action(IAMAction::Single("s3:GetObject".to_string()))
208 .with_resource(IAMResource::Single("*".to_string()))
209 .with_condition(
210 IAMOperator::NumericLessThan,
211 "aws:RequestCount".to_string(),
212 ConditionValue::Number(10),
213 ),
214 );
215
216 let numeric_request = IAMRequest::new_with_context(
217 Principal::Aws(PrincipalId::String(
218 "arn:aws:iam::123456789012:user/alice".to_string(),
219 )),
220 "s3:GetObject",
221 Arn::parse("arn:aws:s3:::any-bucket/file.txt").unwrap(),
222 numeric_context,
223 );
224
225 match evaluate_policy(&numeric_policy, &numeric_request)? {
226 Decision::Allow => println!("✓ Numeric condition satisfied - Access ALLOWED"),
227 Decision::Deny => println!("✗ Access DENIED"),
228 Decision::NotApplicable => println!("? Numeric condition failed"),
229 }
230 println!();
231
232 // Example 8: Detailed Evaluation with Options
233 println!("8. Detailed Evaluation with Options:");
234 let detailed_evaluator = PolicyEvaluator::with_policies(vec![allow_policy.clone()])
235 .with_options(EvaluationOptions {
236 collect_match_details: true,
237 stop_on_explicit_deny: false,
238 max_statements: 100,
239 ignore_resource_constraints: false,
240 });
241
242 let detailed_result = detailed_evaluator.evaluate(&request)?;
243 println!("Decision: {:?}", detailed_result.decision);
244 println!("Matched Statements:");
245 for (i, statement_match) in detailed_result.matched_statements.iter().enumerate() {
246 println!(
247 " {}. SID: {:?}, Effect: {:?}, Satisfied: {}, Reason: {}",
248 i + 1,
249 statement_match.sid,
250 statement_match.effect,
251 statement_match.conditions_satisfied,
252 statement_match.reason
253 );
254 }
255 println!();
256
257 // Example 9: No Applicable Policy (Implicit Deny)
258 println!("9. No Applicable Policy (Implicit Deny):");
259 let unrelated_request = IAMRequest::new(
260 Principal::Aws(PrincipalId::String(
261 "arn:aws:iam::123456789012:user/alice".to_string(),
262 )),
263 "ec2:DescribeInstances",
264 Arn::parse("arn:aws:ec2:us-east-1:123456789012:instance/*").unwrap(),
265 );
266
267 match evaluate_policy(&allow_policy, &unrelated_request)? {
268 Decision::Allow => println!("✓ Access ALLOWED"),
269 Decision::Deny => println!("✗ Access DENIED"),
270 Decision::NotApplicable => println!("? No applicable policy - Implicit DENY"),
271 }
272 println!();
273
274 // Example 10: Resource Pattern Matching
275 println!("10. Resource Pattern Matching:");
276 let pattern_policy = IAMPolicy::new()
277 .with_id("550e8400-e29b-41d4-a716-446655440007")
278 .add_statement(
279 IAMStatement::new(IAMEffect::Allow)
280 .with_sid("AllowBucketAccess")
281 .with_action(IAMAction::Multiple(vec![
282 "s3:GetObject".to_string(),
283 "s3:PutObject".to_string(),
284 ]))
285 .with_resource(IAMResource::Single(
286 "arn:aws:s3:::user-data-*/*".to_string(),
287 )),
288 );
289
290 let pattern_request = IAMRequest::new(
291 Principal::Aws(PrincipalId::String(
292 "arn:aws:iam::123456789012:user/alice".to_string(),
293 )),
294 "s3:GetObject",
295 Arn::parse("arn:aws:s3:::user-data-alice/profile.json").unwrap(),
296 );
297
298 match evaluate_policy(&pattern_policy, &pattern_request)? {
299 Decision::Allow => println!("✓ Resource pattern matched - Access ALLOWED"),
300 Decision::Deny => println!("✗ Access DENIED"),
301 Decision::NotApplicable => println!("? Resource pattern didn't match"),
302 }
303
304 println!("\n=== Policy Evaluation Demo Complete ===");
305 println!("\nThe Policy Evaluation Engine successfully:");
306 println!("• ✅ Evaluates Allow/Deny effects");
307 println!("• ✅ Handles wildcard actions and resources");
308 println!("• ✅ Processes condition blocks with various operators");
309 println!("• ✅ Implements proper IAM logic (explicit deny overrides)");
310 println!("• ✅ Supports detailed evaluation with match information");
311 println!("• ✅ Handles multiple policies with complex interactions");
312 println!("• ✅ Provides clear Allow/Deny/NotApplicable decisions");
313
314 Ok(())
315}
Sourcepub fn with_string<K: Into<String>, V: Into<String>>(
self,
key: K,
value: V,
) -> Self
pub fn with_string<K: Into<String>, V: Into<String>>( self, key: K, value: V, ) -> Self
Adds a string context value
Sourcepub fn with_boolean<K: Into<String>>(self, key: K, value: bool) -> Self
pub fn with_boolean<K: Into<String>>(self, key: K, value: bool) -> Self
Adds a boolean context value
Sourcepub fn with_number<K: Into<String>>(self, key: K, value: f64) -> Self
pub fn with_number<K: Into<String>>(self, key: K, value: f64) -> Self
Adds a numeric context value
Trait Implementations§
Source§impl<'de> Deserialize<'de> for Context
impl<'de> Deserialize<'de> for Context
Source§fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where
D: Deserializer<'de>,
Deserialize this value from the given Serde deserializer. Read more
impl StructuralPartialEq for Context
Auto Trait Implementations§
impl Freeze for Context
impl RefUnwindSafe for Context
impl Send for Context
impl Sync for Context
impl Unpin for Context
impl UnwindSafe for Context
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more