fix: redact observation source debug output
This commit is contained in:
parent
aeb12b3b8e
commit
38ff7d8f80
|
|
@ -10,7 +10,7 @@ use tokio_tungstenite::tungstenite::{Error as TungsteniteError, Message as Tungs
|
||||||
use worker_runtime::http_server::{RuntimeWorkerEventWsEnvelope, RuntimeWorkerEventWsFrame};
|
use worker_runtime::http_server::{RuntimeWorkerEventWsEnvelope, RuntimeWorkerEventWsFrame};
|
||||||
|
|
||||||
/// Backend-private source for a runtime worker observation stream.
|
/// Backend-private source for a runtime worker observation stream.
|
||||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
pub struct RuntimeObservationSourceConfig {
|
pub struct RuntimeObservationSourceConfig {
|
||||||
pub runtime_id: String,
|
pub runtime_id: String,
|
||||||
pub worker_id: String,
|
pub worker_id: String,
|
||||||
|
|
@ -18,6 +18,20 @@ pub struct RuntimeObservationSourceConfig {
|
||||||
pub bearer_token: Option<String>,
|
pub bearer_token: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for RuntimeObservationSourceConfig {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("RuntimeObservationSourceConfig")
|
||||||
|
.field("runtime_id", &self.runtime_id)
|
||||||
|
.field("worker_id", &self.worker_id)
|
||||||
|
.field("endpoint", &"<backend-private>")
|
||||||
|
.field(
|
||||||
|
"bearer_token",
|
||||||
|
&self.bearer_token.as_ref().map(|_| "<redacted>"),
|
||||||
|
)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Event consumed from a Runtime-owned worker observation WebSocket.
|
/// Event consumed from a Runtime-owned worker observation WebSocket.
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||||
pub struct RuntimeObservationUpstreamEvent {
|
pub struct RuntimeObservationUpstreamEvent {
|
||||||
|
|
@ -181,12 +195,21 @@ pub struct BackendObservationOpen {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Backend-owned in-memory v0 observation proxy state.
|
/// Backend-owned in-memory v0 observation proxy state.
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone)]
|
||||||
pub struct BackendObservationProxy {
|
pub struct BackendObservationProxy {
|
||||||
sources: Arc<BTreeMap<ObservationKey, RuntimeObservationSourceConfig>>,
|
sources: Arc<BTreeMap<ObservationKey, RuntimeObservationSourceConfig>>,
|
||||||
state: Arc<Mutex<BackendObservationState>>,
|
state: Arc<Mutex<BackendObservationState>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for BackendObservationProxy {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("BackendObservationProxy")
|
||||||
|
.field("source_count", &self.sources.len())
|
||||||
|
.field("state", &"<omitted>")
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl BackendObservationProxy {
|
impl BackendObservationProxy {
|
||||||
pub fn new(sources: Vec<RuntimeObservationSourceConfig>) -> Self {
|
pub fn new(sources: Vec<RuntimeObservationSourceConfig>) -> Self {
|
||||||
let sources = sources
|
let sources = sources
|
||||||
|
|
@ -475,3 +498,56 @@ impl RuntimeWsObservationClient {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
fn sensitive_source() -> RuntimeObservationSourceConfig {
|
||||||
|
RuntimeObservationSourceConfig {
|
||||||
|
runtime_id: "remote-runtime".to_string(),
|
||||||
|
worker_id: "worker-1".to_string(),
|
||||||
|
endpoint: "wss://remote.example.invalid/private/workers/worker-1/events/ws".to_string(),
|
||||||
|
bearer_token: Some("top-secret-bearer-token".to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn runtime_observation_source_debug_redacts_endpoint_and_token() {
|
||||||
|
let debug = format!("{:?}", sensitive_source());
|
||||||
|
|
||||||
|
assert!(debug.contains("remote-runtime"));
|
||||||
|
assert!(debug.contains("worker-1"));
|
||||||
|
assert!(debug.contains("<backend-private>"));
|
||||||
|
assert!(debug.contains("<redacted>"));
|
||||||
|
for forbidden in [
|
||||||
|
"remote.example.invalid",
|
||||||
|
"/private/workers/worker-1/events/ws",
|
||||||
|
"top-secret-bearer-token",
|
||||||
|
] {
|
||||||
|
assert!(
|
||||||
|
!debug.contains(forbidden),
|
||||||
|
"debug leaked {forbidden}: {debug}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn backend_observation_proxy_debug_redacts_contained_sources() {
|
||||||
|
let proxy = BackendObservationProxy::new(vec![sensitive_source()]);
|
||||||
|
let debug = format!("{proxy:?}");
|
||||||
|
|
||||||
|
assert!(debug.contains("BackendObservationProxy"));
|
||||||
|
assert!(debug.contains("source_count"));
|
||||||
|
for forbidden in [
|
||||||
|
"remote.example.invalid",
|
||||||
|
"/private/workers/worker-1/events/ws",
|
||||||
|
"top-secret-bearer-token",
|
||||||
|
] {
|
||||||
|
assert!(
|
||||||
|
!debug.contains(forbidden),
|
||||||
|
"debug leaked {forbidden}: {debug}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user