Verify Image Signatures :: Kloudfuse Docs

Verify Image Signatures

Overview

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

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 using 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/*"
       }
     ]
}
  1. Cosign installed - See Install Cosign

  2. 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

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

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

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 directly. You can also extract it yourself using the following command:

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

Public Key (PEM format):

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

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

Advantages

Disadvantages

Install Cosign

Package Managers (Recommended)

Homebrew (macOS/Linux):

brew install cosign
cosign version

Alpine Linux:

apk add cosign

Arch Linux:

pacman -S cosign

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

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

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

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

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-----

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"

"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: Verify Using Public Key File 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.