From bb20adc3b469ddbd89a881b188dc50bf32658a81 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 9 Jul 2025 16:28:50 -0600 Subject: chore: print error when policies cannot be loaded --- src/authorization/cedar_authorizer.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'src/authorization/cedar_authorizer.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index 64287414..51061648 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -23,7 +23,14 @@ impl CedarAuthorizer { pub fn new_from(path: &std::path::Path, entities: cedar_policy::Entities) -> CedarAuthorizer { Self::new( - Self::load_from(path).unwrap_or_else(|_| cedar_policy::PolicySet::default()), + Self::load_from(path).unwrap_or_else(|e| { + tracing::error!( + path = ?path, + error = %e, + "Failed to load Cedar policies, using empty policy set" + ); + cedar_policy::PolicySet::default() + }), entities, ) } -- cgit v1.2.3 From 9c62299e87a89b48e829eca0491076a82d61263e Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 9 Jul 2025 17:17:14 -0600 Subject: fix: use PolicySet#merge to merge policies from multiple files --- src/authorization/cedar_authorizer.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'src/authorization/cedar_authorizer.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index 51061648..230c10a8 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -50,10 +50,7 @@ impl CedarAuthorizer { if extension == "cedar" { let content = fs::read_to_string(&file_path)?; let file_policies = cedar_policy::PolicySet::from_str(&content)?; - - for policy in file_policies.policies() { - policies.add(policy.clone())?; - } + policies.merge(&file_policies, true)?; } } } -- cgit v1.2.3 From c203a32775e10f9a5a8e474ab36631b95cf13bb3 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 9 Jul 2025 17:27:10 -0600 Subject: refactor: recursively load files and directories --- src/authorization/cedar_authorizer.rs | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src/authorization/cedar_authorizer.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index 230c10a8..5ed810a7 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -38,24 +38,29 @@ impl CedarAuthorizer { fn load_from( path: &std::path::Path, ) -> Result> { - if !path.exists() || !path.is_dir() { + if !path.exists() { return Ok(cedar_policy::PolicySet::default()); } - let mut policies = cedar_policy::PolicySet::new(); - for entry in fs::read_dir(path)? { - let file_path = entry?.path(); - - if let Some(extension) = file_path.extension() { + if path.is_file() { + if let Some(extension) = path.extension() { if extension == "cedar" { - let content = fs::read_to_string(&file_path)?; - let file_policies = cedar_policy::PolicySet::from_str(&content)?; - policies.merge(&file_policies, true)?; + let content = fs::read_to_string(&path)?; + return Ok(cedar_policy::PolicySet::from_str(&content)?); } } } - Ok(policies) + if !path.is_dir() { + return Ok(cedar_policy::PolicySet::default()); + } + + let mut policies = cedar_policy::PolicySet::new(); + for entry in fs::read_dir(path)? { + let file_path = entry?.path(); + policies.merge(&Self::load_from(&file_path)?, true)?; + } + return Ok(policies); } fn map_from( -- cgit v1.2.3 From 350be4f0dc862ea9b02a492356280ff63d4ace4e Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 9 Jul 2025 17:30:07 -0600 Subject: refactor: inline file_path variable --- src/authorization/cedar_authorizer.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/authorization/cedar_authorizer.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index 5ed810a7..f86bcf03 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -57,8 +57,7 @@ impl CedarAuthorizer { let mut policies = cedar_policy::PolicySet::new(); for entry in fs::read_dir(path)? { - let file_path = entry?.path(); - policies.merge(&Self::load_from(&file_path)?, true)?; + policies.merge(&Self::load_from(&entry?.path())?, true)?; } return Ok(policies); } -- cgit v1.2.3 From 392874038d2ac78796bd8bdceaee6ce18e11c648 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 9 Jul 2025 17:40:28 -0600 Subject: refactor: use map_or instead of match expression --- src/authorization/cedar_authorizer.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/authorization/cedar_authorizer.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index f86bcf03..6d729772 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -43,11 +43,9 @@ impl CedarAuthorizer { } if path.is_file() { - if let Some(extension) = path.extension() { - if extension == "cedar" { - let content = fs::read_to_string(&path)?; - return Ok(cedar_policy::PolicySet::from_str(&content)?); - } + if path.extension().map_or(false, |ext| ext == "cedar") { + let content = fs::read_to_string(&path)?; + return Ok(cedar_policy::PolicySet::from_str(&content)?); } } -- cgit v1.2.3 From c50336c0bd581c7e9c5799188212e81318f829a2 Mon Sep 17 00:00:00 2001 From: mo khan Date: Wed, 9 Jul 2025 17:43:19 -0600 Subject: refactor: combine conditionals --- src/authorization/cedar_authorizer.rs | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/authorization/cedar_authorizer.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index 6d729772..c6b886ec 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -42,11 +42,9 @@ impl CedarAuthorizer { return Ok(cedar_policy::PolicySet::default()); } - if path.is_file() { - if path.extension().map_or(false, |ext| ext == "cedar") { - let content = fs::read_to_string(&path)?; - return Ok(cedar_policy::PolicySet::from_str(&content)?); - } + if path.is_file() && path.extension().map_or(false, |ext| ext == "cedar") { + let content = fs::read_to_string(&path)?; + return Ok(cedar_policy::PolicySet::from_str(&content)?); } if !path.is_dir() { -- cgit v1.2.3 From 539cf6a187637783ae11becfa9d7b2d5faba4c24 Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 10 Jul 2025 08:22:16 -0600 Subject: feat: extract JWT subject claim header --- src/authorization/cedar_authorizer.rs | 9 +++++++-- tests/authorization/cedar_authorizer_test.rs | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) (limited to 'src/authorization/cedar_authorizer.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index c6b886ec..ceaee51c 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -74,11 +74,16 @@ impl CedarAuthorizer { fn principal_from( &self, - _http_request: &envoy_types::pb::envoy::service::auth::v3::attribute_context::HttpRequest, + http_request: &envoy_types::pb::envoy::service::auth::v3::attribute_context::HttpRequest, ) -> Result> { + let subject = http_request + .headers + .get("x-jwt-claim-sub") + .map_or("", |v| v); + Ok(cedar_policy::EntityUid::from_type_name_and_id( cedar_policy::EntityTypeName::from_str("User")?, - cedar_policy::EntityId::from_str("client")?, + cedar_policy::EntityId::from_str(subject)?, )) } diff --git a/tests/authorization/cedar_authorizer_test.rs b/tests/authorization/cedar_authorizer_test.rs index 8add9868..0cffeb13 100644 --- a/tests/authorization/cedar_authorizer_test.rs +++ b/tests/authorization/cedar_authorizer_test.rs @@ -74,7 +74,7 @@ mod tests { #[test] fn test_authenticated_create_sparkle() { let request = build_request(|item: &mut HttpRequest| { - item.method = "GET".to_string(); + item.method = "POST".to_string(); item.path = "/sparkles".to_string(); item.host = "sparkle.staging.runway.gitlab.net".to_string(); item.headers = build_headers(vec![ -- cgit v1.2.3 From b7338b400eea2ce06de362f046da927ed135d048 Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 10 Jul 2025 14:27:31 -0600 Subject: refactor: remove unused context value --- src/authorization/cedar_authorizer.rs | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/authorization/cedar_authorizer.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index ceaee51c..0f53dacb 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -113,7 +113,6 @@ impl CedarAuthorizer { ) -> Result> { let mut items = std::collections::HashMap::new(); - items.insert("bearer_token".to_string(), self.token_from(&http_request)); items.insert("host".to_string(), self.safe_string(&http_request.host)); items.insert("method".to_string(), self.safe_string(&http_request.method)); items.insert("path".to_string(), self.safe_string(&http_request.path)); @@ -123,19 +122,6 @@ impl CedarAuthorizer { )?) } - fn token_from( - &self, - http_request: &envoy_types::pb::envoy::service::auth::v3::attribute_context::HttpRequest, - ) -> cedar_policy::RestrictedExpression { - let bearer_token = &http_request - .headers - .get("authorization") - .and_then(|auth| auth.strip_prefix("Bearer ")) - .unwrap_or(""); - - self.safe_string(bearer_token) - } - fn safe_string(&self, item: &str) -> cedar_policy::RestrictedExpression { cedar_policy::RestrictedExpression::new_string(item.to_string()) } -- cgit v1.2.3 From 501fbdd53312a2a449891386a7982f324ccfe23a Mon Sep 17 00:00:00 2001 From: mo khan Date: Thu, 10 Jul 2025 14:28:12 -0600 Subject: feat: provide the http method and path as the action and resource --- src/authorization/cedar_authorizer.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/authorization/cedar_authorizer.rs') diff --git a/src/authorization/cedar_authorizer.rs b/src/authorization/cedar_authorizer.rs index 0f53dacb..662aafeb 100644 --- a/src/authorization/cedar_authorizer.rs +++ b/src/authorization/cedar_authorizer.rs @@ -89,21 +89,21 @@ impl CedarAuthorizer { fn permission_from( &self, - _http_request: &envoy_types::pb::envoy::service::auth::v3::attribute_context::HttpRequest, + http_request: &envoy_types::pb::envoy::service::auth::v3::attribute_context::HttpRequest, ) -> Result> { Ok(cedar_policy::EntityUid::from_type_name_and_id( cedar_policy::EntityTypeName::from_str("Action")?, - cedar_policy::EntityId::from_str("check")?, + cedar_policy::EntityId::from_str(&http_request.method)?, )) } fn resource_from( &self, - _http_request: &envoy_types::pb::envoy::service::auth::v3::attribute_context::HttpRequest, + http_request: &envoy_types::pb::envoy::service::auth::v3::attribute_context::HttpRequest, ) -> Result> { Ok(cedar_policy::EntityUid::from_type_name_and_id( cedar_policy::EntityTypeName::from_str("Resource")?, - cedar_policy::EntityId::from_str("resource")?, + cedar_policy::EntityId::from_str(&http_request.path)?, )) } -- cgit v1.2.3