Configure Credentials for Signing

Set up credential configuration so OCM can find your signing keys when signing or verifying component versions.

You’ll end up with

  • A configured .ocmconfig file that OCM uses to locate your signing keys
  • Ability to sign and verify component versions without specifying key paths manually

Estimated time: ~3 minutes

Prerequisites

Steps

  1. Create .ocmconfig file (optional)

    Create .ocmconfig in your current directory. If you already have an .ocmconfig file, you can skip this step and add the credential configuration to your existing file.

    touch .ocmconfig
  2. Add the signing credential configuration to your .ocmconfig

    Copy the following YAML into your .ocmconfig file.

    We use the key pair you created in the How-To: Generate Signing Keys. If you already have a key pair that is located in a different location, simply update the file paths accordingly.

    Identity attributes are required for credential matching. The type and signature attributes apply to every identity. The algorithm attribute only applies to RSA — GPG and Sigstore each have a single algorithm, so it is resolved implicitly and must not be set in the identity. See the Consumer Identities Reference for details.

    There are two ways to configure signing credentials, either using file paths that point to your key files, or by including the key material directly in the config file. For more details on the supported attributes and configuration options, see Credential Consumer Identities Reference.

    The most convenient way to configure signing credentials is to add a consumer block to your .ocmconfig with the key file paths.

    Use the typed RSACredentials/v1 credential type:

    type: generic.config.ocm.software/v1
    configurations:
      - type: credentials.config.ocm.software
        consumers:
          - identity:
              type: RSA/v1alpha1
              algorithm: RSASSA-PSS
              signature: default
            credentials:
              - type: RSACredentials/v1
                privateKeyPEMFile: /tmp/keys/private-key.pem
                publicKeyPEMFile: /tmp/keys/public-key.pem

    RSACredentials/v1 uses flat camelCase fields validated at parse time. For all supported fields, see Reference: Credential Types.

    Key paths:

    • privateKeyPEMFile - Required for signing operations
    • publicKeyPEMFile - Required for verification operations

    It is also possible to configure the keys inline using `privateKeyPEM` / `publicKeyPEM`.
    Example .ocmconfig with inline keys (RSACredentials/v1)
    type: generic.config.ocm.software/v1
    configurations:
      - type: credentials.config.ocm.software
        consumers:
          - identity:
              type: RSA/v1alpha1
              algorithm: RSASSA-PSS
              signature: default
            credentials:
              - type: RSACredentials/v1
                privateKeyPEM: |
                  -----BEGIN RSA PRIVATE KEY-----
                  MIIEpAIBAAKCAQEA...
                  -----END RSA PRIVATE KEY-----
                publicKeyPEM: |
                  -----BEGIN PUBLIC KEY-----
                  MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...
                  -----END PUBLIC KEY-----

    GPG signing uses a different identity type (GPG/v1alpha1) and ASCII-armored OpenPGP key files (.asc). Generate the keys via How-To: Generate Signing Keys → GPG first.

    Use the typed GPGCredentials/v1alpha1 credential type:

    type: generic.config.ocm.software/v1
    configurations:
      - type: credentials.config.ocm.software
        consumers:
          - identity:
              type: GPG/v1alpha1
              signature: default
            credentials:
              - type: GPGCredentials/v1alpha1
                privateKeyPGPFile: /tmp/keys/signing-key.asc
                publicKeyPGPFile: /tmp/keys/verify-key.asc

    GPGCredentials/v1alpha1 uses flat camelCase fields validated at parse time. For all supported fields, see Reference: Credential Types.

    Key paths:

    • privateKeyPGPFile - Required for signing operations (ASCII-armored OpenPGP private key)
    • publicKeyPGPFile - Required for verification operations (ASCII-armored OpenPGP public key)

    It is also possible to configure the keys inline using `privateKeyPGP` / `publicKeyPGP`.
    Example .ocmconfig with inline keys (GPGCredentials/v1alpha1)
    type: generic.config.ocm.software/v1
    configurations:
      - type: credentials.config.ocm.software
        consumers:
          - identity:
              type: GPG/v1alpha1
              signature: default
            credentials:
              - type: GPGCredentials/v1alpha1
                privateKeyPGP: |
                  -----BEGIN PGP PRIVATE KEY BLOCK-----
                  ...
                  -----END PGP PRIVATE KEY BLOCK-----
                publicKeyPGP: |
                  -----BEGIN PGP PUBLIC KEY BLOCK-----
                  ...
                  -----END PGP PUBLIC KEY BLOCK-----

    For passphrase-protected private keys, add a top-level passphrase: <secret> field next to privateKeyPGPFile. OCM decrypts the key in memory only; the passphrase is never written back to disk.

    If your keyring contains multiple keys, pin the one to use by adding keyFingerprint to the GPG signer spec (set in the sign how-to), not in .ocmconfig.

  3. Test the configuration

    The dry run signs in memory without persisting the signature, so it’s a quick way to confirm OCM can locate your keys. Match the command to the algorithm you configured above:

    RSA (uses the default RSA handler — no --signer-spec needed):

    ocm sign cv --dry-run /tmp/helloworld/transport-archive//github.com/acme.org/helloworld:1.0.0

    If configured correctly, the dry run completes without “no private key found” errors.

    Expected output
    time=2026-03-12T17:05:46.428+01:00 level=INFO msg="no signer spec file provided, using default" algorithm=RSASSA-PSS encodingPolicy=Plain
    digest:
      hashAlgorithm: SHA-256
      normalisationAlgorithm: jsonNormalisation/v4alpha1
      value: 91dd197868907487e62872695db1fa7b397fde300bcbae23e24abc188fb147ad
    name: default
    signature:
      algorithm: RSASSA-PSS
      mediaType: application/vnd.ocm.signature.rsa.pss
      value: 0cb48e5867575151fca94e995fc03c6df734163aed8fbee46231c9b36e59956d51df60263d8cd58e3de7662b2fbc3c4f800107d96b4fc27e7a16807388f7e5a73d2269290c0f367d0eb92d930b485054911c10e22ed1fe6c5bfab441f1af28d8deec4df8d67ca5a54fa4495510e2fff809fe8162f875d6b91a6bc1d29e7466f113a9d9d23f16956588a5792e4c7553a8ceb6f8c630aa6090aceb83e763734c33902d4697beadc65a6bc4761e6221ec49a6882bd46c87a14c5a5c24c70bf95880d0a43b176a5bf6200837ce344abff360e13f07db35290b3e1e3639a0fdc87252542965ea95231444807564c718734ccf10a5dbbb58a8b11f7df418002e6bebfa
    
    time=2026-03-12T17:05:46.437+01:00 level=INFO msg="dry run: signature not persisted"

    GPG (requires --signer-spec pointing at a GPGSigningConfiguration/v1alpha1 file — see the sign how-to → GPG tab for the spec format):

    ocm sign cv --dry-run \
      --signer-spec ./signer-spec.yaml \
      /tmp/helloworld/transport-archive//github.com/acme.org/helloworld:1.0.0

    If configured correctly, the dry run completes without “no private key found” errors.

    Expected output
    digest:
      hashAlgorithm: SHA-256
      normalisationAlgorithm: jsonNormalisation/v4alpha1
      value: 4e376182b3d535143e8e009b1e467df3a5b0c1f912c71ae432200654c355606f
    name: default
    signature:
      algorithm: GPG
      mediaType: application/vnd.ocm.signature.gpg
      value: |-
        -----BEGIN PGP SIGNATURE-----
    
        wsGpBAABCABdBYJqMYiKCRB0vWiFKz87GDUUAAAAAAAcABBzYWx0QG5vdGF0aW9u
        cy5vcGVucGdwanMub3Jnna9mTDE6s2TgixavxY2HgBYhBNFEh4hYDHyZ/JZi4XS9
        aIUrPzsYAAAOWA/+Jck5Nvq1yWxoIht6TCv0HpQKjhRy3txVemq1oJvt1a9eukvX
        ...
        DNcbgT3EjqN6YOIA1MENuzdqdwNv9SoC+Ixex0DeHVHyKsOFsuD+3uEWoNc=
        =JoWY
        -----END PGP SIGNATURE-----
    
    time=2026-06-16T19:31:54.138+02:00 level=INFO msg="dry run: signature not persisted"

Configure multiple signing identities

For different environments (e.g., dev and prod) you can create different key pairs and add multiple consumer blocks to your .ocmconfig with different signature names:

type: generic.config.ocm.software/v1
configurations:
  - type: credentials.config.ocm.software
    consumers:
      - identity:
          type: RSA/v1alpha1
          algorithm: RSASSA-PSS
          signature: dev
        credentials:
          - type: RSACredentials/v1
            privateKeyPEMFile: /tmp/keys/dev/private-key.pem
            publicKeyPEMFile: /tmp/keys/dev/public-key.pem
      - identity:
          type: RSA/v1alpha1
          algorithm: RSASSA-PSS
          signature: prod
        credentials:
          - type: RSACredentials/v1
            privateKeyPEMFile: /tmp/keys/prod/private-key.pem
            publicKeyPEMFile: /tmp/keys/prod/public-key.pem

Specify the signature name when signing:

ocm sign cv --dry-run --signature dev /tmp/helloworld/transport-archive//github.com/acme.org/helloworld:1.0.0
ocm sign cv --dry-run --signature prod /tmp/helloworld/transport-archive//github.com/acme.org/helloworld:1.0.0

Identity Attributes Reference

The consumer identity for RSA signing/verification supports these attributes:

AttributeRequiredDescription
typeYesMust be RSA/v1alpha1
algorithmYesRSASSA-PSS (default) or RSASSA-PKCS1-V1_5. Required for credential matching — the lookup always includes this field.
signatureYesLogical name for this key configuration (default: default). Must match the --signature CLI flag.

Troubleshooting

Symptom: “no private key found”

Cause: OCM cannot find a matching consumer entry in .ocmconfig.

Fix: Ensure:

  • The key file path is correct and the file exists (privateKeyPEMFile for RSA, privateKeyPGPFile for GPG)
  • The algorithm attribute is present in the identity (e.g. algorithm: RSASSA-PSS). See Consumer Identities Reference.
  • The signature name matches what you’re using (or is default if not specified)
  • The file is valid YAML with correct indentation

Symptom: “permission denied” reading key file

Cause: Key file has restrictive permissions.

Fix: Ensure your user can read the key file:

chmod 600 /tmp/keys/private-key.pem
ls -la /tmp/keys/private-key.pem

CLI Reference

CommandDescription
ocm sign cv --dry-run --config .ocmconfigTest signing configuration
ocm verify cvTest verification configuration

Next Steps