Sign and Verify Components

In this tutorial, you’ll sign a component version with a private key and verify it with the corresponding public key. By the end, you’ll understand the complete signing and verification workflow that ensures component authenticity and integrity.

What You’ll Learn

  • Create an RSA key pair for signing and verification
  • Sign component version in a CTF archive
  • Hands-on experience verifying the signature

Estimated time: ~15 minutes

Scenario

You’re a software engineer who has built a helloworld component and packaged it as an OCM component version. Before distributing it to your team, you need to sign it so consumers can verify that:

  1. The component is authentic — it comes from you, not an imposter
  2. The component has integrity — it hasn’t been tampered with since signing

How It Works

  flowchart LR
    subgraph sign ["Sign (You)"]
        direction TB
        A[Component Version] --> C[Sign with Private Key]
        C --> D[Signed Component Version]
    end
    
    D --> T["Share Component"]
    
    T --> verify
    
    subgraph verify ["Verify (Consumer)"]
        direction TB
        E[Signed Component Version] --> H[Verify with Public Key]
        H --> I{Valid?}
        I -->|Yes| VALID["✓ Trusted"]
        I -->|No| INVALID["✗ Rejected"]
    end
    
    style VALID fill:#dcfce7,color:#166534
    style INVALID fill:#fee2e2,color:#991b1b

The producer signs the component version with a private key, creating a signed component. Consumers verify the signature using the corresponding public key to ensure authenticity and integrity.

Prerequisites

  • OCM CLI installed
  • A component version to sign (we’ll create one if you don’t have one)

Steps

  1. Create a sample component (if needed)

    If you already have a component version in a CTF archive, e.g, by following our Create a Component Version guide, skip to the next step.

    Create a simple helloworld component:

    # Create a directory for the tutorial
    mkdir -p /tmp/ocm-signing-tutorial && cd /tmp/ocm-signing-tutorial
    
    # Create a basic `component-constructor.yaml` without any resources:
    cat > component-constructor.yaml << 'EOF'
    components:
    - name: github.com/acme.org/helloworld
      version: 1.0.0
      provider:
        name: acme.org
    EOF
    
    # Create component version in a CTF archive located at ./transport-archive
    ocm add cv 

    You should see that the component version was created successfully.

    Expected output
     COMPONENT                      │ VERSION │ PROVIDER
    ────────────────────────────────┼─────────┼──────────
     github.com/acme.org/helloworld │ 1.0.0   │ acme.org
  2. Generate an RSA key pair

    Create a directory for your keys and generate a 4096-bit RSA key pair:

    # Create a directory for the generated keys
    mkdir keys
    
    # Generate private key
    openssl genpkey -algorithm RSA -out ./keys/private-key.pem -pkeyopt rsa_keygen_bits:4096
    
    # Extract public key
    openssl rsa -in ./keys/private-key.pem -pubout -out ./keys/public-key.pem
    
    # Secure the private key
    chmod 600 ./keys/private-key.pem

    Verify both files exist:

    ls -la ./keys/*.pem

    ⚠️ Keep your private key secure! ⚠️
    Never commit it to version control or share it.

    For more details, see How-to: Generate Signing Keys.

  3. Configure signing credentials

    Create a new .ocmconfig in the current directory and copy the content below to it, to tell OCM where to find your keys. If you already have a $HOME/.ocmconfig file you can skip creating a new one and just add the credential configuration to your existing file.

    A detailed How-To guide is available here: How-to: Configure Signing Credentials.

    touch .ocmconfig
    
    cat > .ocmconfig << 'EOF'
    type: generic.config.ocm.software/v1
    configurations:
      - type: credentials.config.ocm.software
        consumers:
          - identity:
              type: RSA/v1alpha1
              algorithm: RSASSA-PSS
              signature: default
            credentials:
              - type: Credentials/v1
                properties:
                  private_key_pem_file: /tmp/ocm-signing-tutorial/keys/private-key.pem
                  public_key_pem_file: /tmp/ocm-signing-tutorial/keys/public-key.pem  
    EOF

    👉 The signature: default name is used when you don’t specify --signature on the command line.

    For more details, see How-to: Configure Signing Credentials.

  4. Sign the component version

    Sign your component with the private key:

    ocm sign cv ./transport-archive//github.com/acme.org/helloworld:1.0.0
    Expected output
    time=... level=INFO msg="signing component version" name=default
    time=... level=INFO msg="signature added" name=default

    Verify the signature was added:

    ocm get cv ./transport-archive//github.com/acme.org/helloworld:1.0.0 -o yaml | grep -A 10 signatures:

    You should see a signatures: section with your signature.

  5. Verify the signature

    Now verify the signature using the public key:

    ocm verify cv ./transport-archive//github.com/acme.org/helloworld:1.0.0
    Expected output
    time=2026-03-12T22:06:37.357+01:00 level=INFO msg="no verifier specification file given, using default RSASSA-PSS"
    time=2026-03-12T22:06:37.357+01:00 level=INFO msg="verifying signature" name=default
    time=2026-03-12T22:06:37.358+01:00 level=INFO msg="signature verification completed" name=default duration=798.25µs
    time=2026-03-12T22:06:37.358+01:00 level=INFO msg="SIGNATURE VERIFICATION SUCCESSFUL"

    Success!
    The component version is verified as authentic and unmodified.

What You’ve Learned

Congratulations! You’ve successfully:

  • ✅ Generated an RSA key pair for signing and verification
  • ✅ Configured OCM to use your keys via .ocmconfig
  • ✅ Signed a component version with your private key
  • ✅ Verified the signature using the public key
  • ✅ Understood how signatures detect tampering

Best Practices for Production

Now that you understand the workflow, here are key practices for production environments:

  • Protect private keys — Use hardware security modules (HSMs) or secrets managers instead of local PEM files
  • Rotate keys periodically — Have a key rotation strategy; OCM supports multiple signatures to ease transitions
  • Sign at the right time — Sign after all resources are finalized; re-signing is possible but creates audit complexity
  • Distribute public keys securely — Document how consumers should obtain and verify public keys
  • Verify before deployment — Make signature verification a mandatory step in your deployment pipeline

Check Your Understanding

Why does OCM sign the component descriptor instead of the artifacts directly?

OCM signs the component descriptor because it contains digests (cryptographic hashes) of all resources. This approach is:

  • Efficient: Verification doesn’t require downloading large artifacts
  • Complete: Any change to any resource changes its digest, invalidating the signature
  • Portable: The descriptor can be verified independently of artifact storage
What’s the difference between the private and public key?
  • Private key: Used to create signatures. Keep it secret — anyone with this key can sign components as you.
  • Public key: Used to verify signatures. Share it freely with anyone who needs to verify your components.
Can a component have multiple signatures?

Yes! A component version can have multiple signatures from different parties. This enables:

  • Different signing identities (dev, staging, prod)
  • Multiple approval workflows
  • Cross-organizational trust chains

Use --signature <name> to specify which signature to create or verify.

Cleanup

Remove the tutorial artifacts:

rm -r /tmp/ocm-signing-tutorial

Next Steps