Skip to content

feat: include resolved Kubernetes workload image identity in OCSF events #5215

Open

Description

@aeilot

User Story

I use OpenShell OCSF records to trace sandbox activity back to the Kubernetes workload image that produced it. I need the resolved image ID in those records so I can identify the exact image used, even when a mutable image tag later points to a different image.

Problem Statement

Kubernetes supervisor OCSF records currently lack a resolved immutable workload image UID. With the changes in PR #5048, records preserve known image references in unmapped.container_image, but cannot populate the standard device.container.image object without its required UID.

The maintainer requested Kubernetes image UID enrichment as a separate follow-up in the review of PR #5048.

Related: #4272 proposes broader supervisor-version and resolved-image reporting across sandbox status and events. This follow-up is limited to Kubernetes workload image identity in supervisor OCSF records; it does not add sandbox status fields or supervisor-version reporting. The published OCSF JSON export documentation describes the existing collection workflow.

Impact / Why This Matters

Consumers can identify a workload's requested image reference through the fallback field, but cannot use the standard OCSF image UID to distinguish the actual images behind a mutable tag. Image-based queries also need separate mappings for Kubernetes and drivers that already provide a resolved UID.

Proposed Design

When a user creates an OpenShell sandbox on Kubernetes and enables OCSF JSON export, supervisor records should identify the immutable image actually provisioned for the workload. This behavior should cover both dedicated and shared supervisors without additional user configuration.

When resolved identity is available, records should include:

{
  "device": {
    "container": {
      "image": {
        "uid": "<resolved workload image identity>",
        "name": "registry.example/workload:latest"
      }
    }
  }
}

The example is an excerpt, not a complete OCSF record. name is optional when the requested reference is unavailable. If resolved identity is unavailable, records should omit the image object and preserve any known reference in unmapped.container_image.

Identity must describe the provisioned workload image, including after a mutable tag changes, rather than the supervisor companion's image or a fresh resolution of the tag.

Acceptance Criteria

  • Kubernetes supervisor records include the provisioned workload's resolved immutable image UID when available.
  • The behavior covers dedicated and shared supervisors.
  • Known requested references remain available in device.container.image.name when an image UID is present.
  • Changing a tag does not change the image identity reported for an existing workload unless that workload is reprovisioned with a different image.
  • Missing resolved identity preserves known references in unmapped.container_image without emitting an invalid image object.
  • Records omit unavailable image names instead of emitting empty strings.
  • Real Kubernetes supervisor JSONL records validate against the exported OCSF schemas, and the recorded identity matches the workload's runtime-reported identity.

Alternatives Considered

  • Keep the fallback reference only. This preserves the requested name but does not supply immutable identity for image-based correlation.
  • Use the requested tag as image.uid. A mutable reference does not identify the provisioned image and can later resolve to different content.
  • Resolve the tag again when emitting logs. This can attribute a running workload to an image it never used.
  • Use middleware, gateway interceptors, or credential providers. Their existing request-processing and credential workflows do not provide the provisioned Kubernetes workload image identity needed for supervisor event attribution. If an existing extension can expose that identity, it should be considered during implementation.

Checklist

  • I've reviewed existing issues and the published docs
  • This is a design proposal, not a "please build this" request

Activity

  1. aeilot commented on Nov 3, 2026

    @aeilot
    ContributorAuthor

    I’d like to take this on as the Kubernetes follow-up to #5048. I’ll cover both dedicated and shared supervisors, preserve the image-reference fallback, and add Kubernetes E2E coverage for the resolved workload image identity.

    Could a maintainer confirm acceptance and assign this issue to me?

  2. aeilot commented on Nov 4, 2026

    @aeilot
    ContributorAuthor

    I’ve looked into the current Kubernetes bootstrap flow. I’m leaning toward having the driver read status.containerStatuses[name=agent].imageID from the actual workload Pod and pass it into the supervisor’s OCSF context.

    The main wrinkle is timing: supervisor launch material is currently prepared before the workload’s scheduling gate is removed, so the resolved image ID is generally unavailable at that point.

    My proposed approach is to:

    • Release the workload’s trusted runtime first, then observe its image ID before starting the dedicated supervisor or assigning the shared instance. User processes would still wait for supervision.
    • Pass the reference and optional UID through dedicated launch material and shared-instance registration.
    • Persist the identity with the workload Pod UID and runtime generation so recovery preserves it without re-resolving a mutable tag.
    • Use a bounded wait and preserve the existing unmapped.container_image fallback when no resolved identity is available.
      Before committing to that ordering, I’ll validate both connection modes and gateway recovery during bootstrap, and check mixed-version compatibility for shared registrations.

    E2E coverage would exercise dedicated and shared supervisors, validate real JSONL records against the OCSF schemas, and compare the recorded UID with the workload container’s runtime-reported image ID. It would also verify that moving a tag does not change an existing workload’s recorded identity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    state:triage-neededOpened without agent diagnostics and needs triage

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions