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:
- The component is authentic — it comes from you, not an imposter
- 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
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 cvYou should see that the component version was created successfully.
Expected output
COMPONENT │ VERSION │ PROVIDER ────────────────────────────────┼─────────┼────────── github.com/acme.org/helloworld │ 1.0.0 │ acme.orgGenerate 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.pemVerify 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.
Configure signing credentials
Create a new
.ocmconfigin the current directory and copy the content below to it, to tell OCM where to find your keys. If you already have a$HOME/.ocmconfigfile 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: defaultname is used when you don’t specify--signatureon the command line.For more details, see How-to: Configure Signing Credentials.
Sign the component version
Sign your component with the private key:
ocm sign cv ./transport-archive//github.com/acme.org/helloworld:1.0.0Expected output
time=... level=INFO msg="signing component version" name=default time=... level=INFO msg="signature added" name=defaultVerify 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.Verify the signature
Now verify the signature using the public key:
ocm verify cv ./transport-archive//github.com/acme.org/helloworld:1.0.0Expected 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-tutorialNext Steps
- How-to: Generate Signing Keys - Step-by-step creating RSA key pairs.
- How-to: Configure Signing Credentials - Set up OCM to use your keys for signing and verification
- How-to: Sign a Component Version - Step-by-step signing instructions
- How-to: Verify a Component Version - Step-by-step verification instructions
Related Documentation
- Concept: Signing and Verification - Understand the theory behind OCM signing
- How-to: Generate Signing Keys - Detailed key generation guide
- How-to: Configure Signing Credentials - Multi-environment and advanced configurations