From 0e96e8e8c977fc77fcd72ed4e8482639b07939a7 Mon Sep 17 00:00:00 2001 From: Kris Hicks Date: Fri, 30 Oct 2026 15:23:37 +0000 Subject: [PATCH] feat(ocsf)!: emit OCSF 1.8.0 only and deprecate the schema version knobs (#5036) Remove the OCSF schema downgrade. OpenShell now writes native OCSF 1.8.0 records to supervisor JSONL and stderr, gateway JSONL, and OTLP log export regardless of configuration. The downgrade did not produce valid records: events it labelled 1.1 or 1.3 failed validation against those versions, because OpenShell's emitters rely on requirements that only 1.8 relaxed (#4284). It was also not shown to be required by any SIEM: of ten sinks and pipelines tested with real OpenShell records, none rejected native 1.8.0 or gated on metadata.version. The version knobs stay accepted so existing configuration still loads, but they are deprecated and ignored: - The ocsf_schema_version sandbox setting accepts any value; the supervisor reports a newly set value as a Device Config State Change event. - schema_version under [openshell.gateway.ocsf_log] and [openshell.gateway.otlp.ocsf], and the server.ocsfLog.schemaVersion Helm value, accept any value; the gateway logs a warning at startup. - The compute drivers' OPENSHELL_OTLP_OCSF_SCHEMA_VERSION flag and environment variable are hidden and ignored, with a warning, and are no longer forwarded to sandboxes. BREAKING CHANGE: Deployments that set an OCSF schema version now receive native OCSF 1.8.0 records instead of records labelled 1.1 or 1.3. Closes #4284 Signed-off-by: Kris Hicks --- crates/openshell-core/src/sandbox_env.rs | 25 +- crates/openshell-core/src/settings.rs | 48 +-- crates/openshell-driver-docker/src/main.rs | 23 +- crates/openshell-driver-docker/src/tests.rs | 9 +- .../openshell-driver-kubernetes/src/driver.rs | 10 +- .../openshell-driver-kubernetes/src/main.rs | 23 +- .../openshell-driver-podman/src/container.rs | 5 - crates/openshell-driver-podman/src/driver.rs | 2 - crates/openshell-driver-podman/src/main.rs | 23 +- crates/openshell-driver-vm/src/main.rs | 23 +- crates/openshell-gateway/src/lib.rs | 3 - crates/openshell-gateway/src/vm.rs | 13 +- crates/openshell-ocsf-validate/src/lib.rs | 4 +- crates/openshell-ocsf/src/format/downgrade.rs | 290 ------------------ crates/openshell-ocsf/src/format/mod.rs | 1 - crates/openshell-ocsf/src/lib.rs | 2 - .../src/tracing_layers/jsonl_layer.rs | 51 +-- crates/openshell-ocsf/tests/console_output.rs | 14 +- crates/openshell-otel/src/ocsf.rs | 69 ++--- crates/openshell-server/src/cli.rs | 7 + crates/openshell-server/src/config_file.rs | 95 ++++-- crates/openshell-server/src/ocsf_log.rs | 30 +- crates/openshell-server/src/otel_tracing.rs | 7 +- .../src/config_runtime.rs | 72 +++-- crates/openshell-supervisor/src/lib.rs | 3 +- crates/openshell-supervisor/src/logging.rs | 8 +- crates/openshell-supervisor/src/main.rs | 36 +-- crates/openshell-supervisor/src/shared.rs | 1 - deploy/helm/openshell/README.md | 2 +- deploy/helm/openshell/templates/_toml.tpl | 2 +- .../openshell/tests/gateway_config_test.yaml | 17 +- deploy/helm/openshell/values.yaml | 4 +- docs/how-it-works/gateways/configuration.mdx | 18 +- docs/images/splunk-cim-v1.1-downgrade.png | Bin 171583 -> 0 bytes docs/observability/ocsf-json-export.mdx | 75 +---- docs/observability/overview.mdx | 2 +- e2e/rust/tests/ocsf_jsonl_conformance.rs | 11 +- skills/debug-openshell-cluster/SKILL.md | 2 +- skills/openshell-cli/SKILL.md | 3 - 39 files changed, 263 insertions(+), 770 deletions(-) delete mode 100644 crates/openshell-ocsf/src/format/downgrade.rs delete mode 100644 docs/images/splunk-cim-v1.1-downgrade.png diff --git a/crates/openshell-core/src/sandbox_env.rs b/crates/openshell-core/src/sandbox_env.rs index 00648f8b8..f106a1e7e 100644 --- a/crates/openshell-core/src/sandbox_env.rs +++ b/crates/openshell-core/src/sandbox_env.rs @@ -38,9 +38,6 @@ pub const OTLP_OCSF_ENDPOINT: &str = "OPENSHELL_OTLP_OCSF_ENDPOINT"; /// keeps the relay inactive and leaves the workload environment unchanged. pub const OTLP_AGENT_ENDPOINT: &str = "OPENSHELL_OTLP_AGENT_ENDPOINT"; -/// OCSF schema version that supervisors downgrade exported events to. -pub const OTLP_OCSF_SCHEMA_VERSION: &str = "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION"; - /// Name of the gateway that launched the sandbox, reported as /// `openshell.gateway.name` on supervisor telemetry. pub const GATEWAY_NAME: &str = "OPENSHELL_GATEWAY_NAME"; @@ -49,19 +46,12 @@ pub const GATEWAY_NAME: &str = "OPENSHELL_GATEWAY_NAME"; #[derive(Clone, Debug, Eq, PartialEq)] pub struct OcsfOtlpExport { pub endpoint: String, - pub schema_version: Option, } impl OcsfOtlpExport { /// The supervisor environment variables for this export. pub fn environment(&self) -> Vec<(&'static str, String)> { - std::iter::once((OTLP_OCSF_ENDPOINT, self.endpoint.clone())) - .chain( - self.schema_version - .clone() - .map(|version| (OTLP_OCSF_SCHEMA_VERSION, version)), - ) - .collect() + vec![(OTLP_OCSF_ENDPOINT, self.endpoint.clone())] } } @@ -392,23 +382,14 @@ mod tests { use super::*; #[test] - fn ocsf_export_environment_carries_the_schema_version_only_when_set() { - let mut export = OcsfOtlpExport { + fn ocsf_export_environment_carries_the_endpoint() { + let export = OcsfOtlpExport { endpoint: "http://siem:4317".into(), - schema_version: None, }; assert_eq!( export.environment(), [(OTLP_OCSF_ENDPOINT, "http://siem:4317".to_string())] ); - export.schema_version = Some("1.3".into()); - assert_eq!( - export.environment(), - [ - (OTLP_OCSF_ENDPOINT, "http://siem:4317".to_string()), - (OTLP_OCSF_SCHEMA_VERSION, "1.3".to_string()), - ] - ); } #[test] diff --git a/crates/openshell-core/src/settings.rs b/crates/openshell-core/src/settings.rs index c3db1f731..f819d8ab3 100644 --- a/crates/openshell-core/src/settings.rs +++ b/crates/openshell-core/src/settings.rs @@ -106,14 +106,6 @@ pub const PROPOSAL_APPROVAL_MODE_KEY: &str = "proposal_approval_mode"; /// fail-closes on unknown persisted values for defense in depth. pub const PROPOSAL_APPROVAL_MODE_VALUES: &[&str] = &["manual", "auto"]; -/// Allowed values for `ocsf_schema_version`. -/// -/// Only versions with actual downgrade transforms in -/// `openshell_ocsf::format::downgrade` are accepted. Empty string disables -/// downgrade (equivalent to unsetting the key). Malformed or unsupported -/// versions (e.g. `"banana"`, `"1.6"`) are rejected at configure time. -pub const OCSF_SCHEMA_VERSION_VALUES: &[&str] = &["", "1.1", "1.3"]; - pub const REGISTERED_SETTINGS: &[RegisteredSetting] = &[ // When true the supervisor emits OCSF-JSON records to stderr and writes // JSONL to `/var/log/openshell-ocsf*.jsonl` when file logging is available. @@ -123,13 +115,12 @@ pub const REGISTERED_SETTINGS: &[RegisteredSetting] = &[ kind: SettingValueKind::Bool, allowed_string_values: None, }, - // Target OCSF schema version for JSONL downgrade. When set (e.g. "1.1" - // or "1.3"), the JSONL layer strips fields and profiles that don't exist - // in the target version. Empty or unset means no downgrade. + // Deprecated and ignored: OpenShell emits OCSF 1.8.0 only. Still + // registered so existing values load; the supervisor reports a set value. RegisteredSetting { key: "ocsf_schema_version", kind: SettingValueKind::String, - allowed_string_values: Some(OCSF_SCHEMA_VERSION_VALUES), + allowed_string_values: None, }, // Sandbox-level opt-in for the agent-driven policy proposal surface. // See AGENT_POLICY_PROPOSALS_ENABLED_KEY for details. Defaults to false. @@ -176,9 +167,8 @@ pub fn parse_bool_like(raw: &str) -> Option { #[cfg(test)] mod tests { use super::{ - OCSF_SCHEMA_VERSION_VALUES, PROPOSAL_APPROVAL_MODE_KEY, PROPOSAL_APPROVAL_MODE_VALUES, - REGISTERED_SETTINGS, RegisteredSetting, SettingValueKind, parse_bool_like, - registered_keys_csv, setting_for_key, + PROPOSAL_APPROVAL_MODE_KEY, PROPOSAL_APPROVAL_MODE_VALUES, REGISTERED_SETTINGS, + RegisteredSetting, SettingValueKind, parse_bool_like, registered_keys_csv, setting_for_key, }; #[test] @@ -243,33 +233,15 @@ mod tests { } } - // ---- ocsf_schema_version validation ---- + // ---- ocsf_schema_version (deprecated) ---- #[test] - fn ocsf_schema_version_accepts_supported_versions() { + fn deprecated_ocsf_schema_version_accepts_any_value() { let setting = setting_for_key("ocsf_schema_version") - .expect("ocsf_schema_version should be registered"); + .expect("ocsf_schema_version should stay registered while deprecated"); assert_eq!(setting.kind, SettingValueKind::String); - assert_eq!( - setting.allowed_string_values, - Some(OCSF_SCHEMA_VERSION_VALUES) - ); - assert!(setting.validate_string_value("").is_ok()); - assert!(setting.validate_string_value("1.1").is_ok()); - assert!(setting.validate_string_value("1.3").is_ok()); - } - - #[test] - fn ocsf_schema_version_rejects_malformed_and_unsupported() { - let setting = setting_for_key("ocsf_schema_version") - .expect("ocsf_schema_version should be registered"); - for bad in [ - "banana", "1.6", "1.5", "1.7", "1.7.0", "1.1.0", "2.0", " 1.1", "1.1 ", "v1.1", - ] { - let err = setting - .validate_string_value(bad) - .expect_err(&format!("expected '{bad}' to be rejected")); - assert_eq!(err, OCSF_SCHEMA_VERSION_VALUES); + for value in ["", "1.3", "anything"] { + assert!(setting.validate_string_value(value).is_ok(), "{value}"); } } diff --git a/crates/openshell-driver-docker/src/main.rs b/crates/openshell-driver-docker/src/main.rs index dc63c1e0f..da45b1284 100644 --- a/crates/openshell-driver-docker/src/main.rs +++ b/crates/openshell-driver-docker/src/main.rs @@ -51,12 +51,8 @@ struct Args { #[arg(long, env = "OPENSHELL_OTLP_OCSF_ENDPOINT")] otlp_ocsf_endpoint: Option, - /// OCSF schema version that supervisors downgrade exported events to. - #[arg( - long, - env = "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION", - requires = "otlp_ocsf_endpoint" - )] + /// Deprecated and ignored: `OpenShell` emits OCSF 1.8.0 only. + #[arg(long, env = "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION", hide = true)] otlp_ocsf_schema_version: Option, /// OTLP/gRPC collector endpoint that supervisors relay workload traces @@ -80,6 +76,11 @@ async fn main() -> Result<()> { log_level: &args.log_level, }, ); + if args.otlp_ocsf_schema_version.is_some() { + tracing::warn!( + "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION is deprecated and ignored; OpenShell emits OCSF 1.8.0" + ); + } let config_source = std::fs::read_to_string(&args.config).into_diagnostic()?; let mut docker_config: DockerComputeConfig = @@ -97,12 +98,10 @@ async fn main() -> Result<()> { docker_config.supervisor_otlp_endpoint = args.otlp_endpoint.clone(); docker_config.supervisor_otlp_agent_endpoint = args.otlp_agent_endpoint.clone(); docker_config.supervisor_gateway_name = args.gateway_name.clone(); - docker_config.supervisor_ocsf_export = args.otlp_ocsf_endpoint.clone().map(|endpoint| { - openshell_core::sandbox_env::OcsfOtlpExport { - endpoint, - schema_version: args.otlp_ocsf_schema_version.clone(), - } - }); + docker_config.supervisor_ocsf_export = args + .otlp_ocsf_endpoint + .clone() + .map(|endpoint| openshell_core::sandbox_env::OcsfOtlpExport { endpoint }); let driver = DockerComputeDriver::new(args.gateway_bind, &args.log_level, &docker_config, None) .await .into_diagnostic()?; diff --git a/crates/openshell-driver-docker/src/tests.rs b/crates/openshell-driver-docker/src/tests.rs index 2eab3e5ee..7e99f37e2 100644 --- a/crates/openshell-driver-docker/src/tests.rs +++ b/crates/openshell-driver-docker/src/tests.rs @@ -1517,8 +1517,7 @@ fn docker_child_environment_strips_supervisor_control_keys() { #[test] fn supervisor_otlp_environment_carries_only_configured_signals() { use openshell_core::sandbox_env::{ - GATEWAY_NAME, OTLP_AGENT_ENDPOINT, OTLP_ENDPOINT, OTLP_OCSF_ENDPOINT, - OTLP_OCSF_SCHEMA_VERSION, OcsfOtlpExport, + GATEWAY_NAME, OTLP_AGENT_ENDPOINT, OTLP_ENDPOINT, OTLP_OCSF_ENDPOINT, OcsfOtlpExport, }; let mut config = runtime_config(); @@ -1533,14 +1532,10 @@ fn supervisor_otlp_environment_carries_only_configured_signals() { config.supervisor_otlp_endpoint = None; config.supervisor_ocsf_export = Some(OcsfOtlpExport { endpoint: "http://siem:4317".to_string(), - schema_version: Some("1.3".to_string()), }); assert_eq!( supervisor_otlp_environment(&config), - [ - format!("{OTLP_OCSF_ENDPOINT}=http://siem:4317"), - format!("{OTLP_OCSF_SCHEMA_VERSION}=1.3"), - ] + [format!("{OTLP_OCSF_ENDPOINT}=http://siem:4317")] ); config.supervisor_ocsf_export = None; diff --git a/crates/openshell-driver-kubernetes/src/driver.rs b/crates/openshell-driver-kubernetes/src/driver.rs index 65be627dc..e5b12dd7e 100644 --- a/crates/openshell-driver-kubernetes/src/driver.rs +++ b/crates/openshell-driver-kubernetes/src/driver.rs @@ -8978,9 +8978,7 @@ mod tests { #[tokio::test] async fn supervisor_otlp_environment_carries_only_configured_signals() { - use openshell_core::sandbox_env::{ - OTLP_ENDPOINT, OTLP_OCSF_ENDPOINT, OTLP_OCSF_SCHEMA_VERSION, OcsfOtlpExport, - }; + use openshell_core::sandbox_env::{OTLP_ENDPOINT, OTLP_OCSF_ENDPOINT, OcsfOtlpExport}; let names = |config: KubernetesComputeConfig| { KubernetesComputeDriver::new_for_test(config) @@ -9002,16 +9000,12 @@ mod tests { let driver = KubernetesComputeDriver::new_for_test(KubernetesComputeConfig { supervisor_ocsf_export: Some(OcsfOtlpExport { endpoint: "http://siem:4317".into(), - schema_version: Some("1.1".into()), }), ..Default::default() }); assert_eq!( driver.supervisor_otlp_environment(), - [ - (OTLP_OCSF_ENDPOINT, "http://siem:4317".to_string()), - (OTLP_OCSF_SCHEMA_VERSION, "1.1".to_string()), - ] + [(OTLP_OCSF_ENDPOINT, "http://siem:4317".to_string())] ); let driver = KubernetesComputeDriver::new_for_test(KubernetesComputeConfig { diff --git a/crates/openshell-driver-kubernetes/src/main.rs b/crates/openshell-driver-kubernetes/src/main.rs index 7803d1561..7326d904a 100644 --- a/crates/openshell-driver-kubernetes/src/main.rs +++ b/crates/openshell-driver-kubernetes/src/main.rs @@ -49,12 +49,8 @@ struct Args { #[arg(long, env = "OPENSHELL_OTLP_OCSF_ENDPOINT")] otlp_ocsf_endpoint: Option, - /// OCSF schema version that supervisors downgrade exported events to. - #[arg( - long, - env = "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION", - requires = "otlp_ocsf_endpoint" - )] + /// Deprecated and ignored: `OpenShell` emits OCSF 1.8.0 only. + #[arg(long, env = "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION", hide = true)] otlp_ocsf_schema_version: Option, /// OTLP/gRPC collector endpoint that supervisors relay workload traces @@ -248,6 +244,11 @@ async fn main() -> Result<()> { log_level: &args.log_level, }, ); + if args.otlp_ocsf_schema_version.is_some() { + tracing::warn!( + "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION is deprecated and ignored; OpenShell emits OCSF 1.8.0" + ); + } let managed_ssh_gateway_pod_selector = args .managed_ssh_gateway_pod_selector @@ -305,12 +306,10 @@ async fn main() -> Result<()> { supervisor_otlp_endpoint: args.otlp_endpoint.clone(), supervisor_otlp_agent_endpoint: args.otlp_agent_endpoint.clone(), supervisor_gateway_name: args.gateway_name.clone(), - supervisor_ocsf_export: args.otlp_ocsf_endpoint.clone().map(|endpoint| { - openshell_core::sandbox_env::OcsfOtlpExport { - endpoint, - schema_version: args.otlp_ocsf_schema_version.clone(), - } - }), + supervisor_ocsf_export: args + .otlp_ocsf_endpoint + .clone() + .map(|endpoint| openshell_core::sandbox_env::OcsfOtlpExport { endpoint }), ssh_socket_path: args.sandbox_ssh_socket_path, client_tls_secret_name: args.client_tls_secret_name.unwrap_or_default(), host_gateway_ip: args.host_gateway_ip.unwrap_or_default(), diff --git a/crates/openshell-driver-podman/src/container.rs b/crates/openshell-driver-podman/src/container.rs index 7964485d6..a63c58d5f 100644 --- a/crates/openshell-driver-podman/src/container.rs +++ b/crates/openshell-driver-podman/src/container.rs @@ -2928,7 +2928,6 @@ mod tests { let config = PodmanComputeConfig { supervisor_ocsf_export: Some(openshell_core::sandbox_env::OcsfOtlpExport { endpoint: "http://siem:4317".to_string(), - schema_version: Some("1.1".to_string()), }), ..test_config() }; @@ -2937,10 +2936,6 @@ mod tests { spec["env"][openshell_core::sandbox_env::OTLP_OCSF_ENDPOINT], "http://siem:4317" ); - assert_eq!( - spec["env"][openshell_core::sandbox_env::OTLP_OCSF_SCHEMA_VERSION], - "1.1" - ); assert!( spec["env"] .get(openshell_core::sandbox_env::OTLP_AGENT_ENDPOINT) diff --git a/crates/openshell-driver-podman/src/driver.rs b/crates/openshell-driver-podman/src/driver.rs index fb0ff3181..00eb79c0d 100644 --- a/crates/openshell-driver-podman/src/driver.rs +++ b/crates/openshell-driver-podman/src/driver.rs @@ -109,7 +109,6 @@ fn select_supervisor_ocsf_export( config.supervisor_ocsf_export.clone().map(|export| { openshell_core::sandbox_env::OcsfOtlpExport { endpoint: supervisor_collector_endpoint(&export.endpoint, environment), - ..export } }) } @@ -3575,7 +3574,6 @@ mod tests { fn supervisor_ocsf_endpoint_uses_host_alias_for_loopback_on_podman_machine() { let export = |endpoint: &str| openshell_core::sandbox_env::OcsfOtlpExport { endpoint: endpoint.to_string(), - schema_version: Some("1.3".to_string()), }; let config = PodmanComputeConfig { supervisor_ocsf_export: Some(export("http://127.0.0.1:4317")), diff --git a/crates/openshell-driver-podman/src/main.rs b/crates/openshell-driver-podman/src/main.rs index 8d22241a7..2d510e465 100644 --- a/crates/openshell-driver-podman/src/main.rs +++ b/crates/openshell-driver-podman/src/main.rs @@ -46,12 +46,8 @@ struct Args { #[arg(long, env = "OPENSHELL_OTLP_OCSF_ENDPOINT")] otlp_ocsf_endpoint: Option, - /// OCSF schema version that supervisors downgrade exported events to. - #[arg( - long, - env = "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION", - requires = "otlp_ocsf_endpoint" - )] + /// Deprecated and ignored: `OpenShell` emits OCSF 1.8.0 only. + #[arg(long, env = "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION", hide = true)] otlp_ocsf_schema_version: Option, /// OTLP/gRPC collector endpoint that supervisors relay workload traces @@ -231,6 +227,11 @@ async fn main() -> Result<()> { log_level: &args.log_level, }, ); + if args.otlp_ocsf_schema_version.is_some() { + tracing::warn!( + "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION is deprecated and ignored; OpenShell emits OCSF 1.8.0" + ); + } // External drivers have no gateway-local staged artifact. Do not accept // a path or silently emulate destination-CA delivery outside the gateway. @@ -245,12 +246,10 @@ async fn main() -> Result<()> { supervisor_otlp_endpoint: args.otlp_endpoint.clone(), supervisor_otlp_agent_endpoint: args.otlp_agent_endpoint.clone(), supervisor_gateway_name: args.gateway_name.clone(), - supervisor_ocsf_export: args.otlp_ocsf_endpoint.clone().map(|endpoint| { - openshell_core::sandbox_env::OcsfOtlpExport { - endpoint, - schema_version: args.otlp_ocsf_schema_version.clone(), - } - }), + supervisor_ocsf_export: args + .otlp_ocsf_endpoint + .clone() + .map(|endpoint| openshell_core::sandbox_env::OcsfOtlpExport { endpoint }), gateway_port: args.gateway_port, host_gateway_ip: args .host_gateway_ip diff --git a/crates/openshell-driver-vm/src/main.rs b/crates/openshell-driver-vm/src/main.rs index cba0caf12..0ab474377 100644 --- a/crates/openshell-driver-vm/src/main.rs +++ b/crates/openshell-driver-vm/src/main.rs @@ -104,12 +104,8 @@ struct Args { #[arg(long, env = "OPENSHELL_OTLP_OCSF_ENDPOINT")] otlp_ocsf_endpoint: Option, - /// OCSF schema version that supervisors downgrade exported events to. - #[arg( - long, - env = "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION", - requires = "otlp_ocsf_endpoint" - )] + /// Deprecated and ignored: `OpenShell` emits OCSF 1.8.0 only. + #[arg(long, env = "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION", hide = true)] otlp_ocsf_schema_version: Option, /// OTLP/gRPC collector endpoint that supervisors relay workload traces @@ -318,6 +314,11 @@ async fn main() -> Result<()> { log_level: &args.log_level, }, ); + if args.otlp_ocsf_schema_version.is_some() { + tracing::warn!( + "OPENSHELL_OTLP_OCSF_SCHEMA_VERSION is deprecated and ignored; OpenShell emits OCSF 1.8.0" + ); + } let listen_mode = compute_driver_listen_mode(&args).map_err(|err| miette::miette!("{err}"))?; @@ -342,12 +343,10 @@ async fn main() -> Result<()> { supervisor_otlp_endpoint: args.otlp_endpoint.clone(), supervisor_otlp_agent_endpoint: args.otlp_agent_endpoint.clone(), supervisor_gateway_name: args.gateway_name.clone(), - supervisor_ocsf_export: args.otlp_ocsf_endpoint.clone().map(|endpoint| { - openshell_core::sandbox_env::OcsfOtlpExport { - endpoint, - schema_version: args.otlp_ocsf_schema_version.clone(), - } - }), + supervisor_ocsf_export: args + .otlp_ocsf_endpoint + .clone() + .map(|endpoint| openshell_core::sandbox_env::OcsfOtlpExport { endpoint }), state_dir: args.state_dir.clone(), launcher_bin: None, default_image: args.default_image.clone(), diff --git a/crates/openshell-gateway/src/lib.rs b/crates/openshell-gateway/src/lib.rs index a6a50774b..5dd475a7e 100644 --- a/crates/openshell-gateway/src/lib.rs +++ b/crates/openshell-gateway/src/lib.rs @@ -58,9 +58,6 @@ fn supervisor_ocsf_export( let ocsf = otlp?.ocsf.as_ref()?; Some(openshell_core::sandbox_env::OcsfOtlpExport { endpoint: ocsf.endpoint.clone(), - schema_version: ocsf - .schema_version - .map(|version| version.as_str().to_string()), }) } diff --git a/crates/openshell-gateway/src/vm.rs b/crates/openshell-gateway/src/vm.rs index 2cf677d1d..2f9ea5cc8 100644 --- a/crates/openshell-gateway/src/vm.rs +++ b/crates/openshell-gateway/src/vm.rs @@ -696,11 +696,6 @@ fn append_otlp_args(command: &mut Command, otlp_config: Option<&OtlpConfig>, gat } if let Some(ocsf) = ocsf { command.arg("--otlp-ocsf-endpoint").arg(&ocsf.endpoint); - if let Some(version) = ocsf.schema_version { - command - .arg("--otlp-ocsf-schema-version") - .arg(version.as_str()); - } } let agent_endpoint = otlp_config.and_then(OtlpConfig::agent_endpoint); if let Some(endpoint) = agent_endpoint { @@ -808,9 +803,7 @@ mod tests { validate_vm_sandbox_identity, }; use openshell_core::{NetworkSupervisorTrustBundle, UpstreamProxyConfig}; - use openshell_server::config_file::{ - OcsfOtlpConfig, OcsfSchemaVersion, OtlpConfig, OtlpTracesConfig, - }; + use openshell_server::config_file::{OcsfOtlpConfig, OtlpConfig, OtlpTracesConfig}; use std::os::unix::fs::PermissionsExt; use std::os::unix::net::UnixListener as StdUnixListener; use std::path::PathBuf; @@ -894,7 +887,7 @@ mod tests { traces: None, ocsf: Some(OcsfOtlpConfig { endpoint: "http://siem.internal:4317".to_string(), - schema_version: Some(OcsfSchemaVersion::V1_3), + schema_version: None, }), agent: None, }), @@ -911,8 +904,6 @@ mod tests { [ "--otlp-ocsf-endpoint", "http://siem.internal:4317", - "--otlp-ocsf-schema-version", - "1.3", "--gateway-name", "production-us-west" ] diff --git a/crates/openshell-ocsf-validate/src/lib.rs b/crates/openshell-ocsf-validate/src/lib.rs index b867ca361..7c6d7bf49 100644 --- a/crates/openshell-ocsf-validate/src/lib.rs +++ b/crates/openshell-ocsf-validate/src/lib.rs @@ -379,9 +379,9 @@ mod tests { #[test] fn rejects_versions_without_vendored_schemas() { let mut event = base_event(); - event["metadata"]["version"] = json!("1.1.0"); + event["metadata"]["version"] = json!("2.0.0"); assert!( - matches!(validate_event(&event), Err(Error::UnsupportedVersion(found)) if found == "1.1.0") + matches!(validate_event(&event), Err(Error::UnsupportedVersion(found)) if found == "2.0.0") ); } diff --git a/crates/openshell-ocsf/src/format/downgrade.rs b/crates/openshell-ocsf/src/format/downgrade.rs deleted file mode 100644 index 06bd4edd2..000000000 --- a/crates/openshell-ocsf/src/format/downgrade.rs +++ /dev/null @@ -1,290 +0,0 @@ -// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. -// SPDX-License-Identifier: Apache-2.0 - -//! OCSF schema version downgrade filter. -//! -//! Transforms serialized OCSF JSON events to conform to older schema versions -//! by stripping fields and profiles that don't exist in the target version. - -use serde::{Deserialize, Serialize}; -use serde_json::Value; - -/// An older OCSF schema version that events can be downgraded to. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] -pub enum OcsfSchemaVersion { - #[serde(rename = "1.1")] - V1_1, - #[serde(rename = "1.3")] - V1_3, -} - -impl OcsfSchemaVersion { - pub const fn as_str(self) -> &'static str { - match self { - Self::V1_1 => "1.1", - Self::V1_3 => "1.3", - } - } -} - -impl std::str::FromStr for OcsfSchemaVersion { - type Err = String; - - fn from_str(version: &str) -> Result { - match version { - "1.1" => Ok(Self::V1_1), - "1.3" => Ok(Self::V1_3), - other => Err(format!( - "unsupported OCSF schema version {other:?}; expected 1.1 or 1.3" - )), - } - } -} - -/// Fields to strip when downgrading to v1.3.0 or earlier. -const STRIP_FOR_V1_3: &[&str] = &["ai_model", "container", "observation_point_id"]; - -/// Profile names to remove from `metadata.profiles` when downgrading to v1.3.0 or earlier. -const STRIP_PROFILES_V1_3: &[&str] = &["ai_operation", "container"]; - -/// Downgrade a serialized OCSF event to the target schema version. -/// -/// Modifies the JSON in place: strips fields that don't exist in the target -/// version, removes unknown profile names from `metadata.profiles`, and -/// rewrites `metadata.version` to match. -/// -/// Returns `true` if the event was modified, `false` if no changes were needed -/// (target is current version or newer). -pub fn downgrade_event(event: &mut Value, target_version: &str) -> bool { - let target = parse_version(target_version); - let v1_3 = (1, 3, 0); - - if target >= parse_version(crate::OCSF_VERSION) { - return false; - } - - let Some(obj) = event.as_object_mut() else { - return false; - }; - - let mut modified = false; - - if target <= v1_3 { - for field in STRIP_FOR_V1_3 { - if obj.remove(*field).is_some() { - modified = true; - } - } - - if let Some(profiles) = obj - .get_mut("metadata") - .and_then(Value::as_object_mut) - .and_then(|m| m.get_mut("profiles")) - .and_then(Value::as_array_mut) - { - let before = profiles.len(); - profiles.retain(|p| !p.as_str().is_some_and(|s| STRIP_PROFILES_V1_3.contains(&s))); - if profiles.len() != before { - modified = true; - } - } - } - - if let Some(metadata) = obj.get_mut("metadata").and_then(Value::as_object_mut) { - let original_version = metadata - .get("version") - .and_then(Value::as_str) - .unwrap_or(crate::OCSF_VERSION) - .to_string(); - metadata.insert( - "version".to_string(), - Value::String(target_version.to_string()), - ); - modified = true; - - let unmapped = obj - .entry("unmapped") - .or_insert_with(|| Value::Object(serde_json::Map::new())); - if let Some(u) = unmapped.as_object_mut() { - u.insert( - "downgraded_from".to_string(), - Value::String(original_version), - ); - } - } - - modified -} - -fn parse_version(v: &str) -> (u32, u32, u32) { - let parts: Vec = v.split('.').filter_map(|s| s.parse().ok()).collect(); - ( - parts.first().copied().unwrap_or(0), - parts.get(1).copied().unwrap_or(0), - parts.get(2).copied().unwrap_or(0), - ) -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn schema_versions_parse_from_their_names() { - for version in [OcsfSchemaVersion::V1_1, OcsfSchemaVersion::V1_3] { - assert_eq!(version.as_str().parse(), Ok(version)); - } - assert!("1.6".parse::().is_err()); - assert!("".parse::().is_err()); - } - - fn test_event() -> Value { - serde_json::json!({ - "class_uid": 4002, - "class_name": "HTTP Activity", - "time": 1_234_567_890, - "severity_id": 1, - "metadata": { - "version": crate::OCSF_VERSION, - "profiles": ["security_control", "network_proxy", "container", "host"] - }, - "device": {"hostname": "sandbox-1"}, - "container": {"name": "test-sandbox"}, - "observation_point_id": 2, - "unmapped": {"key": "value"} - }) - } - - #[test] - fn test_downgrade_to_v1_3_strips_fields() { - let mut event = test_event(); - let modified = downgrade_event(&mut event, "1.3.0"); - - assert!(modified); - assert!(event.get("container").is_none()); - assert!(event.get("observation_point_id").is_none()); - assert!(event.get("device").is_some()); - assert!(event.get("unmapped").is_some()); - } - - #[test] - fn test_downgrade_to_v1_1_strips_fields() { - let mut event = test_event(); - let modified = downgrade_event(&mut event, "1.1.0"); - - assert!(modified); - assert!(event.get("container").is_none()); - assert!(event.get("observation_point_id").is_none()); - } - - #[test] - fn test_downgrade_strips_profiles() { - let mut event = test_event(); - downgrade_event(&mut event, "1.3.0"); - - let profiles = event["metadata"]["profiles"].as_array().unwrap(); - assert!(!profiles.iter().any(|p| p == "container")); - assert!(profiles.iter().any(|p| p == "security_control")); - assert!(profiles.iter().any(|p| p == "host")); - } - - #[test] - fn test_downgrade_rewrites_version() { - let mut event = test_event(); - downgrade_event(&mut event, "1.1.0"); - - assert_eq!(event["metadata"]["version"], "1.1.0"); - assert_eq!(event["unmapped"]["downgraded_from"], crate::OCSF_VERSION); - } - - #[test] - fn test_no_downgrade_for_current_version() { - let mut event = test_event(); - let modified = downgrade_event(&mut event, crate::OCSF_VERSION); - - assert!(!modified); - assert_eq!(event["metadata"]["version"], crate::OCSF_VERSION); - } - - #[test] - fn test_no_downgrade_for_newer_version() { - let mut event = test_event(); - let modified = downgrade_event(&mut event, "1.9.0"); - - assert!(!modified); - } - - #[test] - fn test_downgrade_strips_ai_model_when_present() { - let mut event = serde_json::json!({ - "class_uid": 6003, - "metadata": { - "version": "1.8.0", - "profiles": ["container", "host", "ai_operation"] - }, - "ai_model": {"name": "claude-3-haiku", "ai_provider": "anthropic"}, - "unmapped": {"latency_ms": 701} - }); - let modified = downgrade_event(&mut event, "1.3.0"); - - assert!(modified); - assert!(event.get("ai_model").is_none()); - assert!( - !event["metadata"]["profiles"] - .as_array() - .unwrap() - .iter() - .any(|p| p == "ai_operation") - ); - assert_eq!(event["metadata"]["version"], "1.3.0"); - assert_eq!(event["unmapped"]["downgraded_from"], "1.8.0"); - assert_eq!(event["unmapped"]["latency_ms"], 701); - } - - #[test] - fn test_downgrade_creates_unmapped_when_absent() { - let mut event = serde_json::json!({ - "class_uid": 4001, - "metadata": { - "version": crate::OCSF_VERSION, - "profiles": ["container"] - }, - "container": {"name": "sandbox-1"} - }); - let modified = downgrade_event(&mut event, "1.1.0"); - - assert!(modified); - assert_eq!(event["unmapped"]["downgraded_from"], crate::OCSF_VERSION); - } - - #[test] - fn test_downgrade_rewrites_version_without_strippable_fields() { - let mut event = serde_json::json!({ - "class_uid": 0, - "metadata": { - "version": crate::OCSF_VERSION, - "profiles": ["host"] - } - }); - - let modified = downgrade_event(&mut event, "1.3.0"); - - assert!(modified); - assert_eq!(event["metadata"]["version"], "1.3.0"); - assert_eq!(event["unmapped"]["downgraded_from"], crate::OCSF_VERSION); - } - - #[test] - fn test_no_downgrade_omits_breadcrumb() { - let mut event = test_event(); - downgrade_event(&mut event, crate::OCSF_VERSION); - - assert!( - event - .get("unmapped") - .and_then(Value::as_object) - .and_then(|u| u.get("downgraded_from")) - .is_none() - ); - } -} diff --git a/crates/openshell-ocsf/src/format/mod.rs b/crates/openshell-ocsf/src/format/mod.rs index 17518a561..084a013d9 100644 --- a/crates/openshell-ocsf/src/format/mod.rs +++ b/crates/openshell-ocsf/src/format/mod.rs @@ -3,6 +3,5 @@ //! OCSF event formatters: shorthand (human-readable) and JSONL. -pub mod downgrade; pub mod jsonl; pub mod shorthand; diff --git a/crates/openshell-ocsf/src/lib.rs b/crates/openshell-ocsf/src/lib.rs index 569e1bd1d..661b4c6f5 100644 --- a/crates/openshell-ocsf/src/lib.rs +++ b/crates/openshell-ocsf/src/lib.rs @@ -60,8 +60,6 @@ pub use objects::{ // --- Sanitizers --- pub use sanitize::sanitize_reason_for_audit; -pub use format::downgrade::OcsfSchemaVersion; - // --- Builders --- pub use builders::{ ApiActivityBuilder, AppLifecycleBuilder, AuthenticationBuilder, BaseEventBuilder, diff --git a/crates/openshell-ocsf/src/tracing_layers/jsonl_layer.rs b/crates/openshell-ocsf/src/tracing_layers/jsonl_layer.rs index 40484ce43..245f92e59 100644 --- a/crates/openshell-ocsf/src/tracing_layers/jsonl_layer.rs +++ b/crates/openshell-ocsf/src/tracing_layers/jsonl_layer.rs @@ -13,18 +13,15 @@ use tracing::Subscriber; use tracing_subscriber::Layer; use tracing_subscriber::layer::Context; -use crate::format::downgrade::downgrade_event; use crate::tracing_layers::event_bridge::{OCSF_TARGET, clone_current_event}; /// OCSF JSON output settings owned by one hosted sandbox instance. /// -/// Instances apply their own `ocsf_json_enabled` and schema-version settings -/// to these values. Binding them to the instance's runtime threads makes every +/// Instances apply their own `ocsf_json_enabled` setting to this value. Binding them to the instance's runtime threads makes every /// [`OcsfJsonlLayer`] use them for events those threads emit. #[derive(Clone, Debug, Default)] pub struct OcsfJsonSettings { pub enabled: Arc, - pub target_version: Arc>, } std::thread_local! { @@ -47,15 +44,9 @@ pub fn bind_thread_json_settings(settings: Option) { /// `false`, the layer short-circuits without writing. This allows the sandbox /// to hot-toggle OCSF JSONL output at runtime via the `ocsf_json_enabled` /// setting without rebuilding the subscriber. -/// -/// An optional target schema version can be set via -/// [`with_target_version`](Self::with_target_version). When set, events are -/// downgraded to the target version before writing (stripping fields and -/// profiles that don't exist in older schema versions). pub struct OcsfJsonlLayer { writer: Mutex, enabled: Option>, - target_version: Option>>, console_format: bool, } @@ -66,7 +57,6 @@ impl OcsfJsonlLayer { Self { writer: Mutex::new(writer), enabled: None, - target_version: None, console_format: false, } } @@ -81,16 +71,6 @@ impl OcsfJsonlLayer { self } - /// Attach a shared target schema version for downgrade filtering. - /// - /// When set, events are downgraded to the target version before writing. - /// The version can be changed at runtime via the shared mutex. - #[must_use] - pub fn with_target_version(mut self, version: Arc>) -> Self { - self.target_version = Some(version); - self - } - /// Prefix each compact JSON record with a UTC timestamp and `OCSF-JSON`. /// /// Console collectors can match the marker and decode the remainder as @@ -114,10 +94,9 @@ where // A hosted sandbox instance's settings replace the process-wide ones. let instance = THREAD_JSON_SETTINGS.with(|current| current.borrow().clone()); - let (enabled, target_version) = instance.as_ref().map_or( - (self.enabled.as_ref(), self.target_version.as_ref()), - |settings| (Some(&settings.enabled), Some(&settings.target_version)), - ); + let enabled = instance + .as_ref() + .map_or(self.enabled.as_ref(), |settings| Some(&settings.enabled)); // If an enabled flag is set and it reads `false`, skip writing. if let Some(flag) = enabled @@ -129,26 +108,8 @@ where if let Some(ocsf_event) = clone_current_event() && let Ok(mut w) = self.writer.lock() { - let line = if let Some(target) = target_version - && let Ok(version) = target.lock() - && !version.is_empty() - { - let Ok(mut json) = serde_json::to_value(&ocsf_event) else { - return; - }; - downgrade_event(&mut json, &version); - match serde_json::to_string(&json) { - Ok(mut s) => { - s.push('\n'); - s - } - Err(_) => return, - } - } else { - match ocsf_event.to_json_line() { - Ok(l) => l, - Err(_) => return, - } + let Ok(line) = ocsf_event.to_json_line() else { + return; }; let line = if self.console_format { let ts = Utc::now().format("%Y-%m-%dT%H:%M:%S%.3fZ"); diff --git a/crates/openshell-ocsf/tests/console_output.rs b/crates/openshell-ocsf/tests/console_output.rs index 07fa1f31b..38249ff35 100644 --- a/crates/openshell-ocsf/tests/console_output.rs +++ b/crates/openshell-ocsf/tests/console_output.rs @@ -51,15 +51,13 @@ fn context() -> EventContext { } #[test] -fn console_json_toggles_and_downgrades_without_changing_event_identity() { +fn console_json_toggles_without_changing_event_identity() { let records = Records::default(); let enabled = Arc::new(AtomicBool::new(false)); - let version = Arc::new(Mutex::new(String::new())); let subscriber = tracing_subscriber::registry().with( OcsfJsonlLayer::new(records.clone()) .with_console_format() - .with_enabled_flag(enabled.clone()) - .with_target_version(version.clone()), + .with_enabled_flag(enabled.clone()), ); let event = NetworkActivityBuilder::new(&context()) .dst_endpoint(openshell_ocsf::Endpoint::from_domain("example.com", 443)) @@ -71,18 +69,12 @@ fn console_json_toggles_and_downgrades_without_changing_event_identity() { tracing::warn!("diagnostics are not JSON audit events"); enabled.store(true, Ordering::Relaxed); ocsf_emit!(event.clone()); - *version.lock().unwrap() = "1.3".to_string(); - ocsf_emit!(event.clone()); enabled.store(false, Ordering::Relaxed); ocsf_emit!(event); }); let records = records.0.lock().unwrap(); - assert_eq!(records.len(), 2); + assert_eq!(records.len(), 1); assert_eq!(payload(&records[0]), expected); - let downgraded = payload(&records[1]); - assert_eq!(downgraded["metadata"]["version"], "1.3"); - assert_eq!(downgraded["metadata"]["uid"], expected["metadata"]["uid"]); - assert_eq!(downgraded["message"], expected["message"]); } #[test] diff --git a/crates/openshell-otel/src/ocsf.rs b/crates/openshell-otel/src/ocsf.rs index 2dc33cee8..680b4c1e3 100644 --- a/crates/openshell-otel/src/ocsf.rs +++ b/crates/openshell-otel/src/ocsf.rs @@ -7,8 +7,7 @@ use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::{Arc, Mutex, PoisonError}; use std::time::{Duration, SystemTime}; -use openshell_ocsf::format::downgrade::downgrade_event; -use openshell_ocsf::{OCSF_TARGET, OcsfEvent, OcsfSchemaVersion, SeverityId, clone_current_event}; +use openshell_ocsf::{OCSF_TARGET, OcsfEvent, SeverityId, clone_current_event}; use opentelemetry::InstrumentationScope; use opentelemetry::logs::{AnyValue, LogRecord as _, Logger as _, LoggerProvider as _, Severity}; use opentelemetry_sdk::Resource; @@ -45,11 +44,7 @@ pub struct OcsfOtlp { impl OcsfOtlp { /// Start exporting through `exporter`. - pub fn start( - mut exporter: E, - resource: Resource, - schema_version: Option, - ) -> Self + pub fn start(mut exporter: E, resource: Resource) -> Self where E: LogExporter + 'static, { @@ -71,7 +66,6 @@ impl OcsfOtlp { layer: OcsfOtlpLayer { sender, logger, - schema_version, gap, pending_bytes, }, @@ -110,7 +104,6 @@ impl OcsfOtlp { pub struct OcsfOtlpLayer { sender: mpsc::Sender, logger: SdkLogger, - schema_version: Option, gap: Arc, pending_bytes: Arc, } @@ -123,8 +116,7 @@ impl Layer for OcsfOtlpLayer { let Some(event) = clone_current_event() else { return; }; - let Ok(record) = log_record(&self.logger, &event, self.schema_version, SystemTime::now()) - else { + let Ok(record) = log_record(&self.logger, &event, SystemTime::now()) else { self.gap.record_loss("serialization", 1); return; }; @@ -377,14 +369,11 @@ fn logger() -> SdkLogger { /// Map one OCSF event onto an OTLP log record. /// -/// The body is the OCSF JSON record, downgraded when a schema version is -/// configured. Attributes come from the event itself, so identifiers that a -/// downgrade strips, such as the sandbox container, remain available for -/// routing. +/// The body is the OCSF JSON record. Attributes repeat identifiers from the +/// event, such as the sandbox container, for routing. fn log_record( logger: &SdkLogger, event: &OcsfEvent, - schema_version: Option, observed: SystemTime, ) -> Result { let base = event.base(); @@ -410,14 +399,7 @@ fn log_record( record.add_attribute("openshell.sandbox.id", sandbox_id); } - let body = match schema_version { - None => serde_json::to_string(event)?, - Some(schema_version) => { - let mut body = serde_json::to_value(event)?; - downgrade_event(&mut body, schema_version.as_str()); - serde_json::to_string(&body)? - } - }; + let body = serde_json::to_string(event)?; record.set_body(AnyValue::String(body.into())); Ok(record) } @@ -491,29 +473,21 @@ mod tests { .map(|(_, value)| value.clone()) } - fn record(event: &OcsfEvent, schema_version: Option) -> SdkLogRecord { - log_record(&logger(), event, schema_version, SystemTime::UNIX_EPOCH).unwrap() + fn record(event: &OcsfEvent) -> SdkLogRecord { + log_record(&logger(), event, SystemTime::UNIX_EPOCH).unwrap() } #[test] fn body_is_the_native_ocsf_json_record() { let event = event("sandbox-1", SeverityId::Informational); - assert_eq!(body(&record(&event, None)), native(&event)); - } - - #[test] - fn body_follows_the_configured_schema_version() { - let event = event("sandbox-1", SeverityId::Informational); - let body = body(&record(&event, Some(OcsfSchemaVersion::V1_3))); - assert_eq!(body["metadata"]["version"], "1.3"); - assert!(body.get("container").is_none()); + assert_eq!(body(&record(&event)), native(&event)); } #[test] fn timestamps_are_event_time_and_observed_time() { let event = event("sandbox-1", SeverityId::Informational); let observed = SystemTime::UNIX_EPOCH + Duration::from_secs(42); - let record = log_record(&logger(), &event, None, observed).unwrap(); + let record = log_record(&logger(), &event, observed).unwrap(); let time_ms = native(&event)["time"].as_u64().unwrap(); assert_eq!( record.timestamp(), @@ -534,7 +508,7 @@ mod tests { (SeverityId::Fatal, Severity::Fatal), (SeverityId::Other, Severity::Info), ] { - let record = record(&event("", severity), None); + let record = record(&event("", severity)); assert_eq!(record.severity_number(), Some(number), "{severity:?}"); assert_eq!(record.severity_text(), Some(severity.label())); } @@ -544,8 +518,7 @@ mod tests { fn attributes_identify_the_event_and_its_sandbox() { let event = event("sandbox-1", SeverityId::Medium); let native = native(&event); - // The sandbox identity survives a downgrade that strips `container`. - let record = record(&event, Some(OcsfSchemaVersion::V1_1)); + let record = record(&event); let int = |key| match attribute(&record, key) { Some(AnyValue::Int(value)) => value, other => panic!("{key}: {other:?}"), @@ -574,7 +547,7 @@ mod tests { #[test] fn events_without_a_sandbox_carry_no_sandbox_attribute() { - let record = record(&event("", SeverityId::Informational), None); + let record = record(&event("", SeverityId::Informational)); assert!(attribute(&record, "openshell.sandbox.id").is_none()); } @@ -696,7 +669,7 @@ mod tests { #[tokio::test] async fn emitted_ocsf_events_reach_the_exporter_with_its_resource() { let exporter = RecordingExporter::default(); - let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource(), None); + let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource()); let subscriber = tracing_subscriber::registry().with(otlp.layer()); let event = event("sandbox-1", SeverityId::Medium); let expected = native(&event); @@ -716,7 +689,7 @@ mod tests { #[tokio::test] async fn shutdown_exports_every_queued_record_in_bounded_batches() { let exporter = RecordingExporter::default(); - let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource(), None); + let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource()); emit(&otlp, BATCH_SIZE * 2 + 1); otlp.shutdown().await; assert_eq!(exporter.exported().len(), BATCH_SIZE * 2 + 1); @@ -734,7 +707,7 @@ mod tests { #[tokio::test(start_paused = true)] async fn transient_export_failures_are_retried_without_loss() { let exporter = RecordingExporter::failing(MAX_EXPORT_ATTEMPTS - 1); - let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource(), None); + let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource()); emit(&otlp, 3); settle().await; otlp.shutdown().await; @@ -748,7 +721,7 @@ mod tests { #[tokio::test(start_paused = true)] async fn exhausted_retries_drop_the_batch_and_report_the_gap_next() { let exporter = RecordingExporter::failing(MAX_EXPORT_ATTEMPTS); - let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource(), None); + let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource()); emit(&otlp, 3); settle().await; emit(&otlp, 1); @@ -778,7 +751,7 @@ mod tests { #[tokio::test(start_paused = true)] async fn batches_stay_within_the_byte_limit() { let exporter = RecordingExporter::default(); - let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource(), None); + let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource()); emit_sized(&otlp, 5, BATCH_MAX_BYTES * 2 / 5); settle().await; let pending_bytes = Arc::clone(&otlp.layer.pending_bytes); @@ -797,7 +770,7 @@ mod tests { #[tokio::test(start_paused = true)] async fn records_larger_than_a_batch_are_dropped_and_reported() { let exporter = RecordingExporter::default(); - let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource(), None); + let otlp = OcsfOtlp::start(exporter.clone(), exporter_resource()); emit_sized(&otlp, 1, BATCH_MAX_BYTES); emit(&otlp, 1); settle().await; @@ -814,7 +787,7 @@ mod tests { #[tokio::test(start_paused = true)] async fn the_queue_rejects_records_beyond_its_byte_limit() { - let otlp = OcsfOtlp::start(HangingExporter::default(), exporter_resource(), None); + let otlp = OcsfOtlp::start(HangingExporter::default(), exporter_resource()); let events = QUEUE_MAX_BYTES / (BATCH_MAX_BYTES / 2) + 4; emit_sized(&otlp, events, BATCH_MAX_BYTES / 2); @@ -841,7 +814,7 @@ mod tests { async fn shutdown_stops_a_worker_that_outlasts_the_budget() { let exporter = HangingExporter::default(); let alive = Arc::clone(&exporter.alive); - let otlp = OcsfOtlp::start(exporter, exporter_resource(), None); + let otlp = OcsfOtlp::start(exporter, exporter_resource()); emit(&otlp, 1); settle().await; otlp.shutdown().await; diff --git a/crates/openshell-server/src/cli.rs b/crates/openshell-server/src/cli.rs index 9b16b5391..035b3bcda 100644 --- a/crates/openshell-server/src/cli.rs +++ b/crates/openshell-server/src/cli.rs @@ -793,6 +793,13 @@ async fn run_from_args( if prepared.legacy_compute_driver_env_seen { warn!("OPENSHELL_DRIVERS is deprecated; migrate to OPENSHELL_COMPUTE_DRIVER"); } + for field in prepared + .config_file + .iter() + .flat_map(ConfigFile::deprecated_ocsf_schema_versions) + { + warn!("{field} is deprecated and ignored; OpenShell emits OCSF 1.8.0"); + } if let Some(bundle) = prepared.network_trust.as_ref() { info!( certificate_count = bundle.certificate_count(), diff --git a/crates/openshell-server/src/config_file.rs b/crates/openshell-server/src/config_file.rs index cee598a99..a01b3c119 100644 --- a/crates/openshell-server/src/config_file.rs +++ b/crates/openshell-server/src/config_file.rs @@ -261,14 +261,13 @@ pub enum OcsfLogRotation { Daily, } -pub use openshell_ocsf::OcsfSchemaVersion; - #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(try_from = "RawOcsfLogConfig")] pub struct OcsfLogConfig { pub path: PathBuf, + /// Deprecated and ignored: `OpenShell` emits OCSF 1.8.0 only. #[serde(skip_serializing_if = "Option::is_none")] - pub schema_version: Option, + pub schema_version: Option, pub rotation: OcsfLogRotation, #[serde(skip_serializing_if = "Option::is_none")] pub max_files: Option, @@ -280,7 +279,7 @@ pub struct OcsfLogConfig { #[serde(deny_unknown_fields)] struct RawOcsfLogConfig { path: PathBuf, - schema_version: Option, + schema_version: Option, #[serde(default)] rotation: OcsfLogRotation, max_files: Option, @@ -402,9 +401,9 @@ pub struct OcsfOtlpConfig { /// OTLP/gRPC collector endpoint for OCSF log records. pub endpoint: String, - /// Optional OCSF downgrade target for exported log records. + /// Deprecated and ignored: `OpenShell` emits OCSF 1.8.0 only. #[serde(default, skip_serializing_if = "Option::is_none")] - pub schema_version: Option, + pub schema_version: Option, } /// `[openshell.gateway.otlp.agent]`. @@ -454,7 +453,7 @@ struct RawOcsfOtlp { #[serde(default)] endpoint: Option, #[serde(default)] - schema_version: Option, + schema_version: Option, } impl TryFrom for OtlpConfig { @@ -535,6 +534,28 @@ pub struct SupervisorNetworkFileSection { } impl ConfigFile { + /// Deprecated `schema_version` fields that are set; they are ignored. + pub fn deprecated_ocsf_schema_versions(&self) -> Vec<&'static str> { + let gateway = &self.openshell.gateway; + let mut set = Vec::new(); + if gateway + .ocsf_log + .as_ref() + .is_some_and(|ocsf| ocsf.schema_version.is_some()) + { + set.push("openshell.gateway.ocsf_log.schema_version"); + } + if gateway + .otlp + .as_ref() + .and_then(|otlp| otlp.ocsf.as_ref()) + .is_some_and(|ocsf| ocsf.schema_version.is_some()) + { + set.push("openshell.gateway.otlp.ocsf.schema_version"); + } + set + } + /// Resolve the selected driver's exact backend name without sandbox input. pub(crate) fn isolation_backend( &self, @@ -1389,20 +1410,40 @@ service_name = "openshell-gateway-dev" assert_eq!(config.queue_capacity.get(), 10_000); assert_eq!(config.queue_max_bytes.get(), 16 * 1024 * 1024); assert!(ConfigFile::default().openshell.gateway.ocsf_log.is_none()); + } + #[test] + fn names_the_deprecated_schema_versions_that_are_set() { + assert!( + ConfigFile::default() + .deprecated_ocsf_schema_versions() + .is_empty() + ); + let tmp = write_tmp( + "[openshell.gateway.ocsf_log]\npath = 'events.jsonl'\nschema_version = '1.3'\n\n\ + [openshell.gateway.otlp.ocsf]\nenabled = true\nendpoint = 'http://siem:4317'\nschema_version = '1.3'\n", + ); + assert_eq!( + load(tmp.path()).unwrap().deprecated_ocsf_schema_versions(), + [ + "openshell.gateway.ocsf_log.schema_version", + "openshell.gateway.otlp.ocsf.schema_version" + ] + ); + } + + #[test] + fn ocsf_log_accepts_the_deprecated_schema_version() { let tmp = write_tmp( "[openshell.gateway.ocsf_log]\npath = 'events.jsonl'\nschema_version = '1.3'\n", ); - assert_eq!( - load(tmp.path()) - .unwrap() - .openshell - .gateway - .ocsf_log - .unwrap() - .schema_version, - Some(OcsfSchemaVersion::V1_3) - ); + let config = load(tmp.path()) + .unwrap() + .openshell + .gateway + .ocsf_log + .unwrap(); + assert_eq!(config.schema_version.as_deref(), Some("1.3")); } #[test] @@ -1414,8 +1455,6 @@ service_name = "openshell-gateway-dev" "path = 'log'\nqueue_max_bytes = 0", "path = 'log'\nmax_files = 0", "path = 'log'\nrotation = 'hourly'", - "path = 'log'\nschema_version = ''", - "path = 'log'\nschema_version = '1.8'", "path = 'log'\nkind = 'jsonl'", "path = 'log'\nrotation = 'never'\nmax_files = 7", ] { @@ -1467,18 +1506,29 @@ service_name = "openshell-gateway-dev" let otlp = otlp( "[openshell.gateway.otlp]\nendpoint = 'http://shared:4317'\n\n\ [openshell.gateway.otlp.traces]\nendpoint = 'http://traces:4317'\n\n\ - [openshell.gateway.otlp.ocsf]\nenabled = true\nendpoint = 'http://siem:4317'\nschema_version = '1.1'\n", + [openshell.gateway.otlp.ocsf]\nenabled = true\nendpoint = 'http://siem:4317'\n", ); assert_eq!(otlp.traces_endpoint(), Some("http://traces:4317")); assert_eq!( otlp.ocsf, Some(OcsfOtlpConfig { endpoint: "http://siem:4317".into(), - schema_version: Some(OcsfSchemaVersion::V1_1), + schema_version: None, }) ); } + #[test] + fn otlp_ocsf_accepts_the_deprecated_schema_version() { + let otlp = otlp( + "[openshell.gateway.otlp.ocsf]\nenabled = true\nendpoint = 'http://siem:4317'\nschema_version = '1.3'\n", + ); + assert_eq!( + otlp.ocsf.and_then(|ocsf| ocsf.schema_version).as_deref(), + Some("1.3") + ); + } + #[test] fn otlp_ocsf_exports_without_traces() { let otlp = @@ -1546,7 +1596,7 @@ service_name = "openshell-gateway-dev" fn otlp_config_round_trips() { let tmp = write_tmp( "[openshell.gateway.otlp]\nendpoint = 'http://shared:4317'\nservice_name = 'gw'\n\n\ - [openshell.gateway.otlp.ocsf]\nenabled = true\nschema_version = '1.3'\n\n\ + [openshell.gateway.otlp.ocsf]\nenabled = true\n\n\ [openshell.gateway.otlp.agent]\nenabled = true\nendpoint = 'http://agents:4317'\n", ); let file = load(tmp.path()).unwrap(); @@ -1562,7 +1612,6 @@ service_name = "openshell-gateway-dev" "[openshell.gateway.otlp.traces]\n", "[openshell.gateway.otlp.ocsf]\n", "[openshell.gateway.otlp.ocsf]\nenabled = true\n", - "[openshell.gateway.otlp.ocsf]\nenabled = true\nendpoint = 'http://siem:4317'\nschema_version = '1.8'\n", "[openshell.gateway.otlp.ocsf]\nenabled = 'yes'\nendpoint = 'http://siem:4317'\n", "[openshell.gateway.otlp.metrics]\nendpoint = 'http://metrics:4317'\n", "[openshell.gateway.otlp]\nendpoint = 'http://127.0.0.1:4317'\nocsf_logs = true\n", diff --git a/crates/openshell-server/src/ocsf_log.rs b/crates/openshell-server/src/ocsf_log.rs index 8858c9c58..6ecf9a790 100644 --- a/crates/openshell-server/src/ocsf_log.rs +++ b/crates/openshell-server/src/ocsf_log.rs @@ -9,12 +9,12 @@ use std::sync::{Arc, Condvar, Mutex}; use std::time::{Duration, Instant}; use chrono::{DateTime, NaiveDate, Utc}; -use openshell_ocsf::{OcsfEvent, format::downgrade::downgrade_event}; +use openshell_ocsf::OcsfEvent; use tracing::{Event, Subscriber}; use tracing_subscriber::Layer; use tracing_subscriber::layer::Context; -use crate::config_file::{OcsfLogConfig, OcsfLogRotation, OcsfSchemaVersion}; +use crate::config_file::{OcsfLogConfig, OcsfLogRotation}; const BATCH_SIZE: usize = 100; const FLUSH_INTERVAL: Duration = Duration::from_millis(500); @@ -49,7 +49,7 @@ impl Collector { } pub(crate) fn collect(&self, event: &OcsfEvent) { - match serialize_event(event, self.0.config.schema_version) { + match event.to_json_line().map(String::into_bytes) { Ok(line) => { self.enqueue(line); } @@ -158,20 +158,6 @@ impl Collector { } } -fn serialize_event( - event: &OcsfEvent, - schema_version: Option, -) -> Result, serde_json::Error> { - let Some(schema_version) = schema_version else { - return event.to_json_line().map(String::into_bytes); - }; - let mut event = serde_json::to_value(event)?; - downgrade_event(&mut event, schema_version.as_str()); - let mut line = serde_json::to_vec(&event)?; - line.push(b'\n'); - Ok(line) -} - pub struct OcsfLog { collector: Collector, done: tokio::sync::oneshot::Receiver<()>, @@ -483,11 +469,11 @@ mod tests { } #[tokio::test] - async fn gateway_events_use_the_configured_schema_version() { + async fn deprecated_schema_version_is_ignored() { let directory = tempfile::tempdir().unwrap(); let path = directory.path().join("events.jsonl"); let mut settings = config(&path); - settings.schema_version = Some(OcsfSchemaVersion::V1_3); + settings.schema_version = Some("1.3".to_string()); let log = OcsfLog::start(settings).unwrap(); let event = ConfigStateChangeBuilder::new(&crate::gateway_ocsf::context("", "")) .message("Gateway configuration changed") @@ -498,11 +484,7 @@ mod tests { let event: serde_json::Value = serde_json::from_str(&std::fs::read_to_string(path).unwrap()).unwrap(); - assert_eq!(event["metadata"]["version"], "1.3"); - assert_eq!( - event["unmapped"]["downgraded_from"], - openshell_ocsf::OCSF_VERSION - ); + assert_eq!(event["metadata"]["version"], openshell_ocsf::OCSF_VERSION); } #[tokio::test] diff --git a/crates/openshell-server/src/otel_tracing.rs b/crates/openshell-server/src/otel_tracing.rs index 0d147c0e8..a50ba1e21 100644 --- a/crates/openshell-server/src/otel_tracing.rs +++ b/crates/openshell-server/src/otel_tracing.rs @@ -171,11 +171,7 @@ impl OtlpExport { let target = target(&ocsf.endpoint)?; Ok::<_, SetupError>(Signal { endpoint: target.endpoint().to_string(), - exporter: OcsfOtlp::start( - target.log_exporter()?, - target.resource().clone(), - ocsf.schema_version, - ), + exporter: OcsfOtlp::start(target.log_exporter()?, target.resource().clone()), }) }) .transpose()?; @@ -727,7 +723,6 @@ mod tests { .log_exporter_with_headers(Some("authorization=Bearer%20collector-token")) .unwrap(), target.resource().clone(), - None, ); let event = ConfigStateChangeBuilder::new(&crate::gateway_ocsf::context("sandbox-1", "sandbox")) diff --git a/crates/openshell-supervisor/src/config_runtime.rs b/crates/openshell-supervisor/src/config_runtime.rs index 1a83fd088..8ced34ffe 100644 --- a/crates/openshell-supervisor/src/config_runtime.rs +++ b/crates/openshell-supervisor/src/config_runtime.rs @@ -689,7 +689,7 @@ impl ConfigRuntime { // Apply OCSF JSON toggle from the `ocsf_json_enabled` setting. apply_ocsf_json_setting(&ctx.ocsf_enabled, &result.settings); - apply_ocsf_schema_version_setting(&ctx.ocsf_schema_version, &result.settings); + report_deprecated_ocsf_schema_version(&ctx.ocsf_schema_version, &result.settings); // Apply the agent-proposals feature toggle. On a false→true transition // we lazily install the skill so a sandbox that started with the flag @@ -1277,7 +1277,10 @@ async fn run_policy_poll_loop_with_client( runtime.applied_revision = Some(sandbox_config_revision(&result)); } apply_ocsf_json_setting(&ctx.ocsf_enabled, &result.settings); - apply_ocsf_schema_version_setting(&ctx.ocsf_schema_version, &result.settings); + report_deprecated_ocsf_schema_version( + &ctx.ocsf_schema_version, + &result.settings, + ); apply_agent_proposals_enabled( &ctx.agent_proposals, agent_proposals_enabled_from_settings(&result.settings), @@ -1316,7 +1319,10 @@ async fn run_policy_poll_loop_with_client( } (InitialPollDisposition::TrackOnly, _) => { apply_ocsf_json_setting(&ctx.ocsf_enabled, &result.settings); - apply_ocsf_schema_version_setting(&ctx.ocsf_schema_version, &result.settings); + report_deprecated_ocsf_schema_version( + &ctx.ocsf_schema_version, + &result.settings, + ); apply_agent_proposals_enabled( &ctx.agent_proposals, agent_proposals_enabled_from_settings(&result.settings), @@ -1465,20 +1471,33 @@ fn extract_bool_setting( }) } -fn apply_ocsf_schema_version_setting( - version: &std::sync::Mutex, +/// Report a newly set `ocsf_schema_version`, which is deprecated and ignored. +fn report_deprecated_ocsf_schema_version( + seen: &std::sync::Mutex, settings: &std::collections::HashMap, -) { - let new_version = extract_string_setting(settings, "ocsf_schema_version").unwrap_or_default(); - if let Ok(mut current) = version.lock() - && *current != new_version - { - info!( - ocsf_schema_version = %new_version, - "OCSF schema version target changed" - ); - *current = new_version; +) -> bool { + let value = extract_string_setting(settings, "ocsf_schema_version").unwrap_or_default(); + let Ok(mut seen) = seen.lock() else { + return false; + }; + if *seen == value { + return false; } + seen.clone_from(&value); + if value.is_empty() { + return false; + } + ocsf_emit!( + ConfigStateChangeBuilder::new(ocsf_ctx()) + .severity(SeverityId::Medium) + .state(StateId::Other, "deprecated") + .unmapped("ocsf_schema_version", serde_json::json!(value)) + .message( + "Setting ocsf_schema_version is deprecated and ignored; OpenShell emits OCSF 1.8.0" + ) + .build() + ); + true } /// Extract a string value from an effective setting, if present. @@ -1694,9 +1713,11 @@ mod tests { } #[test] - fn apply_ocsf_schema_version_setting_updates_from_initial_settings_snapshot() { - let version = std::sync::Mutex::new(String::new()); + fn deprecated_ocsf_schema_version_is_reported_once_per_change() { + let seen = std::sync::Mutex::new(String::new()); let mut settings = std::collections::HashMap::new(); + assert!(!report_deprecated_ocsf_schema_version(&seen, &settings)); + settings.insert( "ocsf_schema_version".to_string(), openshell_core::proto::EffectiveSetting { @@ -1708,20 +1729,11 @@ mod tests { scope: openshell_core::proto::SettingScope::Sandbox.into(), }, ); + assert!(report_deprecated_ocsf_schema_version(&seen, &settings)); + assert!(!report_deprecated_ocsf_schema_version(&seen, &settings)); - apply_ocsf_schema_version_setting(&version, &settings); - - assert_eq!(*version.lock().unwrap(), "1.3"); - } - - #[test] - fn apply_ocsf_schema_version_setting_clears_when_setting_is_unset() { - let version = std::sync::Mutex::new("1.1".to_string()); - let settings = std::collections::HashMap::new(); - - apply_ocsf_schema_version_setting(&version, &settings); - - assert_eq!(*version.lock().unwrap(), ""); + settings.clear(); + assert!(!report_deprecated_ocsf_schema_version(&seen, &settings)); } #[test] diff --git a/crates/openshell-supervisor/src/lib.rs b/crates/openshell-supervisor/src/lib.rs index dddf8990c..8b1035bec 100644 --- a/crates/openshell-supervisor/src/lib.rs +++ b/crates/openshell-supervisor/src/lib.rs @@ -1590,7 +1590,7 @@ pub async fn run_sandbox_instance( let poll_gateway = gateway.clone(); let poll_engine = engine.clone(); let poll_ocsf_enabled = ocsf_json.enabled.clone(); - let poll_ocsf_schema_version = ocsf_json.target_version.clone(); + let poll_ocsf_schema_version = Arc::new(std::sync::Mutex::new(String::new())); let poll_pid = entrypoint_pid.clone(); let poll_provider_credentials = provider_credentials.clone(); let poll_policy_local = networking.as_ref().map(|n| n.policy_local_ctx.clone()); @@ -4207,6 +4207,7 @@ struct PolicyPollLoopContext { entrypoint_pid: Arc, interval_secs: u64, ocsf_enabled: Arc, + /// Last value of the deprecated `ocsf_schema_version` setting. ocsf_schema_version: Arc>, provider_credentials: ProviderCredentialState, provider_readiness: ProviderReadinessTracker, diff --git a/crates/openshell-supervisor/src/logging.rs b/crates/openshell-supervisor/src/logging.rs index 89b313c3d..d75e6704f 100644 --- a/crates/openshell-supervisor/src/logging.rs +++ b/crates/openshell-supervisor/src/logging.rs @@ -6,7 +6,6 @@ use std::io::Write; use std::path::Path; use std::sync::Arc; -use std::sync::Mutex; use std::sync::atomic::AtomicBool; use openshell_ocsf::{OcsfJsonlLayer, OcsfShorthandLayer}; @@ -24,7 +23,6 @@ pub fn layers( directory: &Path, console_filter: EnvFilter, enabled: Arc, - schema_version: Arc>, ) -> (impl Layer, Vec, bool) where S: Subscriber + for<'a> LookupSpan<'a> + 'static, @@ -49,7 +47,6 @@ where let json_file = json_file.map(|writer| { OcsfJsonlLayer::new(writer) .with_enabled_flag(enabled.clone()) - .with_target_version(schema_version.clone()) .with_filter(LevelFilter::INFO) }); // Keep per-destination filters independent: a diagnostic filter must not @@ -61,7 +58,6 @@ where OcsfJsonlLayer::new(console) .with_console_format() .with_enabled_flag(enabled) - .with_target_version(schema_version) .with_filter(LevelFilter::INFO) .boxed(), shorthand_file.boxed(), @@ -92,6 +88,7 @@ fn file_writer( mod tests { use super::*; use openshell_ocsf::{EventContext, NetworkActivityBuilder, ocsf_emit}; + use std::sync::Mutex; use tracing_subscriber::layer::SubscriberExt; #[derive(Clone)] @@ -132,7 +129,6 @@ mod tests { &invalid_directory, EnvFilter::new("off"), Arc::new(AtomicBool::new(true)), - Arc::new(Mutex::new(String::new())), ); assert!(!file_available); let subscriber = tracing_subscriber::registry().with(layers); @@ -162,7 +158,6 @@ mod tests { directory.path(), EnvFilter::new("info"), Arc::new(AtomicBool::new(true)), - Arc::new(Mutex::new(String::new())), ); assert!(file_available); let subscriber = tracing_subscriber::registry().with(layers); @@ -244,7 +239,6 @@ mod tests { &invalid_directory, EnvFilter::new("info"), Arc::new(AtomicBool::new(false)), - Arc::new(Mutex::new(String::new())), ); let dispatch = tracing::Dispatch::new(tracing_subscriber::registry().with(layers)); tracing::dispatcher::with_default(&dispatch, || tracing::info!("occupy writer")); diff --git a/crates/openshell-supervisor/src/main.rs b/crates/openshell-supervisor/src/main.rs index be91a6455..7c35b9682 100644 --- a/crates/openshell-supervisor/src/main.rs +++ b/crates/openshell-supervisor/src/main.rs @@ -142,10 +142,6 @@ struct Args { #[arg(long, env = openshell_core::sandbox_env::OTLP_OCSF_ENDPOINT)] otlp_ocsf_endpoint: Option, - /// OCSF schema version that exported events are downgraded to. - #[arg(long, env = openshell_core::sandbox_env::OTLP_OCSF_SCHEMA_VERSION)] - otlp_ocsf_schema_version: Option, - /// OTLP/gRPC collector endpoint that workload traces are relayed to. /// Absent keeps the relay inactive. #[arg(long, env = openshell_core::sandbox_env::OTLP_AGENT_ENDPOINT)] @@ -496,7 +492,6 @@ fn main() -> Result<()> { start_ocsf_export( args.otlp_ocsf_endpoint.as_deref().map(export_config), ocsf_headers, - args.otlp_ocsf_schema_version, ) }); let otlp_layer_provider = otlp_provider.clone(); @@ -527,14 +522,12 @@ fn main() -> Result<()> { let push_layer = log_push_state.as_ref().map(|(layer, _)| layer.clone()); let _log_push_handle = log_push_state.map(|(_, handle)| handle); let ocsf_enabled = Arc::new(AtomicBool::new(false)); - let ocsf_schema_version = Arc::new(std::sync::Mutex::new(String::new())); let (logging_layers, _logging_guards, file_available) = logging::layers( std::io::stderr(), Path::new("/var/log"), console_filter, ocsf_enabled.clone(), - ocsf_schema_version.clone(), ); tracing_subscriber::registry() .with(logging_layers) @@ -642,7 +635,6 @@ fn main() -> Result<()> { gateway_credentials, openshell_ocsf::OcsfJsonSettings { enabled: ocsf_enabled, - target_version: ocsf_schema_version, }, ); let result = Box::pin(openshell_supervisor::run_sandbox_with_backend( @@ -695,7 +687,6 @@ fn main() -> Result<()> { fn start_ocsf_export( config: Option>, headers: Option<&str>, - schema_version: Option, ) -> ( Option, Option, @@ -707,7 +698,6 @@ fn start_ocsf_export( Ok(openshell_otel::OcsfOtlp::start( target.log_exporter_with_headers(headers)?, target.resource().clone(), - schema_version, )) }); match started { @@ -921,27 +911,6 @@ mod tests { assert!(supervisor_resource_attributes(None, None).is_empty()); } - #[test] - fn ocsf_export_takes_a_supported_schema_version() { - let args = Args::try_parse_from([ - "openshell-supervisor", - "--otlp-ocsf-endpoint", - "http://siem:4317", - "--otlp-ocsf-schema-version", - "1.3", - ]) - .expect("parse OCSF export"); - assert_eq!(args.otlp_ocsf_endpoint.as_deref(), Some("http://siem:4317")); - assert_eq!( - args.otlp_ocsf_schema_version, - Some(openshell_ocsf::OcsfSchemaVersion::V1_3) - ); - assert!( - Args::try_parse_from(["openshell-supervisor", "--otlp-ocsf-schema-version", "1.8"]) - .is_err() - ); - } - #[test] fn agent_relay_endpoint_is_separate_from_trace_export() { let args = Args::try_parse_from([ @@ -975,17 +944,16 @@ mod tests { service_version: None, resource_attributes: Vec::new(), }; - let (export, error) = start_ocsf_export(None, None, None); + let (export, error) = start_ocsf_export(None, None); assert!(export.is_none() && error.is_none()); - let (export, error) = start_ocsf_export(Some(config("not a url")), None, None); + let (export, error) = start_ocsf_export(Some(config("not a url")), None); assert!(export.is_none()); assert!(error.is_some()); let (export, error) = start_ocsf_export( Some(config("http://127.0.0.1:4317")), Some("authorization=Bearer%20t"), - None, ); assert!(error.is_none(), "unexpected setup error: {error:?}"); export.expect("OCSF export").shutdown().await; diff --git a/crates/openshell-supervisor/src/shared.rs b/crates/openshell-supervisor/src/shared.rs index 2f449327e..243f18165 100644 --- a/crates/openshell-supervisor/src/shared.rs +++ b/crates/openshell-supervisor/src/shared.rs @@ -94,7 +94,6 @@ from sandbox runtimes)", std::path::Path::new("/var/log"), console_filter, Arc::new(AtomicBool::new(false)), - Arc::new(std::sync::Mutex::new(String::new())), ); tracing_subscriber::registry() .with(logging_layers) diff --git a/deploy/helm/openshell/README.md b/deploy/helm/openshell/README.md index ff240bc77..df46e0a4a 100644 --- a/deploy/helm/openshell/README.md +++ b/deploy/helm/openshell/README.md @@ -646,7 +646,7 @@ discovery endpoint or its TLS CA. | server.ocsfLog.queueCapacity | int | `10000` | Maximum records waiting for the file writer. | | server.ocsfLog.queueMaxBytes | int | `16777216` | Maximum encoded bytes waiting for the file writer. | | server.ocsfLog.rotation | string | `"daily"` | Rotate the active file daily in UTC, or never. | -| server.ocsfLog.schemaVersion | string | `""` | Optional OCSF downgrade target. Empty emits native OCSF 1.8.0. Supported values: "1.1", "1.3". | +| server.ocsfLog.schemaVersion | string | `""` | Deprecated and ignored: the gateway emits native OCSF 1.8.0 and logs a warning at startup when this is set. | | server.oidc.adminRole | string | `""` | Role name for admin access. Leave empty (with userRole also empty) for authentication-only mode. Both must be set or both empty. | | server.oidc.audience | string | `"openshell-cli"` | Expected audience claim for the API resource server. This should match the server's --oidc-audience, NOT the CLI client ID. | | server.oidc.caConfigMapName | string | `""` | Name of a ConfigMap containing a CA certificate bundle (key: ca.crt) for verifying the OIDC issuer's TLS certificate. Required when the issuer uses a non-public CA (e.g. OpenShift ingress, private PKI). | diff --git a/deploy/helm/openshell/templates/_toml.tpl b/deploy/helm/openshell/templates/_toml.tpl index cf8bf6120..cc79d51d7 100644 --- a/deploy/helm/openshell/templates/_toml.tpl +++ b/deploy/helm/openshell/templates/_toml.tpl @@ -183,7 +183,7 @@ Top-level lists represent TOML arrays of tables and preserve their YAML order. * {{- if not (hasKey $ocsfConfig "rotation") -}}{{- $rotation := get $legacyOcsf "rotation" | default "daily" -}}{{- if not (has $rotation (list "daily" "never")) -}}{{- fail "server.ocsfLog.rotation must be daily or never" -}}{{- end -}}{{- $_ := set $ocsfConfig "rotation" $rotation -}}{{- end -}} {{- if not (hasKey $ocsfConfig "queue_capacity") -}}{{- $queueCapacity := 10000 -}}{{- if and (hasKey $legacyOcsf "queueCapacity") (ne (get $legacyOcsf "queueCapacity") nil) -}}{{- $queueCapacity = get $legacyOcsf "queueCapacity" -}}{{- end -}}{{- if lt (int $queueCapacity) 1 -}}{{- fail "server.ocsfLog.queueCapacity and queueMaxBytes must be positive" -}}{{- end -}}{{- $_ := set $ocsfConfig "queue_capacity" (int $queueCapacity) -}}{{- end -}} {{- if not (hasKey $ocsfConfig "queue_max_bytes") -}}{{- $queueMaxBytes := 16777216 -}}{{- if and (hasKey $legacyOcsf "queueMaxBytes") (ne (get $legacyOcsf "queueMaxBytes") nil) -}}{{- $queueMaxBytes = get $legacyOcsf "queueMaxBytes" -}}{{- end -}}{{- if lt (int $queueMaxBytes) 1 -}}{{- fail "server.ocsfLog.queueCapacity and queueMaxBytes must be positive" -}}{{- end -}}{{- $_ := set $ocsfConfig "queue_max_bytes" (int $queueMaxBytes) -}}{{- end -}} -{{- if not (hasKey $ocsfConfig "schema_version") -}}{{- $schemaVersion := get $legacyOcsf "schemaVersion" | default "" -}}{{- if not (has $schemaVersion (list "" "1.1" "1.3")) -}}{{- fail "server.ocsfLog.schemaVersion must be empty, 1.1, or 1.3" -}}{{- end -}}{{- if $schemaVersion -}}{{- $_ := set $ocsfConfig "schema_version" $schemaVersion -}}{{- end -}}{{- end -}} +{{- if not (hasKey $ocsfConfig "schema_version") -}}{{- $schemaVersion := get $legacyOcsf "schemaVersion" | default "" -}}{{- if $schemaVersion -}}{{- $_ := set $ocsfConfig "schema_version" (toString $schemaVersion) -}}{{- end -}}{{- end -}} {{- if and (eq (get $ocsfConfig "rotation") "daily") (not (hasKey $ocsfConfig "max_files")) -}}{{- $maxFiles := 7 -}}{{- if and (hasKey $legacyOcsf "maxFiles") (ne (get $legacyOcsf "maxFiles") nil) -}}{{- $maxFiles = get $legacyOcsf "maxFiles" -}}{{- end -}}{{- if lt (int $maxFiles) 1 -}}{{- fail "server.ocsfLog.maxFiles must be positive when rotation is daily" -}}{{- end -}}{{- $_ := set $ocsfConfig "max_files" (int $maxFiles) -}}{{- end -}} {{- end -}} {{- $_ := set $config "openshell.gateway.ocsf_log" $ocsfConfig -}} diff --git a/deploy/helm/openshell/tests/gateway_config_test.yaml b/deploy/helm/openshell/tests/gateway_config_test.yaml index 16639d892..f298fe93b 100644 --- a/deploy/helm/openshell/tests/gateway_config_test.yaml +++ b/deploy/helm/openshell/tests/gateway_config_test.yaml @@ -341,11 +341,10 @@ tests: openshell.gateway.otlp.ocsf: enabled: true endpoint: http://siem-collector:4317 - schema_version: "1.3" asserts: - matchRegex: path: data["gateway.toml"] - pattern: '(?ms)\[openshell\.gateway\.otlp\.ocsf\]\nenabled\s*=\s*true\nendpoint\s*=\s*"http://siem-collector:4317"\nschema_version\s*=\s*"1\.3"' + pattern: '(?ms)\[openshell\.gateway\.otlp\.ocsf\]\nenabled\s*=\s*true\nendpoint\s*=\s*"http://siem-collector:4317"' - matchRegex: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\.otlp\.traces\]\nendpoint\s*=\s*"http://traces:4317"' @@ -440,7 +439,6 @@ tests: set: server.ocsfLog.enabled: true server.ocsfLog.path: /var/openshell/gateway-ocsf.jsonl - server.ocsfLog.schemaVersion: "1.3" server.ocsfLog.rotation: daily server.ocsfLog.maxFiles: 14 server.ocsfLog.queueCapacity: 20000 @@ -448,7 +446,7 @@ tests: asserts: - matchRegex: path: data["gateway.toml"] - pattern: '(?ms)\[openshell\.gateway\.ocsf_log\].*?max_files\s*=\s*14.*?path\s*=\s*"/var/openshell/gateway-ocsf\.jsonl".*?queue_capacity\s*=\s*20000.*?queue_max_bytes\s*=\s*33554432.*?rotation\s*=\s*"daily".*?schema_version\s*=\s*"1\.3"' + pattern: '(?ms)\[openshell\.gateway\.ocsf_log\].*?max_files\s*=\s*14.*?path\s*=\s*"/var/openshell/gateway-ocsf\.jsonl".*?queue_capacity\s*=\s*20000.*?queue_max_bytes\s*=\s*33554432.*?rotation\s*=\s*"daily"' - it: omits OCSF retention when rotation is disabled template: templates/gateway-config.yaml @@ -513,15 +511,16 @@ tests: path: data["gateway.toml"] pattern: '(?ms)\[openshell\.gateway\.ocsf_log\].*?max_files\s*=\s*7.*?queue_capacity\s*=\s*10000.*?queue_max_bytes\s*=\s*16777216' - - it: rejects an unsupported OCSF schema version - template: templates/statefulset.yaml + - it: passes the deprecated OCSF schema version through for the gateway to report + template: templates/gateway-config.yaml set: server.ocsfLog.enabled: true server.ocsfLog.path: /var/openshell/gateway-ocsf.jsonl - server.ocsfLog.schemaVersion: "1.8" + server.ocsfLog.schemaVersion: "1.3" asserts: - - failedTemplate: - errorMessage: "server.ocsfLog.schemaVersion must be empty, 1.1, or 1.3" + - matchRegex: + path: data["gateway.toml"] + pattern: '(?ms)\[openshell\.gateway\.ocsf_log\].*?schema_version\s*=\s*"1\.3"' - it: mounts extra gateway volumes for OCSF output in a Deployment template: templates/deployment.yaml diff --git a/deploy/helm/openshell/values.yaml b/deploy/helm/openshell/values.yaml index 3f6f0f86d..fa1519e02 100644 --- a/deploy/helm/openshell/values.yaml +++ b/deploy/helm/openshell/values.yaml @@ -406,8 +406,8 @@ server: # When replicas share the volume, set subPathExpr: $(OPENSHELL_POD_NAME) # on the mount so each replica writes its own file. path: /tmp/gateway-ocsf.jsonl - # -- Optional OCSF downgrade target. Empty emits native OCSF 1.8.0. - # Supported values: "1.1", "1.3". + # -- Deprecated and ignored: the gateway emits native OCSF 1.8.0 and logs + # a warning at startup when this is set. schemaVersion: "" # -- Rotate the active file daily in UTC, or never. rotation: daily diff --git a/docs/how-it-works/gateways/configuration.mdx b/docs/how-it-works/gateways/configuration.mdx index ef49f8ec8..715135e63 100644 --- a/docs/how-it-works/gateways/configuration.mdx +++ b/docs/how-it-works/gateways/configuration.mdx @@ -528,7 +528,6 @@ Gateway records use `[openshell.gateway] name` as `device.uid` and `device.name` ```toml [openshell.gateway.ocsf_log] path = "/var/log/openshell/gateway-ocsf.jsonl" -schema_version = "1.3" rotation = "daily" max_files = 7 queue_capacity = 10000 @@ -538,7 +537,7 @@ queue_max_bytes = 16777216 | Field | Default | Behavior | |---|---|---| | `path` | Required | Nonempty file path; relative paths use the gateway's working directory. | -| `schema_version` | Native OCSF 1.8.0 | Optional downgrade target. Accepted values are `1.1` and `1.3`. The configured version applies to every record in the file. | +| `schema_version` | None | Deprecated and ignored; records are native OCSF 1.8.0. The gateway logs a warning at startup when it is set. | | `rotation` | `daily` | Rotate on the first write of a new UTC day. `never` allows unbounded file growth. | | `max_files` | `7` | Positive number of rotated segments to retain, in addition to the active file. Rejects explicit use with `rotation = "never"`. | | `queue_capacity` | `10000` | Positive queued-record limit. Overflow discards incoming records. | @@ -546,7 +545,7 @@ queue_max_bytes = 16777216 Unknown fields are rejected. This is one file destination, not an exporter registry. To send the same events to a collector, use [OCSF log export](#ocsf-log-export). The existing `ocsf_json_enabled` sandbox setting remains independent. -For Helm installations, set `server.ocsfLog.enabled` to render this table and optionally set `server.ocsfLog.schemaVersion`. The default `server.ocsfLog.path`, `/tmp/gateway-ocsf.jsonl`, is writable in the gateway container with either the StatefulSet or Deployment workload but does not persist across pod restarts. To keep records, mount a volume with `server.extraVolumes` and `server.extraVolumeMounts` and set the path on it. When replicas share a volume, add `subPathExpr: $(OPENSHELL_POD_NAME)` to the mount so each replica writes its own file. +For Helm installations, set `server.ocsfLog.enabled` to render this table. The default `server.ocsfLog.path`, `/tmp/gateway-ocsf.jsonl`, is writable in the gateway container with either the StatefulSet or Deployment workload but does not persist across pod restarts. To keep records, mount a volume with `server.extraVolumes` and `server.extraVolumeMounts` and set the path on it. When replicas share a volume, add `subPathExpr: $(OPENSHELL_POD_NAME)` to the mount so each replica writes its own file. Give each gateway replica its own writable file and an external shipper read access to the containing directory. New files use owner-only permissions on Unix; arrange shipper access deliberately. Rotation renames the active file to a date- and UUID-suffixed sibling. The shipper must follow rotated files and checkpoint its progress. Do not use multiple writers or external copy-truncate rotation on this path. @@ -621,23 +620,24 @@ In-process compute drivers read their backend-specific settings from `[openshell ### OCSF Log Export -Set `enabled = true` in `[openshell.gateway.otlp.ocsf]` to export gateway OCSF events as OTLP log records. It defaults to `false`, so trace export alone never sends OCSF events. Records go to the table's `endpoint`, or to `[openshell.gateway.otlp]` `endpoint` when it is omitted, with the same resource attributes as spans, under the `openshell.ocsf` instrumentation scope. Use a separate endpoint to send OCSF events to a collector that feeds a SIEM while spans go elsewhere. Sandbox supervisors receive the same endpoint and schema version and export their own OCSF events there directly, so the endpoint must also be reachable from sandboxes. Supervisor records carry the supervisor's resource attributes, including `openshell.sandbox.id` and `openshell.gateway.name`. Supervisors also send the collector headers that the gateway uses for OCSF export, from `OTEL_EXPORTER_OTLP_LOGS_HEADERS` or else `OTEL_EXPORTER_OTLP_HEADERS`, so a collector that requires authentication accepts their records too. The gateway delivers the headers with each sandbox's launch credentials, never through the sandbox environment. Other `OTEL_*` variables do not reach supervisors. +Set `enabled = true` in `[openshell.gateway.otlp.ocsf]` to export gateway OCSF events as OTLP log records. It defaults to `false`, so trace export alone never sends OCSF events. Records go to the table's `endpoint`, or to `[openshell.gateway.otlp]` `endpoint` when it is omitted, with the same resource attributes as spans, under the `openshell.ocsf` instrumentation scope. Use a separate endpoint to send OCSF events to a collector that feeds a SIEM while spans go elsewhere. Sandbox supervisors receive the same endpoint and export their own OCSF events there directly, so the endpoint must also be reachable from sandboxes. Supervisor records carry the supervisor's resource attributes, including `openshell.sandbox.id` and `openshell.gateway.name`. Supervisors also send the collector headers that the gateway uses for OCSF export, from `OTEL_EXPORTER_OTLP_LOGS_HEADERS` or else `OTEL_EXPORTER_OTLP_HEADERS`, so a collector that requires authentication accepts their records too. The gateway delivers the headers with each sandbox's launch credentials, never through the sandbox environment. Other `OTEL_*` variables do not reach supervisors. ```toml [openshell.gateway.otlp.ocsf] enabled = true -endpoint = "http://siem-collector.security.svc:4317" # optional -schema_version = "1.3" # optional +endpoint = "http://siem-collector.security.svc:4317" # optional ``` Each OCSF event becomes one log record: | Field | Value | |---|---| -| Body | The OCSF event as a JSON string. With `schema_version` set to `1.1` or `1.3`, the record is downgraded as for [OCSF JSONL output](#ocsf-jsonl-output). | +| Body | The OCSF event as a JSON string. | | Timestamp | The OCSF `time`. The observed timestamp is when the gateway received the event. | | Severity | Unknown, Informational, and Other are INFO, Low is WARN, Medium is WARN2, High is ERROR, Critical is ERROR2, and Fatal is FATAL. The severity text is the OCSF severity name. | -| Attributes | `ocsf.class_uid`, `ocsf.activity_id`, `ocsf.severity_id`, `ocsf.metadata.uid`, and, for events associated with a sandbox, `openshell.sandbox.id`. These come from the event before any downgrade, so they remain when a downgrade removes the fields from the body. | +| Attributes | `ocsf.class_uid`, `ocsf.activity_id`, `ocsf.severity_id`, `ocsf.metadata.uid`, and, for events associated with a sandbox, `openshell.sandbox.id`. | + +`schema_version` in this table is deprecated and ignored; the gateway logs a warning at startup when it is set. Log export is independent of `RUST_LOG` and of `[openshell.gateway.ocsf_log]`; you can enable both. The gateway queues up to 10,000 records, and up to 16 MiB of records including the batch being exported, without blocking event producers. It exports a batch as soon as 100 records or 1 MiB are queued, or 500 ms after the first record of a batch arrives. A record larger than 1 MiB, such as an event for a request with a very long path, is dropped rather than exported. @@ -669,7 +669,7 @@ The relayed hop does not yet support TLS or authentication to the collector; an ### Tuning -`[openshell.gateway.otlp]` decides whether and where to export. How the SDK exports is controlled by the standard OpenTelemetry environment variables, which the gateway reads through the SDK rather than mirroring as TOML keys. They apply to the gateway and its in-process compute drivers. The gateway does not pass them to sandbox supervisors, which receive only the endpoints, the OCSF schema version, and the [OCSF collector headers](#ocsf-log-export). +`[openshell.gateway.otlp]` decides whether and where to export. How the SDK exports is controlled by the standard OpenTelemetry environment variables, which the gateway reads through the SDK rather than mirroring as TOML keys. They apply to the gateway and its in-process compute drivers. The gateway does not pass them to sandbox supervisors, which receive only the endpoints and the [OCSF collector headers](#ocsf-log-export). The gateway honors these variables: diff --git a/docs/images/splunk-cim-v1.1-downgrade.png b/docs/images/splunk-cim-v1.1-downgrade.png deleted file mode 100644 index feb8e21683e0a8e50b4fb4dc35769c9fb6ac732f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 171583 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

&Y)~GQd78;x#@rc1QGjPDNs`r0!_m)v{ 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 diff --git a/docs/observability/ocsf-json-export.mdx b/docs/observability/ocsf-json-export.mdx index cdc5f9418..f6c5d306c 100644 --- a/docs/observability/ocsf-json-export.mdx +++ b/docs/observability/ocsf-json-export.mdx @@ -3,7 +3,7 @@ # SPDX-License-Identifier: Apache-2.0 title: "OCSF JSON Export" sidebar-title: "OCSF JSON Export" -description: "How to enable full OCSF JSON logging for SIEM integration, compliance, and structured analysis. Includes schema version downgrade for AWS Security Lake, Splunk, and CrowdStrike compatibility." +description: "How to enable full OCSF JSON logging for SIEM integration, compliance, and structured analysis." keywords: "Generative AI, Cybersecurity, OCSF, JSON, SIEM, Compliance, Observability" --- @@ -119,7 +119,7 @@ When `ocsf_json_enabled=true`, sandbox supervisors emit full OCSF JSON to stderr 2026-10-07T23:21:19.000Z OCSF-JSON {"class_uid":4001,...} ``` -The example payload is abbreviated. Each actual `OCSF-JSON` line contains one complete compact JSON object. Configure your collector to match the `OCSF-JSON` token after the UTC timestamp and decode everything after the following space as JSON. Select these lines to avoid ingesting the shorthand copy of each event. The JSON preserves the original `metadata.uid` and follows `ocsf_schema_version`; with that setting unset, it uses the full native schema. +The example payload is abbreviated. Each actual `OCSF-JSON` line contains one complete compact JSON object. Configure your collector to match the `OCSF-JSON` token after the UTC timestamp and decode everything after the following space as JSON. Select these lines to avoid ingesting the shorthand copy of each event. The JSON preserves the original `metadata.uid`. Collect stderr through the supervisor's platform log interface: @@ -153,7 +153,7 @@ Some fields depend on the event class: - Process Activity records from the sandbox name the `openshell-sandbox` launcher as `actor.process`. - `connection_info` carries `direction_id` and `direction`. OpenShell reports Unknown (`0`) where it does not track the direction. -Each JSONL file line, or the payload after the stderr marker, is a complete OCSF v1.8.0 JSON object when no downgrade is configured. Records validate against OCSF v1.8.0 except for the top-level `container` object, which OCSF does not define at the event level. Here is an example of a network connection event: +Each JSONL file line, or the payload after the stderr marker, is a complete OCSF v1.8.0 JSON object. Records validate against OCSF v1.8.0 except for the top-level `container` object, which OCSF does not define at the event level. Here is an example of a network connection event: ```json { @@ -310,66 +310,9 @@ failures without an observed network endpoint, use Base Event (`class_uid: 0`). Include these classes when filtering supervisor operational events. Relay-control records that previously appeared as `NET:*` now appear as `EVENT`. -## SIEM Schema Version Compatibility +## Schema Version -OpenShell emits OCSF v1.8.0 events internally, but many SIEMs only support older schema versions. The `ocsf_schema_version` setting tells the JSONL layer to downgrade events before writing, stripping fields and profiles that don't exist in the target version. - -For gateway JSONL, set `schema_version` on the output destination. The target applies uniformly to every record written to that file and requires a gateway restart: - -```toml -[openshell.gateway.ocsf_log] -path = "/var/log/openshell/gateway-ocsf.jsonl" -schema_version = "1.3" -``` - -The sandbox-scoped setting below controls the legacy supervisor-local JSONL file only. - -Set the target version globally: - -```shell -openshell settings set --global --key ocsf_schema_version --value "1.1" -``` - -Or per-sandbox: - -```shell -openshell settings set my-sandbox --key ocsf_schema_version --value "1.3" -``` - -The setting takes effect on the next poll cycle, by default every 10 seconds. No sandbox restart is required. - -Supported target versions are `1.1` and `1.3`. When set, the JSONL layer applies the following transformations: - -- Strips fields added after the target version: `ai_model`, `container`, `observation_point_id` -- Removes unknown profile names from `metadata.profiles`: `ai_operation`, `container` -- Rewrites `metadata.version` to match the target version - -The shorthand log output is unaffected. The internal event model stays at v1.8.0; only the serialized JSONL is transformed. - -When unset or empty, no downgrade is applied and events are written at the current schema version. - -| SIEM | Required OCSF Version | `ocsf_schema_version` Value | -|---|---|---| -| AWS Security Lake | v1.1.0 | `1.1` | -| Splunk CIM Add-On | v1.1-v1.3 | `1.1` or `1.3` | -| CrowdStrike FDR | v1.5.0 | Not yet supported | -| Datadog Cloud SIEM | v1.5.0 (selectable) | Not yet supported | - - -Downgrading is lossy. The `ai_model` field and `ai_operation` profile are stripped for v1.1 and v1.3 targets, so AI model attribution is not present in downgraded events. If your audit workflow requires knowing which model handled a request, use the full schema version (leave `ocsf_schema_version` unset). OpenShell supports OCSF v1.8.0 natively; upgrade your SIEM's OCSF schema if you need AI attribution alongside backward-compatible ingestion. - - -Downgraded events include a `downgraded_from` marker in the `unmapped` object so auditors can distinguish "no model was involved" from "model attribution was stripped": - -```json -{ - "unmapped": { - "downgraded_from": "1.8.0" - } -} -``` - -The core OCSF event structure (class UIDs, activity IDs, network and HTTP fields) is identical across v1.1 through v1.8. The stripped fields are all profile-gated additions. +OpenShell emits OCSF v1.8.0 only. The `ocsf_schema_version` sandbox setting and the gateway `schema_version` fields under `[openshell.gateway.ocsf_log]` and `[openshell.gateway.otlp.ocsf]` are deprecated and ignored; remove them from your configuration. The gateway logs a warning at startup for each field that is set, and a sandbox reports a set `ocsf_schema_version` as a Device Config State Change event. ## Integration with External Tools @@ -377,9 +320,9 @@ The JSONL file can be shipped to any tool that accepts OCSF-formatted data: | Tool | Integration Path | |---|---| -| Splunk | Use the [Splunk OCSF Add-on](https://splunkbase.splunk.com/app/6943) to ingest OCSF JSONL files. Set `ocsf_schema_version` to `1.3` for CIM Add-On compatibility. | -| Amazon Security Lake | OCSF is the native schema for Security Lake. Set `ocsf_schema_version` to `1.1` for v1.1.0 compatibility. | -| CrowdStrike FDR | Ship JSONL files to Falcon Data Replicator. v1.5 downgrade target is not yet supported. | +| Splunk | Use the [Splunk OCSF Add-on](https://splunkbase.splunk.com/app/6943) to ingest OCSF JSONL files. | +| Amazon Security Lake | OCSF is the native schema for Security Lake. | +| CrowdStrike FDR | Ship JSONL files to Falcon Data Replicator. | | Elastic | Use Filebeat to ship JSONL files with the OCSF field mappings. | | Custom pipelines | Parse the JSONL file with `jq`, Python, or any JSON-capable tool. | @@ -393,7 +336,7 @@ jq -c 'select(.action == "Denied")' ./supervisor-logs/openshell-ocsf.*.jsonl Sandbox events identify the sandbox environment with `device.type_id: 99` (Other) and `device.type: "Sandbox"`. The operating system is reported separately in `device.os.name`; the device type does not classify the underlying host or compute backend. -The shorthand format in `openshell.YYYY-MM-DD.log` and the JSON format in `openshell-ocsf.YYYY-MM-DD.jsonl` are derived from the same OCSF events. The shorthand is a human-readable projection; the JSON is the full structured record when no schema downgrade is configured. When `ocsf_schema_version` is set, the JSON export is a lossy projection of the internal event model. Both formats are generated at the same time from the same event data. +The shorthand format in `openshell.YYYY-MM-DD.log` and the JSON format in `openshell-ocsf.YYYY-MM-DD.jsonl` are derived from the same OCSF events. The shorthand is a human-readable projection; the JSON is the full structured record. Both formats are generated at the same time from the same event data. Shorthand stderr output follows the diagnostic log filter; its local file is available when file logging starts successfully. JSON stderr and file export are opt-in through `ocsf_json_enabled`. File export requires the supervisor's JSONL sink to start successfully; stderr export is independent of that sink. diff --git a/docs/observability/overview.mdx b/docs/observability/overview.mdx index 1bef85662..73ae96470 100644 --- a/docs/observability/overview.mdx +++ b/docs/observability/overview.mdx @@ -77,7 +77,7 @@ path = "/var/log/openshell/gateway-ocsf.jsonl" openshell settings set --global --key ocsf_json_enabled --value true ``` -For the record structure, file locations, rotation, and schema version downgrades for older SIEMs, refer to [OCSF JSON Export](/observability/ocsf-json-export). +For the record structure, file locations, and rotation, refer to [OCSF JSON Export](/observability/ocsf-json-export). ### OTLP Log Export diff --git a/e2e/rust/tests/ocsf_jsonl_conformance.rs b/e2e/rust/tests/ocsf_jsonl_conformance.rs index 64b26219a..130d26572 100644 --- a/e2e/rust/tests/ocsf_jsonl_conformance.rs +++ b/e2e/rust/tests/ocsf_jsonl_conformance.rs @@ -229,17 +229,12 @@ async fn supervisor_jsonl_conforms_to_the_native_schema() { ); let mut failures = Vec::new(); for record in &records { - match openshell_ocsf_validate::validate_event(record) { - Ok(()) => {} - Err(openshell_ocsf_validate::Error::UnsupportedVersion(version)) => panic!( - "record labelled {version}; native validation needs ocsf_schema_version unset \ - for this sandbox and the gateway" - ), - Err(reason) => failures.push(format!( + if let Err(reason) = openshell_ocsf_validate::validate_event(record) { + failures.push(format!( "{} \"{}\": {reason}", record["class_name"], record["message"].as_str().unwrap_or_default() - )), + )); } } assert!( diff --git a/skills/debug-openshell-cluster/SKILL.md b/skills/debug-openshell-cluster/SKILL.md index 29b440756..264d4ca18 100644 --- a/skills/debug-openshell-cluster/SKILL.md +++ b/skills/debug-openshell-cluster/SKILL.md @@ -1493,7 +1493,7 @@ credential failures. |---|---|---| | `openshell status` fails | Gateway endpoint unreachable or auth mismatch | `openshell gateway info`, gateway logs | | Collector receives no OCSF log records, or `openshell.ocsf.gap` records | `[openshell.gateway.otlp.ocsf]` missing or without `enabled = true`, an unreachable or non-gRPC endpoint, or export failures and queue pressure | Check `[openshell.gateway.otlp.ocsf]` for `enabled = true` and the endpoint it resolves to, the gateway's `OTLP exporting enabled` startup log for `ocsf_endpoint`, export warnings, and `openshell_ocsf_otlp_*` metrics. See the published [gateway configuration reference](https://docs.nvidia.com/openshell/latest/how-it-works/gateways/configuration). | -| Gateway OCSF JSONL stops growing, has gaps, or is rejected by a SIEM | File errors, queue pressure, shipper falling behind retention, or a schema mismatch | Inspect gateway warnings and `openshell_ocsf_log_*` metrics; check `[openshell.gateway.ocsf_log]`, `schema_version`, directory permissions, free space, per-replica paths, and shipper rotation checkpoints. See the published [gateway configuration reference](https://docs.nvidia.com/openshell/latest/how-it-works/gateways/configuration). | +| Gateway OCSF JSONL stops growing, has gaps, or is rejected by a SIEM | File errors, queue pressure, or shipper falling behind retention | Inspect gateway warnings and `openshell_ocsf_log_*` metrics; check `[openshell.gateway.ocsf_log]`, directory permissions, free space, per-replica paths, and shipper rotation checkpoints. See the published [gateway configuration reference](https://docs.nvidia.com/openshell/latest/how-it-works/gateways/configuration). | | `BatchSpanProcessor.ExportError` repeatedly reports connection refused on `127.0.0.1:4317` | The local gateway started with OTLP configured but the collector forwarding task later stopped, or the config was created manually | Restart `gateway:docker`, `gateway:podman`, or `gateway:vm` so it re-detects the listener; inspect the generated `gateway.toml` for `[openshell.gateway.otlp]` | | Sandbox log shows `OTLP agent trace relay inactive: not enabled by the gateway` at startup, then `agent OTLP export attempted but the agent trace relay is not enabled` when the agent exports | The gateway does not enable `[openshell.gateway.otlp.agent]`, so the supervisor refuses the workload's OTLP relay address | Set `enabled = true` in `[openshell.gateway.otlp.agent]` (Helm: `gatewayConfig."openshell.gateway.otlp.agent".enabled`) with an endpoint from that table or `[openshell.gateway.otlp]`, and recreate the sandbox; `openshell logs --source sandbox` then shows `OTLP agent trace relay enabled` | | Gateway starts but sandbox create fails | Compute driver cannot reach runtime | Docker/Podman/Kubernetes/VM driver logs | diff --git a/skills/openshell-cli/SKILL.md b/skills/openshell-cli/SKILL.md index f87e06fdf..a950b3a3b 100644 --- a/skills/openshell-cli/SKILL.md +++ b/skills/openshell-cli/SKILL.md @@ -922,9 +922,6 @@ openshell settings delete work-session --key ocsf_json_enabled openshell settings get --global --json openshell settings set --global --key ocsf_json_enabled --value true - -# OCSF schema version downgrade for SIEM compatibility (allowed: "1.1", "1.3") -openshell settings set --global --key ocsf_schema_version --value "1.1" ``` Enabling `ocsf_json_enabled` adds compact `OCSF-JSON` records to the supervisor's stderr, alongside shorthand, and to its JSONL file when file storage is available. Collect these records through the supervisor's platform logs (`docker logs`, `podman logs`, or `kubectl logs`); `openshell logs` still serves shorthand. Match the `OCSF-JSON` marker after the timestamp and parse the remainder as JSON. See the published [OCSF JSON export guide](https://docs.nvidia.com/openshell/latest/observability/ocsf-json-export) for delivery and retention limits.