You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug: ResolvedWorkloadIdentity deserialization skips the non-root and ordering invariants of new() #5189
I run OpenShell sandboxes with the Podman and Kubernetes drivers, and I read through the isolation core (openshell-sandbox, openshell-binary-identity, openshell-isolation-interface) at 00528d24a. This item comes from reading the code. I have not hit it in production. It is one line of the umbrella issue #5179.
Problem Statement
ResolvedWorkloadIdentity (crates/openshell-isolation-interface/src/contract.rs:144) has public fields and derives Deserialize. ResolvedWorkloadIdentity::new enforces a non-root identity, non-empty source and resource_digest, and sorted, de-duplicated supplementary groups, but a value decoded with serde bypasses all of that. For example, the supervisor decodes SandboxRuntimeDescriptor with serde_json (backend_setup.rs), and the descriptor embeds the identity.
Impact / Why This Matters
A descriptor with uid: 0, an empty source, or unsorted duplicate groups is accepted and used as the launch identity and in boundary confirmation, despite the type's "exact non-root identity" contract. The descriptor comes from a trusted peer today, so this is contract hardening.
Acceptance Criteria
Decoding goes through new() (for example #[serde(try_from = "RawResolvedWorkloadIdentity")]), so invalid values fail to deserialize.
Tests cover uid 0, empty fields, and unsorted or duplicate groups.
The other contract types whose validate() checks only part of what they carry are listed in the PR as follow-ups.
Reproduction Steps
Found by reading the code; not reproduced live. Deserialize {"uid":0,"gid":0,"supplementary_gids":[3,1,1],"source":"","resource_digest":""} into ResolvedWorkloadIdentity in a unit test and observe it succeeds.
Environment
OpenShell: main at 00528d24a
OS: Fedora 44, Linux 7.2.14
Deployment: Podman driver (local gateway); code read for the Kubernetes driver too
Source inspection at 32dcc4a67: ResolvedWorkloadIdentity derives Deserialize directly, while its non-root, required-field, and group-normalization checks live in new(). Routing deserialization through that constructor addresses the contract gap. This is hardening of a descriptor supplied by a trusted peer.
This assessment is based on the source and the linked report/PR; I have not independently run deployment reproductions or the PR test suite. CI and code review still need to validate the fix.
Activity
mrunalp commentedon Nov 3, 2026
Accepted for implementation in #5192.
Source inspection at
32dcc4a67: ResolvedWorkloadIdentity derives Deserialize directly, while its non-root, required-field, and group-normalization checks live in new(). Routing deserialization through that constructor addresses the contract gap. This is hardening of a descriptor supplied by a trusted peer.This assessment is based on the source and the linked report/PR; I have not independently run deployment reproductions or the PR test suite. CI and code review still need to validate the fix.