// file: crates/ksp-worker-api/tests/security_hardening.rs // version: 1 //! Adversarial lifecycle, stop and redaction canaries for the frozen Worker API. const HOSTILE_MARKER: &str = "WORKER-IDENTITY-SECRET-CANARY"; const TEST_FAULT: ksp_worker_api::ErrorCode = ksp_worker_api::ErrorCode::new("worker_test", "fault"); fn running_lifecycle(id_value: &str) -> std::option::Option { let id = match ksp_worker_api::WorkerId::new(id_value) { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return std::option::Option::None, }; let kind = match ksp_worker_api::WorkerKindCode::new("continuous_worker") { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return std::option::Option::None, }; let mut lifecycle = ksp_worker_api::WorkerLifecycle::new(id, kind); if lifecycle.start().is_err() { return std::option::Option::None; } if lifecycle.mark_running().is_err() { return std::option::Option::None; } return std::option::Option::Some(lifecycle); } fn assert_all_mutators_reject(lifecycle: &mut ksp_worker_api::WorkerLifecycle, terminal: ksp_worker_api::WorkerState) { assert!(lifecycle.start().is_err()); assert!(lifecycle.mark_running().is_err()); assert!(lifecycle.mark_stopping().is_err()); assert!(lifecycle.mark_stopped().is_err()); assert!(lifecycle.fault(TEST_FAULT).is_err()); assert_eq!(lifecycle.state(), terminal); return; } #[test] fn pre_003_worker_identity_lifecycle_and_snapshot_debug_redact_hostile_identity() { let lifecycle = running_lifecycle(HOSTILE_MARKER); assert!(lifecycle.is_some()); let lifecycle = match lifecycle { std::option::Option::Some(value) => value, std::option::Option::None => return, }; let id = lifecycle.id(); assert_eq!(std::format!("{id:?}"), "WorkerId(..)"); let lifecycle_debug = std::format!("{lifecycle:?}"); assert!(lifecycle_debug.contains("WorkerLifecycle")); assert!(lifecycle_debug.contains("continuous_worker")); assert!(lifecycle_debug.contains("Running")); assert!(!lifecycle_debug.contains(HOSTILE_MARKER)); let snapshot = ksp_worker_api::WorkerSnapshot::new( lifecycle.id().clone(), lifecycle.kind().clone(), ksp_worker_api::WorkerSnapshotSequence::initial(), lifecycle.state(), ksp_worker_api::WorkerHealth::Healthy, ksp_worker_api::WorkerActivity::Active, ); let snapshot_debug = std::format!("{snapshot:?}"); assert!(snapshot_debug.contains("WorkerSnapshot")); assert!(snapshot_debug.contains("continuous_worker")); assert!(snapshot_debug.contains("Healthy")); assert!(snapshot_debug.contains("Active")); assert!(!snapshot_debug.contains(HOSTILE_MARKER)); return; } #[test] fn pre_003_identity_errors_never_echo_hostile_values() { let hostile = "WORKER-SECRET/CANARY"; let rejected = ksp_worker_api::WorkerId::new(hostile); assert!(rejected.is_err()); let error = match rejected { std::result::Result::Err(value) => value, std::result::Result::Ok(_) => return, }; assert_eq!(error.code(), ksp_worker_api::ERROR_CODE_WORKER_ID_INVALID); assert!(!std::format!("{error}").contains(hostile)); assert!(!std::format!("{error:?}").contains(hostile)); for context in error.context() { assert!(!context.value().contains(hostile)); } return; } #[test] fn pre_003_stopped_and_faulted_are_immutable_under_all_public_mutators() { let id = match ksp_worker_api::WorkerId::new("terminal-created") { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let kind = match ksp_worker_api::WorkerKindCode::new("terminal_worker") { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; let mut stopped = ksp_worker_api::WorkerLifecycle::new(id, kind); assert!(stopped.mark_stopped().is_ok()); assert_all_mutators_reject(&mut stopped, ksp_worker_api::WorkerState::Stopped); let faulted = running_lifecycle("terminal-faulted"); assert!(faulted.is_some()); let mut faulted = match faulted { std::option::Option::Some(value) => value, std::option::Option::None => return, }; assert!(faulted.fault(TEST_FAULT).is_ok()); assert_all_mutators_reject(&mut faulted, ksp_worker_api::WorkerState::Faulted(TEST_FAULT)); return; } #[test] fn pre_003_stop_fault_terminal_orders_are_first_valid_terminal_wins() { let direct_fault = running_lifecycle("race-direct-fault"); assert!(direct_fault.is_some()); let mut direct_fault = match direct_fault { std::option::Option::Some(value) => value, std::option::Option::None => return, }; assert!(direct_fault.fault(TEST_FAULT).is_ok()); assert!(direct_fault.mark_stopping().is_err()); assert_eq!(direct_fault.state(), ksp_worker_api::WorkerState::Faulted(TEST_FAULT)); let stopping_fault = running_lifecycle("race-stopping-fault"); assert!(stopping_fault.is_some()); let mut stopping_fault = match stopping_fault { std::option::Option::Some(value) => value, std::option::Option::None => return, }; assert!(stopping_fault.mark_stopping().is_ok()); assert!(stopping_fault.fault(TEST_FAULT).is_ok()); assert!(stopping_fault.mark_stopped().is_err()); assert_eq!(stopping_fault.state(), ksp_worker_api::WorkerState::Faulted(TEST_FAULT)); let stopping_stopped = running_lifecycle("race-stopping-stopped"); assert!(stopping_stopped.is_some()); let mut stopping_stopped = match stopping_stopped { std::option::Option::Some(value) => value, std::option::Option::None => return, }; assert!(stopping_stopped.mark_stopping().is_ok()); assert!(stopping_stopped.mark_stopped().is_ok()); assert!(stopping_stopped.fault(TEST_FAULT).is_err()); assert_eq!(stopping_stopped.state(), ksp_worker_api::WorkerState::Stopped); return; } #[test] fn pre_003_stop_token_is_send_sync_cross_thread_and_cannot_reanimate_terminal_lifecycle() { fn require_send_sync() {} require_send_sync::(); let lifecycle = running_lifecycle("cross-thread-stop"); assert!(lifecycle.is_some()); let mut lifecycle = match lifecycle { std::option::Option::Some(value) => value, std::option::Option::None => return, }; assert!(lifecycle.fault(TEST_FAULT).is_ok()); let token = ksp_worker_api::WorkerStopToken::new(); let worker_token = token.clone(); let thread = std::thread::spawn(move || return worker_token.request_stop()); let first = match thread.join() { std::result::Result::Ok(value) => value, std::result::Result::Err(_) => return, }; assert!(first); assert!(token.is_stop_requested()); assert!(!token.request_stop()); assert!(lifecycle.mark_stopping().is_err()); assert_eq!(lifecycle.state(), ksp_worker_api::WorkerState::Faulted(TEST_FAULT)); return; } #[test] fn pre_003_public_worker_primitives_keep_promised_send_sync_contracts() { fn require_send_sync() {} require_send_sync::(); require_send_sync::(); require_send_sync::(); require_send_sync::(); require_send_sync::(); require_send_sync::(); require_send_sync::(); require_send_sync::(); require_send_sync::(); return; }