Files
OpenShell/crates/openshell-supervisor-process
krishicks af6604a617 feat(ocsf): validate OCSF events against exported JSON Schemas (#5019)
* feat(ocsf): add JSON Schema validator for OCSF events

Add openshell-ocsf-validate, which validates an OCSF event against the
JSON Schema the OCSF schema server exports for the event's version,
class, and declared profiles. The exports encode required attributes,
at_least_one constraints, undefined attributes, types, and enum values,
so the crate delegates to the jsonschema crate and only selects the
schema. The exports type type_uid only as an integer, so the crate also
checks that it equals class_uid * 100 + activity_id.

An exported schema covers one fixed set of profiles, so the crate vendors
one export per class and profile combination that OpenShell emits, under
schemas/v<version>/<class>@<profiles>.json. An event whose version or
combination has no vendored schema fails with the schemas/update.sh
command that vendors it. Keying on the event's version lets a new OCSF
version's schemas land before the emitters switch to it. The build
embeds every vendored file.

Top-level container is accepted unvalidated, as OCSF does not define it
at the event level (#4915).

Signed-off-by: Kris Hicks <khicks@nvidia.com>

* test(ocsf): validate OCSF events with openshell-ocsf-validate

Replace openshell-ocsf's hand-written schema walker with
openshell-ocsf-validate in the builder, producer, gateway audit and
Podman e2e tests. One validate_event call now covers what the
per-object validate_required_fields, validate_known_fields and
validate_enum_value calls checked, and adds type checks and enum
checks for every attribute.

Remove the validation module and the vendored OCSF object and class
schemas from openshell-ocsf. The e2e suite no longer depends on
openshell-ocsf directly.

Signed-off-by: Kris Hicks <khicks@nvidia.com>

---------

Signed-off-by: Kris Hicks <khicks@nvidia.com>
2026-10-29 00:44:47 +00:00
..

OpenShell process supervisor

This crate manages workload processes and SSH sessions through the admitted isolation backend.

Bounded streaming uploads

The CLI's built-in uploads use the openshell-upload-v1 SSH subsystem. Russh returns SSH receive credit before the supervisor consumes channel data, so this subsystem returns its own credit and uses SSH for everything else. The gateway relays the channel without interpreting it.

The client sends one JSON plan line with the destination, then the raw tar stream, then SSH EOF. When the plan arrives, the supervisor starts the extractor through the ordinary BoundaryExec path, with the same workload identity, environment, working directory and filesystem policy as other SSH children. Startup runs inline, like an exec request.

Stdout carries only big-endian u64 totals of archive bytes that InputTask has written through BoundaryInput::write_all. The first total, zero, means extraction started. Extractor stdout and stderr are both sent as SSH stderr, so extractor output cannot forge credit. The client keeps at most 1 MiB beyond the last total outstanding; the supervisor rejects input beyond that window. The existing 4 MiB pending-input guard remains active.

After the extractor exits successfully and stdin has drained, the supervisor sends the final total, then the exit status. The client succeeds only when the status is zero and the final total equals the bytes it sent. A malformed plan, credit violation, extended data or EOF before the plan fails the upload with exit status 74. A rejection wins until the supervisor reports the exit result, even after the extractor exits. Rejection, channel close or disconnect terminates the extractor. Extraction writes directly to the destination, so failures can leave partially extracted files; there is no rollback or atomic replacement.

The CLI requires supervisor support for this subsystem before sending archive data. It does not fall back to the previous unpaced exec-stdin upload path. Ordinary exec stdin and SFTP retain their existing input-budget behavior.