# Verify Image Signatures

All Kloudfuse container images in AWS ECR are cryptographically signed using [cosign](https://github.com/sigstore/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 image 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 using read-only access
3. No secrets or credentials are required for verification

|     |     |
| --- | --- |
|  | **Asymmetric Cryptography**<br>- **Private Key** → Only Kloudfuse can sign images<br>  <br>- **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:

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

2. **Cosign installed** - See [Install Cosign](https://docs.kloudfuse.com/platform/4.0.2/setup/advanced/image-signature-verification/#install-cosign)
3. **ECR access** - Separate permissions to pull images from ECR

### Verify an Image

Run the following command to verify a Kloudfuse image:

```bash
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:**

```text
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:

```yaml
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:

```bash
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):**

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

### Verify Using Public Key

```bash
cosign verify \
  --key kfuse-cosign-public-key.pem \
  502496443919.dkr.ecr.us-west-2.amazonaws.com/kfuse/ui:0.1.0-b2274ac0
```

## Install Cosign

### Package Managers (Recommended)

**Homebrew (macOS/Linux):**

```bash
brew install cosign
cosign version
```

**Alpine Linux:**

```bash
apk add cosign
```

**Arch Linux:**

```bash
pacman -S cosign
```

### Binary Installation

#### Linux (x86_64)

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

## Automated Verification in Kubernetes

Use admission controllers to automatically verify signatures before pod creation.

### Kyverno Policy Example

```yaml
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:

```bash
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](https://docs.kloudfuse.com/platform/4.0.2/setup/advanced/image-signature-verification/#method-public-key) 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.
