Repository navigation
bug(ocsf): process events omit command arguments #4563
Description
User Story
As an operator using OpenShell OCSF events for audit review, I need process records to include the command that ran so that I can investigate activity without relying on incomplete network event fields.
Problem Statement
OpenShell process launch records include the program name and PID but omit command arguments. Network activity records populate cmd_line from absolute paths found in the process chain rather than the actual argument vector. As a result, the audit trail cannot show the command that produced the activity.
Related downstream report: NVIDIA/NemoClaw#13175
Related broader work: #4268 concerns launch and exit coverage for every workload process; this issue is specifically about the contents of cmd_line in existing records.
Impact / Why This Matters
Auditors cannot reconstruct the executed command from current OCSF process records, and the network record's path-only value can be mistaken for a complete command line. Host logs or manual process inspection are incomplete workarounds after the process exits.
Acceptance Criteria
- Process launch records include the executed command and arguments in the OCSF command-line field when available.
- Network activity records do not present an absolute-path-only list as if it were the actual command line.
- Audit output has a documented bound and redacts known sensitive arguments before emission.
- Regression coverage includes an argument that is not an absolute path and a sensitive argument that must be redacted.
Reproduction Steps
- Enable OpenShell OCSF JSONL logging for a sandbox.
- Launch a workload with a visible non-path argument and make an allowed network request from that process.
- Inspect the process launch record and the corresponding network activity record. The launch record lacks the arguments; the network
cmd_linecontains only selected absolute paths, not the executed command.
Environment
- Reported with OpenShell 0.0.116 on Ubuntu 24.04 with Docker; the downstream report notes internal reproduction.
- The process and network event construction is also present in OpenShell v0.1.2, v0.1.3, v0.1.4, and current
mainas checked in source.
Agent Investigation
crates/openshell-sandbox/src/delegated.rsconstructs the process event withOcsfProcess::new(program, pid)and does not setcmd_line.crates/openshell-supervisor-network/src/proxy.rsbuilds the network event's command-line string fromdecision.cmdline_paths.
Activity
krishicks commentedon Oct 23, 2026
Accepting. The bug reproduces from the code; analysis and open decisions below.
Where it reproduces
crates/openshell-sandbox/src/delegated.rs:131builds the process withOcsfProcess::new(program, pid)and never calls.with_cmd_line(..).argsis in scope and is dropped.crates/openshell-supervisor-network/src/proxy.rs(around lines 869, 2688, 5513) fillscmd_linewith absolute paths collected from the whole process ancestry (procfs::collect_cmdline_paths,openshell-binary-identity), joined with", ". It is not the socket owner's argv. When the list is empty it emits the sentinel"-".docs/observability/ocsf-json-export.mdx:256shows"cmd_line": "curl https://github.com"for a network event, which the code does not emit.crates/openshell-supervisor-processemits no Process Activity events; exec and SSH children emitting none is feat(sandbox): emit process launch and exit events for every workload process, with the parent pid #4268.Small fix
openshell-ocsf(next tosanitize_reason_for_audit) that redacts sensitive arguments, quotes arguments containing whitespace, escapes control characters, and caps argument count and total length with a truncation marker.delegated.rs:131. Keep argv out ofmessage. Move event construction into a pure function so it is testable without a Linux launcher.crates/openshell-ocsf/src/format/shorthand.rs:520, which prints[cmd:..]raw. Once real argv flows, a newline or]could forge or split log lines.cmdline_pathstowith_cmd_lineon network events. If operators still want the path list, put it underunmappedwith an honest key. Leavecmdline_pathsas-is in the OPA input and protocol; it is diagnostic and never authorizes.ocsf-json-export.mdxandlogging.mdx(PROC:LAUNCHexample), and document the bound and redaction rules.Estimate: about 1.5-2 engineer-days with tests and docs.
Large fix
Real argv on network events. This needs a raw-argv field next to
cmdline_pathsinprocfs.rs,openshell-binary-identity,ResolvedBinaryIdentity,proto/sandbox_protocol.proto, and the sandbox-backend conversion. The value must stay out ofPolicyIdentityKeyand the OPA input, because a workload can rewrite its own argv, and it must be capped at the protocol boundary (read_process_cmdlinecurrently reads up to roughly ARG_MAX). Estimate: another 3-5 days.Decisions needed
etw_consumer.rs:1785, regression test at:2122) because they may contain credentials, signed URLs, or PII. The issue asks Linux to include them. Emit redacted argv, or follow MXC? If argv is emitted, should MXC align?unmapped.cmdline_paths, or drop from OCSF."-"sentinel. OCSF guidance is empty or omitted; fixingcmd_lineis in scope here, the other fields are separate.Sequencing
#4288 touches the same lines (adds
.actor_process(..)right afterdelegated.rs:131and makes the process builder require an actor beforebuild()). Landing it first avoids a rebase.krishicks commentedon Oct 23, 2026
Follow-up on decisions 1 and 3: proposing that command-line capture be opt-in, off by default.
Why
Redaction by denylist only catches arguments that look like secrets. A workload that deliberately encodes a secret into a command (for example a path such as
/tmp/<secret>/run) passes any pattern match. Because OCSF events leave the sandbox through the gateway log push, SIEM export, and OTLP, outside the sandbox's network policy, workload-chosen argv is a covert channel for anything the agent can read.How much this matters depends on the event:
AgentSpecWire { program, args }), which the operator or gateway defines, not the running agent. The agent cannot choose what is logged, and the command is already stored in the gateway spec.Agent-chosen strings already appear in OCSF today (destination hosts on denied CONNECTs, L7 request paths, the
cmdline_pathsancestry list), so the channel is partly open already. That is worth auditing separately.Proposal
cmd_line, matching the MXC driver (etw_consumer.rs:1785). Linux and Windows then agree.cmd_lineon workload-spawned processes is attacker-controlled data and not secret-safe.cmd_lineis a bug fix and is not gated by the setting.New decision: where the setting lives
This adds public configuration, and the supervisor emits the events, so the value has to reach it. Candidates: a gateway-level setting, a per-sandbox or policy setting, or a supervisor environment variable. Gateway-level is simplest for operators; per-sandbox allows enabling it for one trusted workload. This should follow the existing supervisor-side setting plumbing and
proto/README.md. It also needs deciding whether the switch covers only launch events or also the child-process events from #4268.