From fac87390ad79424bad417a414e814df270a05023 Mon Sep 17 00:00:00 2001 From: malizz Date: Tue, 22 Aug 2023 09:59:33 -0700 Subject: [PATCH 1/3] add outcome to header --- crates/ext-processor/src/headers.rs | 65 ++++++++++++++++++----------- crates/ext-processor/src/service.rs | 9 ++-- 2 files changed, 45 insertions(+), 29 deletions(-) diff --git a/crates/ext-processor/src/headers.rs b/crates/ext-processor/src/headers.rs index d5184355..8de8487b 100644 --- a/crates/ext-processor/src/headers.rs +++ b/crates/ext-processor/src/headers.rs @@ -1,4 +1,4 @@ -use bulwark_wasm_sdk::Decision; +use bulwark_wasm_sdk::{Decision, Outcome}; use sfv::{BareItem, Decimal, Dictionary, FromPrimitive, Item, List, ListEntry, SerializeValue}; // TODO: capture the entire outcome: accepted/suspicious/restricted + threshold values @@ -7,6 +7,7 @@ use sfv::{BareItem, Decimal, Dictionary, FromPrimitive, Item, List, ListEntry, S /// Serialize a combined [`Decision`] into a [SFV](sfv) header value to be sent with the request to the interior service. pub(crate) fn serialize_decision_sfv( decision: Decision, + outcome: Outcome, ) -> std::result::Result { let accept_value = Item::new(BareItem::Decimal( Decimal::from_f64(decision.accept).unwrap(), @@ -17,11 +18,13 @@ pub(crate) fn serialize_decision_sfv( let unknown_value = Item::new(BareItem::Decimal( Decimal::from_f64(decision.unknown).unwrap(), )); + let outcome_value = Item::new(BareItem::String(outcome.to_string())); let mut dict = Dictionary::new(); dict.insert("accept".into(), accept_value.into()); dict.insert("restrict".into(), restrict_value.into()); dict.insert("unknown".into(), unknown_value.into()); + dict.insert("outcome".into(), outcome_value.into()); dict.serialize_value() } @@ -43,36 +46,48 @@ mod tests { #[test] fn test_serialize_decision_sfv() -> Result<(), Box> { assert_eq!( - serialize_decision_sfv(Decision { - accept: 0.0, - restrict: 0.0, - unknown: 1.0 - })?, - "accept=0.0, restrict=0.0, unknown=1.0" + serialize_decision_sfv( + Decision { + accept: 0.0, + restrict: 0.0, + unknown: 1.0 + }, + Outcome::Suspected + )?, + "accept=0.0, restrict=0.0, unknown=1.0, outcome=\"suspected\"" ); assert_eq!( - serialize_decision_sfv(Decision { - accept: 0.0, - restrict: 1.0, - unknown: 0.0 - })?, - "accept=0.0, restrict=1.0, unknown=0.0" + serialize_decision_sfv( + Decision { + accept: 0.0, + restrict: 1.0, + unknown: 0.0 + }, + Outcome::Restricted + )?, + "accept=0.0, restrict=1.0, unknown=0.0, outcome=\"restricted\"" ); assert_eq!( - serialize_decision_sfv(Decision { - accept: 1.0, - restrict: 0.0, - unknown: 0.0 - })?, - "accept=1.0, restrict=0.0, unknown=0.0" + serialize_decision_sfv( + Decision { + accept: 1.0, + restrict: 0.0, + unknown: 0.0 + }, + Outcome::Accepted + )?, + "accept=1.0, restrict=0.0, unknown=0.0, outcome=\"accepted\"" ); assert_eq!( - serialize_decision_sfv(Decision { - accept: 0.333, - restrict: 0.333, - unknown: 0.333 - })?, - "accept=0.333, restrict=0.333, unknown=0.333" + serialize_decision_sfv( + Decision { + accept: 0.333, + restrict: 0.333, + unknown: 0.333 + }, + Outcome::Suspected + )?, + "accept=0.333, restrict=0.333, unknown=0.333, outcome=\"suspected\"" ); Ok(()) diff --git a/crates/ext-processor/src/service.rs b/crates/ext-processor/src/service.rs index f6485e94..78327ab3 100644 --- a/crates/ext-processor/src/service.rs +++ b/crates/ext-processor/src/service.rs @@ -10,7 +10,7 @@ use { DecisionComponents, ForwardedIP, Plugin, PluginExecutionError, PluginInstance, PluginLoadError, RedisInfo, RequestContext, ScriptRegistry, }, - bulwark_wasm_sdk::{BodyChunk, Decision}, + bulwark_wasm_sdk::{BodyChunk, Decision, Outcome}, envoy_control_plane::envoy::{ config::core::v3::{HeaderMap, HeaderValue, HeaderValueOption}, extensions::filters::http::ext_proc::v3::{processing_mode, ProcessingMode}, @@ -1023,7 +1023,7 @@ impl BulwarkProcessor { | bulwark_wasm_sdk::Outcome::Accepted // suspected requests are monitored but not rejected | bulwark_wasm_sdk::Outcome::Suspected => { - let result = Self::allow_request(&sender, &decision_components, receive_request_body).await; + let result = Self::allow_request(&sender, &decision_components, &outcome, receive_request_body).await; // TODO: must perform proper error handling on sender results, sending can fail if let Err(err) = result { debug!(message = format!("send error: {}", err)); @@ -1051,7 +1051,7 @@ impl BulwarkProcessor { return; } else { // Don't receive a body when we would have otherwise blocked if we weren't in monitor-only mode - let result = Self::allow_request(&sender, &decision_components, false).await; + let result = Self::allow_request(&sender, &decision_components, &outcome, false).await; // TODO: must perform proper error handling on sender results, sending can fail if let Err(err) = result { debug!(message = format!("send error: {}", err)); @@ -1486,6 +1486,7 @@ impl BulwarkProcessor { async fn allow_request( mut sender: &UnboundedSender>, decision_components: &DecisionComponents, + decision_outcome: &Outcome, receive_request_body: bool, ) -> Result<(), ProcessingMessageError> { // Send back a response that changes the request header for the HTTP target. @@ -1493,7 +1494,7 @@ impl BulwarkProcessor { Self::add_set_header( &mut req_headers_cr, "Bulwark-Decision", - &serialize_decision_sfv(decision_components.decision) + &serialize_decision_sfv(decision_components.decision, decision_outcome.to_owned()) .map_err(|err| SfvError::Serialization(err.to_string()))?, ); if !decision_components.tags.is_empty() { From 7acf07a9cef6817782191684581b2cb5838793a7 Mon Sep 17 00:00:00 2001 From: malizz Date: Tue, 22 Aug 2023 11:38:54 -0700 Subject: [PATCH 2/3] add score --- crates/ext-processor/src/headers.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/ext-processor/src/headers.rs b/crates/ext-processor/src/headers.rs index 8de8487b..bd3430a1 100644 --- a/crates/ext-processor/src/headers.rs +++ b/crates/ext-processor/src/headers.rs @@ -18,12 +18,16 @@ pub(crate) fn serialize_decision_sfv( let unknown_value = Item::new(BareItem::Decimal( Decimal::from_f64(decision.unknown).unwrap(), )); + let score_value = Item::new(BareItem::Decimal( + Decimal::from_f64(decision.pignistic().restrict).unwrap(), + )); let outcome_value = Item::new(BareItem::String(outcome.to_string())); let mut dict = Dictionary::new(); dict.insert("accept".into(), accept_value.into()); dict.insert("restrict".into(), restrict_value.into()); dict.insert("unknown".into(), unknown_value.into()); + dict.insert("score".into(), score_value.into()); dict.insert("outcome".into(), outcome_value.into()); dict.serialize_value() @@ -54,7 +58,7 @@ mod tests { }, Outcome::Suspected )?, - "accept=0.0, restrict=0.0, unknown=1.0, outcome=\"suspected\"" + "accept=0.0, restrict=0.0, unknown=1.0, score=0.5, outcome=\"suspected\"" ); assert_eq!( serialize_decision_sfv( @@ -65,7 +69,7 @@ mod tests { }, Outcome::Restricted )?, - "accept=0.0, restrict=1.0, unknown=0.0, outcome=\"restricted\"" + "accept=0.0, restrict=1.0, unknown=0.0, score=1.0, outcome=\"restricted\"" ); assert_eq!( serialize_decision_sfv( @@ -76,7 +80,7 @@ mod tests { }, Outcome::Accepted )?, - "accept=1.0, restrict=0.0, unknown=0.0, outcome=\"accepted\"" + "accept=1.0, restrict=0.0, unknown=0.0, score=0.0, outcome=\"accepted\"" ); assert_eq!( serialize_decision_sfv( @@ -87,7 +91,7 @@ mod tests { }, Outcome::Suspected )?, - "accept=0.333, restrict=0.333, unknown=0.333, outcome=\"suspected\"" + "accept=0.333, restrict=0.333, unknown=0.333, score=0.500, outcome=\"suspected\"" ); Ok(()) From 3d24f6f54cab017f3419bcce0889103fb8aa2520 Mon Sep 17 00:00:00 2001 From: malizz Date: Tue, 22 Aug 2023 12:12:39 -0700 Subject: [PATCH 3/3] update decision outcomes in test --- crates/ext-processor/src/headers.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/crates/ext-processor/src/headers.rs b/crates/ext-processor/src/headers.rs index bd3430a1..8ff968e1 100644 --- a/crates/ext-processor/src/headers.rs +++ b/crates/ext-processor/src/headers.rs @@ -56,9 +56,9 @@ mod tests { restrict: 0.0, unknown: 1.0 }, - Outcome::Suspected + Outcome::Accepted )?, - "accept=0.0, restrict=0.0, unknown=1.0, score=0.5, outcome=\"suspected\"" + "accept=0.0, restrict=0.0, unknown=1.0, score=0.5, outcome=\"accepted\"" ); assert_eq!( serialize_decision_sfv( @@ -78,9 +78,9 @@ mod tests { restrict: 0.0, unknown: 0.0 }, - Outcome::Accepted + Outcome::Trusted )?, - "accept=1.0, restrict=0.0, unknown=0.0, score=0.0, outcome=\"accepted\"" + "accept=1.0, restrict=0.0, unknown=0.0, score=0.0, outcome=\"trusted\"" ); assert_eq!( serialize_decision_sfv( @@ -89,9 +89,9 @@ mod tests { restrict: 0.333, unknown: 0.333 }, - Outcome::Suspected + Outcome::Accepted )?, - "accept=0.333, restrict=0.333, unknown=0.333, score=0.500, outcome=\"suspected\"" + "accept=0.333, restrict=0.333, unknown=0.333, score=0.500, outcome=\"accepted\"" ); Ok(())