Verify Kloudfuse Container Image Signatures

All Kloudfuse container images in AWS ECR are cryptographically signed using cosign and an AWS KMS key. You can verify these signatures to ensure image authenticity and integrity before deployment.

Overview

Kloudfuse signs all container images stored in AWS Elastic Container Registry (ECR) using asymmetric cryptography. This ensures that:

  • Images originate from Kloudfuse

  • Images have not been tampered with or modified

  • You can verify authenticity without needing Kloudfuse’s private key

Signing Key

AWS KMS key owned by Kloudfuse

Key ARN

arn:aws:kms:us-west-2:502496443919:alias/kfuse-cosign-signing-key

ECR Registry

502496443919.dkr.ecr.us-west-2.amazonaws.com/kfuse

Signature Algorithm

ECDSA with P-256 curve (NIST standard)

How Image Signatures Work

Signing Process (Kloudfuse)

  1. Kloudfuse signs images using a private key stored securely in AWS KMS

  2. Signatures are stored as OCI artifacts in ECR with .sig tags

  3. The private key never leaves AWS KMS

Verification Process (Customers)

  1. You verify signatures using the corresponding public key

  2. The public key is derived from the KMS key (read-only access)

  3. No secrets or credentials are required for verification

Asymmetric Cryptography

  • Private Key → Only Kloudfuse can sign images

  • Public Key → Anyone can verify signatures (proving authenticity)

Method 1: Verify Using AWS KMS (Recommended)

This method uses AWS KMS directly for verification and is recommended for production environments.

Prerequisites

  1. AWS IAM Permissions - Your IAM role or user needs the following permissions:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "kms:GetPublicKey",
            "kms:Verify",
            "kms:DescribeKey"
          ],
          "Resource": "arn:aws:kms:us-west-2:502496443919:key/*"
        }
      ]
    }
    json
  2. Cosign installed - See Install Cosign below

  3. ECR access - Separate permissions to pull images from ECR

Verify an Image

Run the following command to verify a Kloudfuse image:

cosign verify \
  --key awskms:///arn:aws:kms:us-west-2:502496443919:alias/kfuse-cosign-signing-key \
  502496443919.dkr.ecr.us-west-2.amazonaws.com/kfuse/ui:0.1.0-b2274ac0
bash

Successful verification output:

Verification for 502496443919.dkr.ecr.us-west-2.amazonaws.com/kfuse/ui:0.1.0-b2274ac0 --
The following checks were performed on each of these signatures:
  - The cosign claims were validated
  - Existence of the claims in the transparency log was verified offline
  - The signatures were verified against the specified public key
text

Example: Verify in CI/CD Pipeline

This example shows how to verify Kloudfuse images in a GitLab CI pipeline:

verify-kfuse-image:
  stage: verify
  image: alpine:latest
  variables:
    IMAGE_NAME: ui
    IMAGE_TAG: "0.1.0-b2274ac0"
    COSIGN_VERSION: "v2.4.0"
    KMS_KEY: "awskms:///arn:aws:kms:us-west-2:502496443919:alias/kfuse-cosign-signing-key"
  before_script:
    - apk add --no-cache curl aws-cli
    - curl -sSfL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64" -o /usr/local/bin/cosign
    - chmod +x /usr/local/bin/cosign
  script:
    - |
      IMAGE_REF="502496443919.dkr.ecr.us-west-2.amazonaws.com/kfuse/${IMAGE_NAME}:${IMAGE_TAG}"
      if cosign verify --key "${KMS_KEY}" "${IMAGE_REF}"; then
        echo "✅ Image signature verified successfully"
      else
        echo "❌ Image signature verification FAILED"
        exit 1
      fi
yaml

Method 2: Verify Using Public Key File

This method uses a downloaded public key file and does not require AWS credentials for verification.

Get the Public Key

Kloudfuse provides the public key. You can also extract it yourself:

aws kms get-public-key \
  --key-id arn:aws:kms:us-west-2:502496443919:alias/kfuse-cosign-signing-key \
  --region us-west-2 \
  --query 'PublicKey' \
  --output text | base64 --decode > kfuse-cosign-public-key.pem
bash

Public Key (PEM format):

-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEg5MTbws6zhPPlz8EKgcyOX+y2BCd
bLVOMHCG3FjpS4JGijEcbKJ9gd13lHbWZuZkFk2I3BVZIctOjvrf+BgIgg==
-----END PUBLIC KEY-----
text

Verify Using Public Key

cosign verify \
  --key kfuse-cosign-public-key.pem \
  502496443919.dkr.ecr.us-west-2.amazonaws.com/kfuse/ui:0.1.0-b2274ac0
bash
Advantages
  • No AWS credentials needed

  • Faster (no KMS API calls)

  • Works in air-gapped environments

Disadvantages
  • Need to manage and distribute public key file

  • Manual updates if key is rotated

Install Cosign

Homebrew (macOS/Linux):

brew install cosign
cosign version
bash

Alpine Linux:

apk add cosign
bash

Arch Linux:

pacman -S cosign
bash

Binary Installation

Linux (x86_64)

set -e  # Exit on error

# Pin to specific version; update periodically from https://github.com/sigstore/cosign/releases
COSIGN_VERSION="v3.0.3"

# Download cosign binary and checksums
curl -sSfL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-linux-amd64" -o /tmp/cosign-linux-amd64
curl -sSfL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign_checksums.txt" -o /tmp/checksums.txt

# Verify checksum (filename must match checksums.txt)
cd /tmp && sha256sum --check --ignore-missing checksums.txt

# Install cosign
chmod +x /tmp/cosign-linux-amd64
sudo mv /tmp/cosign-linux-amd64 /usr/local/bin/cosign

# Verify installation
cosign version
bash

macOS (ARM64)

set -e  # Exit on error

COSIGN_VERSION="v3.0.3"

# Download cosign binary and checksums
curl -sSfL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-darwin-arm64" -o /tmp/cosign-darwin-arm64
curl -sSfL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign_checksums.txt" -o /tmp/checksums.txt

# Verify checksum
cd /tmp && sha256sum --check --ignore-missing checksums.txt

# Install cosign
chmod +x /tmp/cosign-darwin-arm64
sudo mv /tmp/cosign-darwin-arm64 /usr/local/bin/cosign

# Verify installation
cosign version
bash

macOS (Intel x86_64)

set -e  # Exit on error

COSIGN_VERSION="v3.0.3"

# Download cosign binary and checksums
curl -sSfL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign-darwin-amd64" -o /tmp/cosign-darwin-amd64
curl -sSfL "https://github.com/sigstore/cosign/releases/download/${COSIGN_VERSION}/cosign_checksums.txt" -o /tmp/checksums.txt

# Verify checksum
cd /tmp && shasum -a 256 --check --ignore-missing checksums.txt

# Install cosign
chmod +x /tmp/cosign-darwin-amd64
sudo mv /tmp/cosign-darwin-amd64 /usr/local/bin/cosign

# Verify installation
cosign version
bash

Container Image

docker run --rm \
  -v $(pwd):/workspace \
  ghcr.io/sigstore/cosign/cosign:v3.0.3 \
  verify --key awskms:///arn:aws:kms:us-west-2:502496443919:alias/kfuse-cosign-signing-key \
  502496443919.dkr.ecr.us-west-2.amazonaws.com/kfuse/ui:0.1.0-b2274ac0
bash

Automated Verification in Kubernetes

Use admission controllers to automatically verify signatures before pod creation.

Kyverno Policy Example

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-kfuse-images
spec:
  validationFailureAction: Enforce
  background: false
  rules:
    - name: verify-signature
      match:
        any:
        - resources:
            kinds:
              - Pod
      verifyImages:
      - imageReferences:
        - "502496443919.dkr.ecr.us-west-2.amazonaws.com/kfuse/*"
        attestors:
        - entries:
          - keys:
              publicKeys: |
                -----BEGIN PUBLIC KEY-----
                MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEg5MTbws6zhPPlz8EKgcyOX+y2BCd
                bLVOMHCG3FjpS4JGijEcbKJ9gd13lHbWZuZkFk2I3BVZIctOjvrf+BgIgg==
                -----END PUBLIC KEY-----
yaml

Troubleshooting

"Access Denied" when using KMS key

Cause: Missing IAM permissions
Solution: Add KMS permissions (kms:GetPublicKey, kms:Verify, kms:DescribeKey) to your IAM role

"No matching signatures"

Cause: Image is not signed or signature was not found
Solution: Verify the image tag is correct and check if signature exists:

aws ecr list-images \
  --repository-name kfuse/ui \
  --region us-west-2 | grep ".sig"
bash
"MANIFEST_UNKNOWN"

Cause: Image doesn’t exist in ECR
Solution: Verify the image reference is correct and image exists

Security Best Practices

  1. Verify all images before deployment

  2. Use admission controllers to enforce verification at deployment time

  3. Monitor verification failures and alert on unsigned images

  4. Regularly audit signature coverage across your deployments

  5. Keep cosign updated to the latest stable version

Frequently Asked Questions

Do I need Kloudfuse’s private key to verify signatures?

No. You only need the public key, which is freely available.

Can signatures be forged?

No. Signatures can only be created with the private key in Kloudfuse’s KMS, which never leaves AWS.

What if I can’t access AWS KMS?

Use Method 2 with the exported public key (no AWS access required).

Are signatures stored in the image?

No. Signatures are stored as separate OCI artifacts in ECR with .sig tags.

What if Kloudfuse rotates the signing key?

Kloudfuse will notify customers, provide the new public key, and sign new images with the new key. Old signatures remain valid.

Support

For questions or issues: