Skip to content
About

Mixed images and unsigned initContainers

A Pod can contain more than the application’s main image. An initContainer may run before the application and prepare files or other state. If only the regular image were verified, an unsigned init image could execute first despite a trusted main container. The baseline includes two fixtures aimed at that boundary.

Their filenames and screenshot labels sound broader than their contents. Reading the YAML establishes the actual evidence scope: both combine a signed regular container with an unsigned initContainer.

What the recorded container experiment covers
What the recorded container experiment coversThe trusted acceptance capture establishes the signed regular-container path in its setup. The unsigned-init fixture targets initContainers before application startup. The mixed fixture combines signed application and unsigned init; it is not an unsigned regular sidecar experiment. Ephemeral container subresource coverage remains unverified by these captures/tests.Regular imageInit imageMixed Pod denyEphemeral gap
The mixed fixture contains a signed regular container and an unsigned initContainer.
  1. The trusted acceptance capture establishes the signed regular-container path in its setup.
  2. The unsigned-init fixture targets initContainers before application startup.
  3. The mixed fixture combines signed application and unsigned init; it is not an unsigned regular sidecar experiment.
  4. Ephemeral container subresource coverage remains unverified by these captures/tests.

Solid arrows indicate the stated handoff, not a claim of independent trust. Optional relationships are described in the text equivalent. Historical components are labeled in the caption.

Fixture Regular containers initContainers What changes
test-mixed-containers.yaml One signed image by digest One unsigned-test image Mixed trust within a Pod, with the unsigned image in initContainers
test-init-unsigned.yaml One signed image by digest, with sleep command One unsigned-test image, with shell command Explicit init fixture, different commands and labels

Both unsigned images are under the policy’s matching application-registry path. Both fixtures use non-root/no-privilege-escalation settings, so the intended rejection concerns artifact claims rather than intentionally privileged execution. The trusted image’s presence must not excuse the unsigned init image.

Expected behavior is rejection of each Pod request. The screenshot shows two separate kubectl apply --dry-run=server commands and two webhook denials. Both report no signatures for the unsigned-test image, accompanied by missing provenance and SBOM claims.

recorded-live-validation · rejected

Both captured mixed-image fixtures with an unsigned initContainer were denied.

Expected in this setup: An approved regular image must not excuse an unsigned matched init image in the same Pod.

Recorded result: API-server dry runs for test-mixed-containers and test-init-unsigned were denied, each citing unsigned-test with no signatures and no matching attestations.

Historical GCP, europe-west1; current environment not checked · observed 2026-08-23 · source revision unknown; not inferred from the documentation baseline

Both mixed-image fixtures containing an unsigned initContainer are denied.
Both mixed-image fixtures containing an unsigned initContainer are denied. · Select the image to read it at full resolution.

Transcript / inspected observation

Selected visible output:
TEST 1 - Mixed trusted + untrusted containers
resource Pod/default/test-mixed-containers was blocked
verify-image-signature: supply-chain-demo:unsigned-test: no signatures found
verify-provenance-attestation: no matching attestations
verify-sbom-attestation: no matching attestations
RESULT 1: PASS - mixed-container bypass DENIED
TEST 2 - Unsigned initContainer
resource Pod/default/test-init-unsigned was blocked
verify-image-signature: supply-chain-demo:unsigned-test: no signatures found
RESULT 2: PASS - unsigned initContainer DENIED

What this does not establish

  • The baseline YAML shows both fixtures use an unsigned initContainer alongside a signed regular container.
  • This does not establish unsigned regular sidecar or ephemeral-container subresource coverage.
  • The capture's final broad phrase about protected bypass paths is narrowed to the fields actually tested.

Visual review of original capture. Collection capture date attributed to docs/my-validation/README.md; this task did not rerun its cloud experiment. The original screenshot is approved for display at the owner’s explicit request for all evidence images and subsequent Cloudflare publication. Original terminal metadata remains visible. No additional pixel redaction was selected or applied. The selected transcript omits incidental prompts without changing the recorded result.

Read the approved selected-output transcript →

View the related screenshot in the complete gallery →

Inspect the untouched, commit-pinned original →

That observation supports coverage of the shown initContainer path in the historical environment. A server dry run does not launch the init process; rejection occurs before the requested Pod is persisted. The transcript preserves that distinction.

The evidence does not include an unsigned regular sidecar beside the signed regular application container. It also does not show an ephemeral-container update through the pods/ephemeralcontainers subresource. Those fields and request paths should be tested independently, particularly because admission registration and controller-version behavior can differ by operation.

No blanket claim of “all containers, initContainers, and ephemeral containers verified” follows from these two requests. Nor does an untested path establish a bypass. The honest result is a supported historical initContainer rejection and explicit unverified scope elsewhere.

not-verified · gap

Ephemeral-container updates, unmatched-image handling and verifier outages have no established live result in this catalogue.

Expected in this setup: Fresh isolated tests and installed configuration inspection are required to establish each behavior.

Recorded result: No recorded test found for ephemeral-container subresource, isolated unsigned regular sidecar, registry outage or controller outage.

Offline detached baseline inspection; no cloud mutation · observed date unknown · source revision unknown; not inferred from the documentation baseline

Transcript / inspected observation

No execution transcript exists for these cases.

What this does not establish

  • Absence from reviewed evidence is not proof of a vulnerability or capability.
  • Enforce and webhook name do not establish the complete version-specific outage contract.

Source inspected against the pinned baseline; execution scope stated explicitly. No screenshot or sensitive runtime state published.

Inspect the untouched, commit-pinned original →

In an owned reproduction, preserve one positive request and isolate each negative field: unsigned regular-only image, unsigned regular sidecar, unsigned init image, and an ephemeral-container subresource update. Keep registry path and namespace fixed while changing the tested field. Record exact policy, controller version, effective webhook matching, full input YAML, expected result, and API response for every case.

These are proposed validation improvements, not tests performed by this documentation task. The known-gaps page places them beside other scope and outage questions. The admission-scope explanation connects the results to namespace and registry matching.