Skip to content

Lab 04 — Sign and Verify Container Images

Item Details
Lab ID K8S-IMAGE-SECURITY-LAB-04
Difficulty Advanced
Estimated Time 4–6 Hours
Environment Local Workstation, Private OCI Registry and Kubernetes Training Cluster
Platform Docker, Cosign, Trivy, Kubernetes and OCI-Compatible Registry
Supported Registries Amazon ECR, Azure Container Registry, Google Artifact Registry, Harbor, GitHub Container Registry
Cost Free for Local Tools / Registry and Cloud Charges May Apply
Primary Role DevSecOps Engineer
Supporting Roles Kubernetes Security Engineer, Cloud Security Engineer, Platform Engineer, Application Security Engineer
Module Kubernetes Container Image and Supply Chain Security
Previous Lab Lab 03 — Secure Private Container Registries
Next Lab Lab 05 — Enforce Trusted Images with Admission Policies

CloudNova Technologies has implemented:

  • Secure container builds
  • Container-image vulnerability scanning
  • Private registry controls
  • Immutable production tags
  • Digest-based Kubernetes deployments
  • Registry audit logging
  • Repository-level access controls

However, the security team has identified an important remaining gap.

The private registry can confirm where an image is stored, but the Kubernetes platform cannot yet determine:

  • Who approved the image
  • Who signed the image
  • Whether the image was changed after approval
  • Whether the image came from an authorised CI/CD pipeline
  • Whether an SBOM belongs to the deployed image
  • Whether required security checks were completed
  • Whether the signing identity is trusted
  • Whether the image signature is valid
  • Whether the image meets production policy

During a recent internal assessment, an unauthorised image was pushed into a staging repository using compromised CI/CD credentials.

The image passed basic registry authentication but had not been:

  • Signed by an approved identity
  • Associated with verified build provenance
  • Linked to an approved SBOM
  • Validated through an admission policy

CloudNova Technologies has therefore introduced a mandatory software supply-chain trust requirement.

Every production container image must:

  1. Be stored in an approved private registry.
  2. Be identified using an immutable digest.
  3. Pass vulnerability and secret scanning.
  4. Have an approved SBOM.
  5. Be signed by an authorised identity.
  6. Have its signature independently verified.
  7. Include required attestations.
  8. Be rejected when signature verification fails.
  9. Be evaluated by Kubernetes admission policy before deployment.

Your mission is to establish this signed-image workflow using Cosign.

By completing this lab, you will learn how to:

  • Explain container-image signing
  • Understand software-artifact integrity
  • Install and validate Cosign
  • Identify an image by immutable digest
  • Generate a Cosign key pair
  • Protect private signing keys
  • Sign a container image using a local key
  • Verify a key-based image signature
  • Perform identity-based keyless signing
  • Verify certificate identity and OIDC issuer
  • Understand transparency-log records
  • Generate an SBOM
  • Create and attach attestations
  • Verify image attestations
  • Test invalid-signature scenarios
  • Review signature metadata
  • Define enterprise signing identities
  • Prepare Kubernetes admission enforcement
  • Produce an enterprise image-trust report
Application Source Code
Controlled CI/CD Pipeline
┌─────────────────┼─────────────────┐
│ │ │
Container Build Security Scanning SBOM Generation
│ │ │
└─────────────────┼─────────────────┘
Approved Image by Digest
Cosign Image Signature
┌─────────────────┼─────────────────┐
│ │ │
Signing Identity Attestation Transparency Record
│ │ │
└─────────────────┼─────────────────┘
Private Container Registry
Kubernetes Admission Verification
┌─────────────┴─────────────┐
│ │
Verified Unverified
│ │
▼ ▼
Deployment Allowed Deployment Rejected
Trusted Source
Controlled Build
Security Scan
Immutable Digest
Verified Signature
Approved Attestation
Admission Enforcement
Runtime Monitoring

This lab applies the following principles:

  • Sign immutable image digests rather than mutable tags.
  • Keep private signing keys protected.
  • Prefer short-lived identity-based signing where appropriate.
  • Validate both signature integrity and signer identity.
  • Store signatures and attestations with OCI artifacts.
  • Do not treat a valid signature as proof that software is vulnerability-free.
  • Enforce signature verification before production deployment.
  • Retain signing and verification evidence.
  • Separate image builders, approvers and deployers.
  • Revoke trust when a signing identity is compromised.

A valid container-image signature can provide assurance that:

  • The signed artifact has not changed.
  • The image digest matches the signed artifact.
  • The signer possessed an approved signing identity or key.
  • Verification can be performed independently.
  • The signature can be evaluated by automated policy.

A signature does not automatically prove that:

  • The application is secure.
  • The image has no vulnerabilities.
  • The source code is trustworthy.
  • The CI/CD system was not compromised.
  • The signer made a correct approval decision.
  • The running workload is securely configured.

Image signing must be combined with:

  • Secure software development
  • Vulnerability scanning
  • Secret scanning
  • SBOM generation
  • Build provenance
  • Registry security
  • Admission control
  • Kubernetes workload hardening
  • Runtime monitoring

By the end of this lab, you will have:

  • Installed Cosign
  • Validated the Cosign installation
  • Identified an approved registry image by digest
  • Generated a signing-key pair
  • Protected the private signing key
  • Signed an image using a local key
  • Verified the image signature
  • Tested verification with an incorrect key
  • Performed keyless signing where supported
  • Verified the signing identity
  • Inspected signature metadata
  • Generated a CycloneDX SBOM
  • Attached an SBOM-related attestation
  • Verified an attestation
  • Created a vulnerability-scan attestation
  • Tested unsigned-image verification
  • Prepared a Kubernetes Deployment using the signed digest
  • Designed an enterprise signature policy
  • Produced an image-signing security report

Use only container images, registries, cloud accounts and identities that you are authorised to manage.

Do not:

  • Use production signing keys in a training environment
  • Commit private signing keys to Git
  • Store signing-key passwords in scripts
  • Share signing keys between teams
  • Sign unknown or unapproved images
  • Sign images using mutable tags without first resolving the digest
  • Publish confidential attestation data
  • Expose OIDC identity tokens
  • Disable signature verification to bypass deployment controls
  • Delete signature evidence related to an incident
  • Use test identities to approve production images

Before starting, ensure that you have:

  • Docker Desktop, Docker Engine or Podman
  • Cosign installed or permission to install it
  • Trivy installed
  • kubectl installed
  • jq installed where possible
  • A Kubernetes training cluster
  • Access to an authorised OCI-compatible registry
  • A hardened image from Lab 02
  • A secure private registry from Lab 03
  • The image pushed to the private registry
  • The immutable image digest recorded
  • Permission to push signatures and attestations
  • Visual Studio Code
  • Git Bash or PowerShell

Recommended image reference:

<registry-endpoint>/<repository>@sha256:<approved-digest>
Tool Purpose
Cosign Sign and verify images and attestations
Docker or Podman Inspect, pull and manage images
Trivy Scan images and generate SBOM data
kubectl Prepare and validate Kubernetes deployment
jq Review JSON verification output
OCI Registry Store images, signatures and attestations
Git Bash / PowerShell Execute commands
Visual Studio Code Create policies, manifests and reports
lab-04-sign-and-verify-container-images/
├── keys/
│ ├── cosign.pub
│ └── README.md
├── attestations/
│ ├── vulnerability-scan-predicate.json
│ ├── build-review-predicate.json
│ └── sbom-cyclonedx.json
├── kubernetes/
│ ├── namespace.yaml
│ ├── signed-deployment.yaml
│ ├── unsigned-deployment.yaml
│ └── cluster-image-policy-example.yaml
├── policies/
│ ├── enterprise-signing-policy.md
│ ├── trusted-identities.md
│ ├── signing-key-rotation.md
│ └── signing-incident-response.md
├── reports/
│ ├── image-scan.json
│ ├── signature-verification.json
│ ├── attestation-verification.json
│ ├── image-trust-assessment.md
│ └── image-signing-security-report.md
└── evidence/
├── cosign-version.txt
├── image-reference.txt
├── image-digest.txt
├── public-key.txt
├── signing-result.txt
├── verification-result.txt
├── failed-verification.txt
├── keyless-verification.txt
├── attestation-result.txt
└── deployment-validation.txt
Terminal window
mkdir -p lab-04-sign-and-verify-container-images/keys
mkdir -p lab-04-sign-and-verify-container-images/attestations
mkdir -p lab-04-sign-and-verify-container-images/kubernetes
mkdir -p lab-04-sign-and-verify-container-images/policies
mkdir -p lab-04-sign-and-verify-container-images/reports
mkdir -p lab-04-sign-and-verify-container-images/evidence
cd lab-04-sign-and-verify-container-images
Terminal window
New-Item -ItemType Directory -Force `
-Path lab-04-sign-and-verify-container-images\keys
New-Item -ItemType Directory -Force `
-Path lab-04-sign-and-verify-container-images\attestations
New-Item -ItemType Directory -Force `
-Path lab-04-sign-and-verify-container-images\kubernetes
New-Item -ItemType Directory -Force `
-Path lab-04-sign-and-verify-container-images\policies
New-Item -ItemType Directory -Force `
-Path lab-04-sign-and-verify-container-images\reports
New-Item -ItemType Directory -Force `
-Path lab-04-sign-and-verify-container-images\evidence
Set-Location lab-04-sign-and-verify-container-images

Verify:

Terminal window
ls -R

Install Cosign using the approved method for your operating system.

After installation, validate it.

Terminal window
cosign version

Save the version.

Terminal window
cosign version > evidence/cosign-version.txt
Terminal window
cosign version |
Out-File evidence\cosign-version.txt

Record:

Cosign Version:
Git Version:
Build Date:
Go Version:
Operating System:
Installation Method:

Task 03 — Verify the Cosign Binary Source

Section titled “Task 03 — Verify the Cosign Binary Source”

Before using Cosign in an enterprise environment, validate:

  • Download source
  • Release version
  • Release checksum
  • Binary signature
  • Package-manager source
  • Approved software inventory
  • Internal software-distribution policy

Document:

Installation Source:
Release Version:
Checksum Validated:
Signature Validated:
Security Approval:
Installed By:
Installation Date:

Task 04 — Define the Approved Image Reference

Section titled “Task 04 — Define the Approved Image Reference”

Set the image reference using its immutable digest.

Terminal window
export IMAGE="<registry-endpoint>/<repository>@sha256:<approved-digest>"

Verify:

Terminal window
echo "$IMAGE"
Terminal window
$IMAGE = "<registry-endpoint>/<repository>@sha256:<approved-digest>"

Verify:

Terminal window
Write-Host $IMAGE

Save the reference.

Terminal window
echo "$IMAGE" > evidence/image-reference.txt
Terminal window
$IMAGE |
Out-File evidence\image-reference.txt

Task 05 — Confirm Registry Authentication

Section titled “Task 05 — Confirm Registry Authentication”

Authenticate using the approved registry method.

Examples include:

  • Cloud CLI credential helper
  • Workload identity
  • Managed identity
  • Short-lived access token
  • Federated identity

Verify the image can be pulled.

Terminal window
docker pull "$IMAGE"

PowerShell:

Terminal window
docker pull $IMAGE

Do not place registry passwords directly in shell commands.

Inspect the image.

Terminal window
docker image inspect "$IMAGE"

Retrieve repository digests.

Terminal window
docker image inspect "$IMAGE" \
--format='{{json .RepoDigests}}'

Save the digest.

Terminal window
docker image inspect "$IMAGE" \
--format='{{json .RepoDigests}}' \
> evidence/image-digest.txt
Terminal window
docker image inspect $IMAGE `
--format='{{json .RepoDigests}}' |
Out-File evidence\image-digest.txt

Confirm:

  • The digest matches Lab 03.
  • The image exists in the approved registry.
  • The image is not referenced only by a mutable tag.
  • The image is the approved build artifact.

Task 07 — Re-Scan the Image Before Signing

Section titled “Task 07 — Re-Scan the Image Before Signing”

Perform a final vulnerability scan.

Terminal window
trivy image \
--severity HIGH,CRITICAL \
"$IMAGE"

Export the complete report.

Terminal window
trivy image \
--format json \
--output reports/image-scan.json \
"$IMAGE"

Review:

  • Critical vulnerabilities
  • High vulnerabilities
  • Fixed versions
  • Unfixed vulnerabilities
  • Secret findings
  • Image configuration
  • Scan time
  • Scanner version

Do not sign an image merely because the signing command succeeds.

Signing must occur only after required security controls pass.

Task 08 — Define the Signing Approval Gate

Section titled “Task 08 — Define the Signing Approval Gate”

Create an approval checklist.

Control Required Result
Approved source repository Confirmed
Approved build pipeline Confirmed
Immutable image digest Recorded
Critical vulnerability review Completed
High vulnerability review Completed
Secret scan Passed
Malware scan Passed
SBOM generated Completed
Licence review Completed where required
Build provenance Available
Registry destination Approved
Security approval Recorded

Assign one of the following decisions:

  • Approved for Signing
  • Conditionally Approved
  • Rejected
  • Requires Further Investigation

Cosign commonly supports two enterprise signing models.

A private cryptographic key signs the artifact.

Advantages:

  • Can operate with internal key-management systems
  • Can support offline or private trust models
  • Public key can be distributed to verifiers

Risks:

  • Private key must be stored securely
  • Key rotation is required
  • Key compromise can affect all signed artifacts
  • Shared keys weaken attribution

The signer authenticates through an approved OIDC identity provider.

Advantages:

  • No long-lived private signing key for the user
  • Signature is associated with an identity
  • Short-lived certificates can be used
  • Suitable for CI/CD workload identity

Risks:

  • Trust depends on the identity provider
  • Verification must check the expected identity and issuer
  • Identity compromise can result in unauthorised signing
  • Public transparency records may expose non-secret metadata

Use training keys only.

Terminal window
cosign generate-key-pair

Cosign creates:

cosign.key
cosign.pub

Move the public key into the lab directory.

Terminal window
mv cosign.pub keys/cosign.pub
Terminal window
Move-Item cosign.pub keys\cosign.pub

Keep the private key outside source control.

For example:

secure-key-storage/cosign.key

Validate that the private key is not stored in the Git repository.

Create or update .gitignore.

cosign.key
*.key
secure-key-storage/
.env

Review Git status.

Terminal window
git status

On Linux or Git Bash, restrict file permissions where supported.

Terminal window
chmod 600 secure-key-storage/cosign.key

Document:

Key Type:
Key Owner:
Key Location:
Password Protected:
File Permissions:
Backup Location:
Rotation Date:
Revocation Procedure:

Display the public key.

Terminal window
cat keys/cosign.pub

PowerShell:

Terminal window
Get-Content keys\cosign.pub

Save a copy as evidence.

Terminal window
cp keys/cosign.pub evidence/public-key.txt
Terminal window
Copy-Item keys\cosign.pub evidence\public-key.txt

The public key can be distributed to authorised verifiers.

The private key must remain protected.

Task 13 — Sign the Image with the Private Key

Section titled “Task 13 — Sign the Image with the Private Key”

Set the private-key location.

Terminal window
export COSIGN_KEY="secure-key-storage/cosign.key"
Terminal window
$COSIGN_KEY = "secure-key-storage\cosign.key"

Sign the immutable image reference.

Terminal window
cosign sign \
--key "$COSIGN_KEY" \
"$IMAGE"
Terminal window
cosign sign `
--key $COSIGN_KEY `
$IMAGE

Enter the key password securely when prompted.

Do not pass the password directly in shell history.

Capture the signing result without exposing secret data.

Terminal window
cosign sign \
--key "$COSIGN_KEY" \
"$IMAGE" \
> evidence/signing-result.txt 2>&1
Terminal window
cosign sign `
--key $COSIGN_KEY `
$IMAGE *> evidence\signing-result.txt

Record:

Image:
Digest:
Signing Method:
Signing Key Owner:
Signing Time:
Registry:
Signature Storage:
Approval Record:
Result:

Task 15 — Verify the Key-Based Signature

Section titled “Task 15 — Verify the Key-Based Signature”

Verify the image using the public key.

Terminal window
cosign verify \
--key keys/cosign.pub \
"$IMAGE"
Terminal window
cosign verify `
--key keys\cosign.pub `
$IMAGE

Expected result:

  • Signature verification succeeds.
  • The signed image digest matches.
  • Signature payload information is returned.

Export verification output in JSON format.

Terminal window
cosign verify \
--key keys/cosign.pub \
--output json \
"$IMAGE" \
> reports/signature-verification.json
Terminal window
cosign verify `
--key keys\cosign.pub `
--output json `
$IMAGE |
Out-File reports\signature-verification.json

Save the human-readable result.

Terminal window
cosign verify \
--key keys/cosign.pub \
"$IMAGE" \
> evidence/verification-result.txt 2>&1

Task 17 — Inspect the Verification Output

Section titled “Task 17 — Inspect the Verification Output”

Where jq is installed:

Terminal window
jq '.' reports/signature-verification.json

Review:

  • Critical image identity
  • Docker reference
  • Image digest
  • Signature payload
  • Certificate information where applicable
  • Transparency-log data where applicable
  • Verification status

Document:

Verified Image:
Verified Digest:
Signature Count:
Verification Key:
Certificate Identity:
Certificate Issuer:
Transparency Record:
Verification Result:

Task 18 — Generate an Incorrect Test Key

Section titled “Task 18 — Generate an Incorrect Test Key”

Create a separate key pair for negative testing.

Terminal window
mkdir -p test-keys
Terminal window
cd test-keys
Terminal window
cosign generate-key-pair

Return to the lab directory.

Terminal window
cd ..

Do not replace the trusted signing key.

Task 19 — Test Verification with the Incorrect Public Key

Section titled “Task 19 — Test Verification with the Incorrect Public Key”

Attempt verification using the incorrect public key.

Terminal window
cosign verify \
--key test-keys/cosign.pub \
"$IMAGE"

Expected:

Verification failure

Save the result.

Terminal window
cosign verify \
--key test-keys/cosign.pub \
"$IMAGE" \
> evidence/failed-verification.txt 2>&1

PowerShell:

Terminal window
cosign verify `
--key test-keys\cosign.pub `
$IMAGE *> evidence\failed-verification.txt

Confirm that the command returns a non-zero exit code.

Terminal window
echo $?
Terminal window
$LASTEXITCODE

Task 20 — Test Verification of an Unsigned Image

Section titled “Task 20 — Test Verification of an Unsigned Image”

Select an authorised training image that has not been signed.

Terminal window
export UNSIGNED_IMAGE="<registry-endpoint>/<repository>@sha256:<unsigned-digest>"

Attempt verification.

Terminal window
cosign verify \
--key keys/cosign.pub \
"$UNSIGNED_IMAGE"

Expected:

  • No valid signature is found.
  • Verification fails.
  • The image must not pass a signed-image admission policy.

Do not use an unknown public image for enterprise trust testing.

In a supported environment, keyless signing uses an OIDC identity.

The signing identity may represent:

  • A developer
  • A release engineer
  • A GitHub Actions workflow
  • A GitLab pipeline
  • A cloud workload identity
  • An enterprise identity-provider user
  • A controlled build service

The verifier must validate:

  • Expected certificate identity
  • Expected OIDC issuer
  • Image digest
  • Signature integrity
  • Transparency information where required

Use an authorised training identity.

Terminal window
cosign sign "$IMAGE"

Follow the authentication workflow presented by Cosign.

Depending on the environment, this may involve:

  • Browser-based OIDC authentication
  • CI/CD identity token
  • Cloud workload identity
  • Device-code authentication

Record only non-sensitive information.

Signing Identity:
OIDC Issuer:
Signing Time:
Image Digest:
Transparency Entry:
Result:

Verify using the expected identity and issuer.

Terminal window
cosign verify "$IMAGE" \
--certificate-identity="<approved-identity>" \
--certificate-oidc-issuer="<approved-oidc-issuer>"

Example identity forms may include:

release-engineer@example.com

or an approved CI/CD workflow identity.

Do not use broad wildcard identities for production verification without a documented security justification.

Task 24 — Export Keyless Verification Evidence

Section titled “Task 24 — Export Keyless Verification Evidence”
Terminal window
cosign verify "$IMAGE" \
--certificate-identity="<approved-identity>" \
--certificate-oidc-issuer="<approved-oidc-issuer>" \
--output json \
> evidence/keyless-verification.txt

Review:

  • Certificate subject
  • Certificate issuer
  • Image digest
  • Signature time
  • Transparency-log information
  • Verification result

Task 25 — Test an Incorrect Signing Identity

Section titled “Task 25 — Test an Incorrect Signing Identity”

Attempt verification using an identity that did not sign the image.

Terminal window
cosign verify "$IMAGE" \
--certificate-identity="unauthorised@example.com" \
--certificate-oidc-issuer="<approved-oidc-issuer>"

Expected:

Verification failure

This demonstrates that verification must validate signer identity rather than only the presence of a signature.

Use the correct identity but an incorrect issuer.

Terminal window
cosign verify "$IMAGE" \
--certificate-identity="<approved-identity>" \
--certificate-oidc-issuer="https://invalid-issuer.example.com"

Expected:

Verification failure

Document:

Test Expected Actual
Correct identity and issuer Pass
Incorrect identity Fail
Incorrect issuer Fail
Incorrect image digest Fail
Unsigned image Fail

Task 27 — Review Transparency Information

Section titled “Task 27 — Review Transparency Information”

Review the verification output for transparency-related data.

Where supported, document:

Log Entry Identifier:
Integrated Time:
Signed Entry Timestamp:
Log Index:
Certificate Identity:
Certificate Issuer:
Image Digest:

A transparency log can support:

  • Auditability
  • Detection of unexpected signatures
  • Historical verification
  • Incident investigation
  • Software supply-chain monitoring

Do not store confidential application data in public transparency metadata.

Generate an SBOM for the signed image.

Terminal window
trivy image \
--format cyclonedx \
--output attestations/sbom-cyclonedx.json \
"$IMAGE"

Review:

Terminal window
jq '.' attestations/sbom-cyclonedx.json

Count components where supported:

Terminal window
jq '.components | length' \
attestations/sbom-cyclonedx.json

Record:

SBOM Format:
Image:
Image Digest:
Generator:
Generation Time:
Component Count:
Storage Location:

Task 29 — Validate the SBOM Before Attestation

Section titled “Task 29 — Validate the SBOM Before Attestation”

Review the SBOM for:

  • Image identity
  • Package names
  • Package versions
  • Package identifiers
  • Suppliers
  • Licences
  • Dependency relationships
  • Creation timestamp
  • Generator identity

Confirm that the SBOM belongs to the exact image digest being signed.

Task 30 — Create a Vulnerability-Scan Predicate

Section titled “Task 30 — Create a Vulnerability-Scan Predicate”

Create:

attestations/vulnerability-scan-predicate.json

Example:

{
"scanner": {
"name": "Trivy",
"version": "<trivy-version>"
},
"image": {
"reference": "<registry-endpoint>/<repository>",
"digest": "sha256:<approved-digest>"
},
"scan": {
"completed": true,
"scanTime": "<UTC-timestamp>",
"criticalFindings": 0,
"highFindings": 0,
"secretFindings": 0,
"policyResult": "passed"
},
"approval": {
"approvedBy": "<approved-security-role>",
"ticket": "<change-or-approval-reference>"
}
}

Replace placeholders with actual lab values.

Do not include confidential vulnerability details that are not approved for registry storage.

Task 31 — Create a Build-Review Predicate

Section titled “Task 31 — Create a Build-Review Predicate”

Create:

attestations/build-review-predicate.json

Example:

{
"build": {
"repository": "<source-repository>",
"commit": "<git-commit>",
"pipeline": "<pipeline-name>",
"buildId": "<build-id>",
"builder": "<builder-identity>",
"buildTime": "<UTC-timestamp>"
},
"security": {
"sourceReview": "passed",
"dependencyScan": "passed",
"imageScan": "passed",
"secretScan": "passed",
"sbomGenerated": true
},
"release": {
"environment": "training",
"approved": true,
"approvalReference": "<approval-reference>"
}
}

Task 32 — Attach a Key-Based Attestation

Section titled “Task 32 — Attach a Key-Based Attestation”

Create an attestation using the training private key.

Terminal window
cosign attest \
--key "$COSIGN_KEY" \
--predicate attestations/vulnerability-scan-predicate.json \
--type vulnerability-scan \
"$IMAGE"

Record the result.

Terminal window
cosign attest \
--key "$COSIGN_KEY" \
--predicate attestations/vulnerability-scan-predicate.json \
--type vulnerability-scan \
"$IMAGE" \
> evidence/attestation-result.txt 2>&1

Task 33 — Verify the Vulnerability Attestation

Section titled “Task 33 — Verify the Vulnerability Attestation”

Verify using the trusted public key.

Terminal window
cosign verify-attestation \
--key keys/cosign.pub \
--type vulnerability-scan \
"$IMAGE"

Export the result.

Terminal window
cosign verify-attestation \
--key keys/cosign.pub \
--type vulnerability-scan \
--output json \
"$IMAGE" \
> reports/attestation-verification.json

Task 34 — Inspect the Attestation Payload

Section titled “Task 34 — Inspect the Attestation Payload”

Review the verification output.

Terminal window
jq '.' reports/attestation-verification.json

Where required, decode the payload using the structure returned by your installed Cosign version.

Validate:

  • Subject image digest
  • Predicate type
  • Predicate contents
  • Signer
  • Signature
  • Verification result

Document:

Attested Image:
Attested Digest:
Predicate Type:
Scanner:
Policy Result:
Approver:
Verification Key:
Verification Result:

Task 35 — Attach the Build-Review Attestation

Section titled “Task 35 — Attach the Build-Review Attestation”
Terminal window
cosign attest \
--key "$COSIGN_KEY" \
--predicate attestations/build-review-predicate.json \
--type cloudnova-build-review \
"$IMAGE"

Verify it.

Terminal window
cosign verify-attestation \
--key keys/cosign.pub \
--type cloudnova-build-review \
"$IMAGE"

The SBOM should be linked to the exact image digest.

Depending on the approved enterprise workflow, the SBOM may be:

  • Stored as an OCI artifact
  • Signed as a separate OCI artifact
  • Referenced through an attestation
  • Stored in an approved evidence repository
  • Attached to the CI/CD release record

Create an SBOM attestation using the approved predicate type for your environment.

Example workflow:

Terminal window
cosign attest \
--key "$COSIGN_KEY" \
--predicate attestations/sbom-cyclonedx.json \
--type cyclonedx \
"$IMAGE"

Verify:

Terminal window
cosign verify-attestation \
--key keys/cosign.pub \
--type cyclonedx \
"$IMAGE"

Validate command behaviour against the installed Cosign version and enterprise policy before production use.

Task 37 — Sign a Separate SBOM OCI Artifact

Section titled “Task 37 — Sign a Separate SBOM OCI Artifact”

Where the SBOM is stored as an independent OCI artifact, sign it separately.

Example conceptual reference:

<registry-endpoint>/<repository>-sbom@sha256:<sbom-digest>

Sign:

Terminal window
cosign sign \
--key "$COSIGN_KEY" \
"<sbom-oci-reference>"

Verify:

Terminal window
cosign verify \
--key keys/cosign.pub \
"<sbom-oci-reference>"

This allows both the container image and its SBOM artifact to have independent integrity verification.

Task 38 — Review Registry Signature Artifacts

Section titled “Task 38 — Review Registry Signature Artifacts”

Use registry tooling to inspect OCI artifacts associated with the image.

Depending on the platform, review:

  • Signature artifacts
  • Attestations
  • SBOM artifacts
  • Manifest references
  • Artifact digests
  • Creation timestamps
  • Push identity

Document:

Image Digest:
Signature Artifact:
Attestation Artifact:
SBOM Artifact:
Registry:
Created Time:
Created By:

Task 39 — Compare Signing and Attestation

Section titled “Task 39 — Compare Signing and Attestation”
Control Purpose
Image signature Proves integrity and association with a signing identity
Vulnerability attestation States the result of a vulnerability assessment
Build attestation Records build and pipeline information
SBOM attestation Associates software inventory with the image
Admission policy Evaluates trust requirements before deployment
Runtime monitoring Detects suspicious behaviour after deployment

A valid image signature does not automatically validate the truth of every attestation.

The attestation signer and predicate must also be trusted.

Task 40 — Define Trusted Signing Identities

Section titled “Task 40 — Define Trusted Signing Identities”

Create:

policies/trusted-identities.md

Example:

Production Human Signers:
- release-security@example.com
Approved CI/CD Identities:
- GitHub Actions release workflow
- Enterprise build-service workload identity
- Controlled production release pipeline
Approved OIDC Issuers:
- Enterprise identity provider
- Approved CI/CD identity provider
Prohibited Identities:
- Personal accounts
- Shared accounts
- Unmanaged external identities
- Development pipelines
- Forked repository workflows
Required Verification:
- Exact image digest
- Approved certificate identity
- Approved OIDC issuer
- Approved repository
- Required vulnerability attestation
- Required SBOM attestation

Create an enterprise responsibility matrix.

Activity Developer CI/CD Security Release Manager Platform
Commit code Yes No No No No
Build image No Yes No No No
Scan image No Yes Review No No
Generate SBOM No Yes Review No No
Approve exception No No Yes Yes No
Sign production image No Controlled Controlled Approve No
Verify signature No Yes Yes Yes Yes
Deploy image No Controlled No Approve Yes
Change admission policy No No Review No Yes

Avoid allowing one uncontrolled identity to:

  • Build
  • Approve
  • Sign
  • Deploy
  • Change verification policy

Task 42 — Create the Enterprise Signing Policy

Section titled “Task 42 — Create the Enterprise Signing Policy”

Create:

policies/enterprise-signing-policy.md

Include:

Policy Name:
CloudNova Container Image Signing Policy
Scope:
Approved Registries:
Approved Repositories:
Approved Signing Methods:
Approved Signing Identities:
Approved OIDC Issuers:
Approved Key Management Systems:
Required Image Digest:
Required Vulnerability Attestation:
Required SBOM Attestation:
Required Build Provenance:
Maximum Signature Age:
Key-Rotation Period:
Certificate Verification Requirements:
Transparency Requirements:
Emergency Exception Process:
Revocation Process:
Incident Response:
Evidence Retention:

Task 43 — Define Signing-Key Storage Requirements

Section titled “Task 43 — Define Signing-Key Storage Requirements”

Production signing keys should be protected using approved services such as:

  • Hardware Security Module
  • Cloud Key Management Service
  • Enterprise key vault
  • Managed signing service
  • Isolated release system

Production controls should include:

  • Non-exportable private keys where possible
  • MFA for key administrators
  • Key-use audit logging
  • Least-privilege access
  • Dual approval
  • Rotation
  • Revocation
  • Backup and recovery
  • Incident response

Local files are suitable only for controlled training and development use.

Task 44 — Create a Signing-Key Rotation Procedure

Section titled “Task 44 — Create a Signing-Key Rotation Procedure”

Create:

policies/signing-key-rotation.md

Include:

Current Key Identifier:
Key Owner:
Key Creation Date:
Key Expiration Date:
Rotation Frequency:
New Key Generation Method:
Public Key Distribution:
Policy Update Procedure:
Old Signature Verification Period:
Old Key Revocation:
Compromise Response:
Evidence Retention:
Approval Requirements:

Task 45 — Define Signing-Key Compromise Response

Section titled “Task 45 — Define Signing-Key Compromise Response”

Create:

policies/signing-incident-response.md

Required actions:

  1. Declare a software supply-chain security incident.
  2. Disable or revoke the compromised signing identity.
  3. Preserve key-usage logs.
  4. Identify every image signed by the affected identity.
  5. Block new deployments using the compromised trust root.
  6. Evaluate currently running workloads.
  7. Re-scan and rebuild trusted images.
  8. Sign approved replacement images with a new identity.
  9. Update admission policies.
  10. Notify application and platform owners.
  11. Document residual risk.
  12. Conduct a root-cause review.

Task 46 — Create the Kubernetes Namespace

Section titled “Task 46 — Create the Kubernetes Namespace”

Create:

kubernetes/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: signed-image-lab
labels:
environment: training
owner: cloud-security
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/warn: restricted

Apply it.

Terminal window
kubectl apply \
-f kubernetes/namespace.yaml

Verify:

Terminal window
kubectl get namespace signed-image-lab \
--show-labels

Task 47 — Create the Signed Image Deployment

Section titled “Task 47 — Create the Signed Image Deployment”

Create:

kubernetes/signed-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: signed-application
namespace: signed-image-lab
labels:
app: signed-application
environment: training
owner: cloud-security
spec:
replicas: 2
selector:
matchLabels:
app: signed-application
template:
metadata:
labels:
app: signed-application
environment: training
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: application
image: <registry-endpoint>/<repository>@sha256:<signed-image-digest>
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 5000
securityContext:
privileged: false
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 250m
memory: 256Mi
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 15
periodSeconds: 20
volumeMounts:
- name: temporary-files
mountPath: /tmp
volumes:
- name: temporary-files
emptyDir: {}

Add an approved imagePullSecrets configuration only when native registry identity is unavailable.

Before applying the Deployment, independently verify the image.

Terminal window
cosign verify \
--key keys/cosign.pub \
"$IMAGE"

Verify required attestations.

Terminal window
cosign verify-attestation \
--key keys/cosign.pub \
--type vulnerability-scan \
"$IMAGE"
Terminal window
cosign verify-attestation \
--key keys/cosign.pub \
--type cyclonedx \
"$IMAGE"

Only continue when all required checks pass.

Task 49 — Validate the Kubernetes Manifest

Section titled “Task 49 — Validate the Kubernetes Manifest”
Terminal window
kubectl apply \
--dry-run=client \
-f kubernetes/signed-deployment.yaml

Confirm:

  • Image uses an immutable digest.
  • Digest matches the signed image.
  • Image exists in the approved registry.
  • Service Account token is disabled.
  • Pod Security requirements are satisfied.
  • Resources and probes are configured.
  • Root filesystem is read-only.
  • Capabilities are dropped.

Apply the Deployment.

Terminal window
kubectl apply \
-f kubernetes/signed-deployment.yaml

Monitor rollout.

Terminal window
kubectl rollout status \
deployment/signed-application \
-n signed-image-lab

Review Pods.

Terminal window
kubectl get pods \
-n signed-image-lab \
-o wide

Task 51 — Validate the Runtime Image Identity

Section titled “Task 51 — Validate the Runtime Image Identity”

Retrieve the configured image.

Terminal window
kubectl get pod \
<pod-name> \
-n signed-image-lab \
-o jsonpath='{.spec.containers[*].image}{"\n"}'

Retrieve the runtime image ID.

Terminal window
kubectl get pod \
<pod-name> \
-n signed-image-lab \
-o jsonpath='{.status.containerStatuses[*].imageID}{"\n"}'

Confirm:

  • The image came from the approved registry.
  • The configured digest matches the signature.
  • The runtime image ID matches the approved digest.

Check runtime identity.

Terminal window
kubectl exec \
<pod-name> \
-n signed-image-lab \
-- id

Review security status.

Terminal window
kubectl exec \
<pod-name> \
-n signed-image-lab \
-- sh -c "grep -E 'NoNewPrivs|CapEff|Seccomp' /proc/1/status"

Attempt to write to a protected path.

Terminal window
kubectl exec \
<pod-name> \
-n signed-image-lab \
-- touch /etc/signature-test

Expected:

Read-only file system

Task 53 — Prepare an Unsigned Deployment Test

Section titled “Task 53 — Prepare an Unsigned Deployment Test”

Create:

kubernetes/unsigned-deployment.yaml

Use an authorised but unsigned training-image digest.

apiVersion: apps/v1
kind: Deployment
metadata:
name: unsigned-application
namespace: signed-image-lab
spec:
replicas: 1
selector:
matchLabels:
app: unsigned-application
template:
metadata:
labels:
app: unsigned-application
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: application
image: <registry-endpoint>/<repository>@sha256:<unsigned-image-digest>
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL

Do not deploy the unsigned image into production.

Task 54 — Create an Admission-Policy Design

Section titled “Task 54 — Create an Admission-Policy Design”

Create:

kubernetes/cluster-image-policy-example.yaml

Conceptual Sigstore Policy Controller example:

apiVersion: policy.sigstore.dev/v1beta1
kind: ClusterImagePolicy
metadata:
name: cloudnova-signed-images
spec:
images:
- glob: "<registry-endpoint>/<repository>**"
authorities:
- name: cloudnova-trusted-key
key:
data: |
-----BEGIN PUBLIC KEY-----
<PUBLIC-KEY-CONTENT>
-----END PUBLIC KEY-----

The exact API version and configuration must match the policy-controller version installed in the target cluster.

Do not apply an untested cluster-wide policy directly to production.

The production admission policy should validate:

  • Approved registry
  • Approved repository
  • Immutable image digest
  • Valid image signature
  • Approved signing key or identity
  • Approved OIDC issuer
  • Required vulnerability attestation
  • Required SBOM attestation
  • Required build provenance
  • No prohibited emergency bypass
  • Policy audit logging

Expected decisions:

Image Condition Admission Decision
Signed by approved identity Allow
Signed by unapproved identity Reject
Signature invalid Reject
Image unsigned Reject
Digest differs from signature Reject
Required attestation missing Reject
Registry not approved Reject
Formal emergency exception Controlled temporary decision

Task 56 — Test Verification as a CI/CD Gate

Section titled “Task 56 — Test Verification as a CI/CD Gate”

Create a verification script.

#!/usr/bin/env bash
set -euo pipefail
IMAGE="${1:?Usage: verify-image.sh <image-by-digest>}"
cosign verify \
--key keys/cosign.pub \
"$IMAGE"
cosign verify-attestation \
--key keys/cosign.pub \
--type vulnerability-scan \
"$IMAGE"
cosign verify-attestation \
--key keys/cosign.pub \
--type cyclonedx \
"$IMAGE"
echo "Image trust verification passed."

Save as:

verify-image.sh

Make it executable.

Terminal window
chmod +x verify-image.sh

Run:

Terminal window
./verify-image.sh "$IMAGE"

Task 57 — Validate CI/CD Failure Behaviour

Section titled “Task 57 — Validate CI/CD Failure Behaviour”

Run the verification script against:

  • Correct signed image
  • Unsigned image
  • Image signed by a different key
  • Image without required attestation
  • Incorrect digest
  • Image from an unapproved registry

Record:

Test Expected Result Actual Result
Approved signed image Pass
Unsigned image Fail
Incorrect signing key Fail
Missing vulnerability attestation Fail
Missing SBOM attestation Fail
Incorrect digest Fail
Unapproved registry Fail

Task 58 — Review Signature Revocation Challenges

Section titled “Task 58 — Review Signature Revocation Challenges”

Image signatures are attached to immutable artifacts, but trust can change after signing.

Examples:

  • Signing key compromised
  • Signing identity disabled
  • CI/CD pipeline compromised
  • Image later found malicious
  • New critical vulnerability discovered
  • Approval granted incorrectly
  • Registry account compromised

Enterprise controls should maintain:

  • Denied image digest list
  • Revoked signing-key list
  • Revoked identity list
  • Incident quarantine repository
  • Admission-policy updates
  • Runtime image inventory
  • Emergency workload replacement procedure

Task 59 — Create an Image Denylist Procedure

Section titled “Task 59 — Create an Image Denylist Procedure”

Document:

Image Digest:
Registry:
Repository:
Reason for Denial:
Incident ID:
Detection Time:
Affected Clusters:
Affected Workloads:
Signature Identity:
Required Containment:
Replacement Image:
Admission Policy Updated:
Owner:
Status:

A previously valid signature must not override a current security decision to block a compromised image.

Task 60 — Perform the Enterprise Image-Trust Assessment

Section titled “Task 60 — Perform the Enterprise Image-Trust Assessment”

Complete the assessment.

Security Domain Expected Control Status
Approved registry Image stored in trusted registry
Immutable identity Digest recorded
Vulnerability scan Passed
Secret scan Passed
SBOM Generated
Signing approval Recorded
Image signature Present
Signature validity Verified
Signer identity Approved
OIDC issuer Approved
Public key Trusted
Vulnerability attestation Verified
SBOM attestation Verified
Build provenance Available
Transparency evidence Reviewed
Key storage Protected
Key rotation Documented
Revocation Documented
Admission enforcement Designed or enabled
Deployment digest Matches signed image
Runtime image Matches approved digest
Evidence Retained

Rate each control as:

  • Effective
  • Partially Effective
  • Ineffective
  • Not Applicable

Task 61 — Assign the Image-Trust Risk Rating

Section titled “Task 61 — Assign the Image-Trust Risk Rating”

Examples:

  • Production image signed by a compromised key
  • Malicious image signed and deployed
  • Admission verification disabled
  • Signing private key exposed
  • Image digest does not match approved artifact
  • Unauthorised identity trusted for production signing
  • Registry signature artifacts tampered with or unavailable

Examples:

  • Production image is unsigned
  • Signature is not independently verified
  • Signer identity is not restricted
  • OIDC issuer is not validated
  • Shared signing key used by multiple teams
  • Required attestation is missing
  • Private key stored in source control
  • No revocation procedure exists
  • Mutable tag signed without digest control

Examples:

  • Key rotation overdue
  • SBOM not signed
  • Transparency monitoring absent
  • Manual verification only
  • Incomplete separation of duties
  • Signature evidence-retention gap
  • No automated denylist process

Examples:

  • Missing descriptive metadata
  • Incomplete ownership label
  • Reporting-format inconsistency
  • Minor documentation gap
  • Non-production policy warning

Task 62 — Create the Image Trust Assessment

Section titled “Task 62 — Create the Image Trust Assessment”

Create:

reports/image-trust-assessment.md

Include:

Assessment Name:
Enterprise Container Image Trust Assessment
Assessment Date:
Assessor:
Application:
Business Owner:
Technical Owner:
Registry:
Repository:
Image Tag:
Image Digest:
Build Pipeline:
Source Commit:
Vulnerability Scan:
Secret Scan:
SBOM:
Signing Method:
Signing Identity:
Signing Key Identifier:
OIDC Issuer:
Signature Verification:
Transparency Evidence:
Vulnerability Attestation:
SBOM Attestation:
Build Attestation:
Admission Policy:
Deployment Manifest:
Runtime Image ID:
Critical Findings:
High Findings:
Medium Findings:
Low Findings:
Residual Risk:
Trust Decision:
Trusted
Conditionally Trusted
Untrusted
Requires Further Investigation

Task 63 — Create the Enterprise Signing Security Report

Section titled “Task 63 — Create the Enterprise Signing Security Report”

Create:

reports/image-signing-security-report.md
Report Title:
Enterprise Container Image Signing and Verification Report
Assessment Date:
Assessor:
Environment:
Application:
Application Owner:
Registry Platform:
Registry Endpoint:
Repository:
Image Reference:
Image Digest:
Image Build ID:
Source Commit:
Security Scan Status:
Critical Vulnerabilities:
High Vulnerabilities:
Secret Findings:
SBOM Format:
SBOM Digest:
Signing Method:
Key-Based
Identity-Based
Signing Identity:
Signing Key Identifier:
Certificate Identity:
OIDC Issuer:
Signing Time:
Signature Verification Result:
Transparency Log Result:
Vulnerability Attestation Result:
SBOM Attestation Result:
Build Attestation Result:
Admission Policy Status:
Kubernetes Deployment Result:
Runtime Image Digest:
Separation of Duties:
Key Protection:
Key Rotation:
Revocation Readiness:
Critical Findings:
High Findings:
Medium Findings:
Low Findings:
Required Remediation:
Residual Risk:
Overall Risk Rating:
Production Decision:
Approved
Conditionally Approved
Rejected
Approvals:
Application Security:
DevSecOps:
Cloud Security:
Kubernetes Security:
Platform Engineering:
Release Manager:

Collect evidence for:

  • Cosign version
  • Installation verification
  • Image reference
  • Image digest
  • Image vulnerability scan
  • Image signing approval
  • Public signing key
  • Private-key protection review
  • Signing result
  • Signature-verification result
  • Incorrect-key verification failure
  • Unsigned-image verification failure
  • Keyless signing result
  • Certificate identity
  • OIDC issuer
  • Transparency information
  • CycloneDX SBOM
  • Vulnerability predicate
  • Build-review predicate
  • Vulnerability attestation
  • SBOM attestation
  • Attestation verification
  • Trusted identity policy
  • Key-rotation policy
  • Incident-response procedure
  • Kubernetes Deployment
  • Runtime image ID
  • Admission-policy design
  • CI/CD gate test
  • Enterprise image-trust assessment
  • Final signing security report

Suggested filenames:

01-cosign-version.txt
02-cosign-installation-verification.txt
03-image-reference.txt
04-image-digest.txt
05-image-scan.json
06-signing-approval.md
07-public-key.txt
08-private-key-protection.md
09-signing-result.txt
10-signature-verification.json
11-incorrect-key-failure.txt
12-unsigned-image-failure.txt
13-keyless-signing-result.txt
14-certificate-identity.txt
15-oidc-issuer.txt
16-transparency-record.json
17-sbom-cyclonedx.json
18-vulnerability-predicate.json
19-build-review-predicate.json
20-vulnerability-attestation.json
21-sbom-attestation.json
22-attestation-verification.json
23-trusted-identities.md
24-key-rotation.md
25-signing-incident-response.md
26-signed-deployment.yaml
27-runtime-image-id.txt
28-admission-policy-example.yaml
29-cicd-gate-results.txt
30-image-trust-assessment.md
31-image-signing-security-report.md

Delete the training namespace.

Terminal window
kubectl delete namespace signed-image-lab

Verify:

Terminal window
kubectl get namespace signed-image-lab

Expected:

NotFound

Delete only the disposable negative-test keys.

Terminal window
rm -rf test-keys
Terminal window
Remove-Item -Recurse -Force test-keys

Do not delete keys required for ongoing verification or evidence.

Task 67 — Secure or Destroy the Training Private Key

Section titled “Task 67 — Secure or Destroy the Training Private Key”

When the training key is no longer required:

  • Confirm no additional labs depend on it.
  • Preserve the public key where required.
  • Preserve verification evidence.
  • Remove the private key using the approved secure-deletion procedure.
  • Document the destruction.
  • Do not place the private key in the evidence directory.

Create a destruction record:

Key Identifier:
Key Owner:
Key Location:
Destruction Date:
Destroyed By:
Destruction Method:
Approved By:
Evidence Reference:

Enterprise Container Image Signing Checklist

Section titled “Enterprise Container Image Signing Checklist”
Control Status
Image stored in approved registry
Image referenced by immutable digest
Image vulnerability scan completed
Secret scan completed
Signing approval recorded
Cosign installation verified
Private signing key protected
Private key excluded from Git
Public key distributed securely
Image signature created
Signature verified independently
Incorrect-key verification tested
Unsigned-image verification tested
Approved signing identity defined
Approved OIDC issuer defined
Keyless verification tested
Transparency information reviewed
CycloneDX SBOM generated
Vulnerability attestation created
Vulnerability attestation verified
SBOM attestation created
SBOM attestation verified
Build-review attestation created
Signing identities documented
Separation of duties implemented
Key rotation documented
Revocation procedure documented
Signing incident procedure documented
Kubernetes image uses signed digest
Runtime image ID validated
Admission policy prepared
CI/CD verification gate tested
Evidence retained
Security report approved
  • Revoke exposed signing keys.
  • Block images signed by compromised identities.
  • Reject unsigned production images.
  • Require immutable digest references.
  • Remove private keys from source repositories.
  • Restrict trusted signing identities.
  • Validate the OIDC issuer during verification.
  • Preserve evidence relating to suspicious signatures.
  • Move signing keys into managed key storage.
  • Implement automated verification in CI/CD.
  • Require vulnerability attestations.
  • Require SBOM attestations.
  • Define signing-key rotation.
  • Implement image-denylist controls.
  • Separate build, signing and deployment duties.
  • Monitor registry signature events.
  • Adopt workload-identity-based signing.
  • Implement Kubernetes admission enforcement.
  • Require build provenance.
  • Integrate signature policy with GitOps.
  • Monitor transparency records.
  • Automate signing-identity revocation.
  • Establish multi-cluster trust-policy management.
  • Conduct regular software supply-chain incident exercises.

By completing this lab, you will be able to:

  • Explain container-image signing and verification
  • Install and validate Cosign
  • Identify images by immutable digest
  • Generate and protect signing keys
  • Sign images using a private key
  • Verify images using a trusted public key
  • Perform identity-based keyless signing
  • Validate certificate identities and OIDC issuers
  • Review transparency evidence
  • Generate CycloneDX SBOMs
  • Create signed attestations
  • Verify vulnerability and SBOM attestations
  • Test signature-verification failure
  • Define trusted signing identities
  • Implement separation of duties
  • Design signing-key rotation and revocation
  • Prepare Kubernetes admission policies
  • Build CI/CD signature-verification gates
  • Produce enterprise image-trust reports

Why should a container image be signed by digest rather than only by tag?

  • A. Digests increase image size.
  • B. A digest identifies immutable image content, while a tag can be changed.
  • C. Tags automatically encrypt container images.
  • D. Digests replace vulnerability scanning.

Answer: B

What must be protected during key-based image signing?

  • A. The public key
  • B. The private signing key
  • C. The image tag
  • D. The Kubernetes namespace label

Answer: B

What does signature verification confirm?

  • A. The application has no vulnerabilities.
  • B. The image matches the signed artifact and the signature was produced by a trusted key or identity.
  • C. The Kubernetes cluster is fully secure.
  • D. The image does not require runtime monitoring.

Answer: B

Why must keyless verification check the certificate identity?

  • A. To ensure the image was signed by the expected person or workload identity
  • B. To increase Pod replicas
  • C. To create a Kubernetes Secret
  • D. To reduce container memory

Answer: A

Why must the OIDC issuer also be verified?

  • A. The same identity string could otherwise be accepted from an untrusted identity provider.
  • B. The issuer controls container CPU.
  • C. The issuer generates the SBOM.
  • D. The issuer replaces the registry.

Answer: A

What is the purpose of an attestation?

  • A. To record a signed statement about an artifact, such as scan, build or SBOM information
  • B. To replace the container image
  • C. To create a Kubernetes node
  • D. To disable image scanning

Answer: A

Does a valid signature prove that the application is vulnerability-free?

  • A. Yes
  • B. No, signing confirms integrity and identity but does not guarantee application security.
  • C. Yes, when Cosign is used.
  • D. Yes, when the registry is private.

Answer: B

What should happen when an image is signed by an unapproved identity?

  • A. The image should automatically deploy.
  • B. Verification policy should reject the image.
  • C. The image should be tagged latest.
  • D. The signature should replace the SBOM.

Answer: B

Why should signing and deployment duties be separated?

  • A. To prevent a single uncontrolled identity from building, approving, signing and deploying software
  • B. To increase registry storage
  • C. To disable audit logging
  • D. To allow anonymous image pushes

Answer: A

What should happen when a signing key is compromised?

  • A. Continue trusting all signatures permanently.
  • B. Revoke trust, identify affected images, block unsafe deployments and sign approved replacements using a new trusted identity.
  • C. Delete all Kubernetes namespaces without investigation.
  • D. Publish the private key for troubleshooting.

Answer: B

In this lab, you implemented an enterprise container-image signing and verification workflow using Cosign.

You:

  • Installed and validated Cosign
  • Identified an approved image by immutable digest
  • Re-scanned the image before signing
  • Defined a signing approval gate
  • Generated a training signing-key pair
  • Protected the private signing key
  • Signed the image using key-based signing
  • Verified the signature using the public key
  • Tested verification using an incorrect key
  • Tested verification of an unsigned image
  • Performed identity-based signing where supported
  • Verified certificate identity and OIDC issuer
  • Reviewed transparency information
  • Generated a CycloneDX SBOM
  • Created vulnerability and build-review predicates
  • Attached signed attestations
  • Verified image attestations
  • Prepared a signed Kubernetes Deployment
  • Designed an admission-policy workflow
  • Built a CI/CD verification gate
  • Defined trusted signing identities
  • Documented key rotation and compromise response
  • Produced an enterprise image-trust assessment

Container-image signing establishes a cryptographic trust relationship between:

  • The image artifact
  • Its immutable digest
  • The signing identity
  • Associated security evidence
  • The deployment decision

A mature image-trust programme combines:

  • Secure builds
  • Image scanning
  • Secret detection
  • SBOM generation
  • Image signing
  • Identity verification
  • Build provenance
  • Registry governance
  • Admission enforcement
  • Runtime security

Next Lab: Lab 05 — Enforce Trusted Images with Admission Policies

In the next lab, you will deploy or configure a Kubernetes admission-policy solution, define trusted image authorities, allow only approved registries, require valid image signatures, verify image attestations, reject unsigned workloads, test policy audit and enforcement modes, implement controlled exceptions, and produce an enterprise admission-security assessment.