Konfidence is pre-release software. Concepts and APIs are unstable and subject to change.
Skip to content

Configure signing and verification ​

Use this guide when your application requires signed artifacts and vectors. You will sign published artifacts, configure artifact verification and vector signing in a VectorTemplate, and check that assembly succeeds.

Prerequisites ​

Before you begin, make sure you have:

  • A running Kubernetes cluster with Konfidence custom resource definitions (CRDs) installed.
  • Global administrator permissions for the current workflow. Konfidence administrator permissions alone are not sufficient.
  • The kden and kubectl command-line tools.
  • Published application artifacts in an Open Container Initiative (OCI) registry. Follow Publish artifacts to create and publish their Open Component Model (OCM) component versions.
  • The registry address and credentials for accessing your artifacts and uploading the vector.
  • An RSA key pair for artifact signing and a separate RSA key pair for vector signing.
  • An existing Konfidence project and its namespace for the credential Secrets and VectorTemplate. See Create a project.

Coordinate credential setup with your administrator before you begin. Reuse existing CLI credentials and assembly Secrets when available, and skip their setup instructions below. Use the corresponding signature names and Secret references throughout the examples.

The examples sign payment-hub:1.0.0, point the edge alias to that version, and reference payment-hub:edge during assembly. Adapt the examples to your own artifacts and replace the registry addresses, key paths, key material, and namespace placeholders before using them.

Configure CLI credentials ​

Configure the CLI credentials before you sign an artifact. The CLI loads them from ~/.ocmconfig. Use the following configuration to supply your artifact-signing key and registry credentials:

yaml
# ~/.ocmconfig
type: generic.config.ocm.software/v1
configurations:
  - type: credentials.config.ocm.software/v1
    consumers:
      - identities:
          - type: RSA/v1alpha1
            signature: my-artifact-sig
            algorithm: RSASSA-PSS
        credentials:
          - type: Credentials/v1
            properties:
              privateKeyPEMFile: /home/user/.keys/signing-key.pem
              publicKeyPEMFile: /home/user/.keys/signing-cert.pem
      - identities:
          - type: OCIRegistry
            hostname: registry.example.com
        credentials:
          - type: Credentials/v1
            properties:
              username: konfidence
              password: <password>

The CLI uses Credentials/v1 with properties for RSA key material. The Kubernetes Secrets used later in this guide use RSACredentials/v1 directly. For background, see OCM credential resolution.

Sign the published artifact ​

Before assembly can verify an artifact, the artifact must carry a signature. Run these steps locally or in your continuous integration (CI) pipeline.

  1. Create signer-spec.yaml to select the algorithm and encoding:

    yaml
    type: RSASigningConfiguration/v1alpha1
    signatureAlgorithm: RSASSA-PSS
    signatureEncodingPolicy: PEM

    Use PEM encoding. Controllers verify against application/x-pem-file by default. For other encoding options, see OCM signing and verification concepts.

  2. Sign the published component version. Use its semantic version, not an alias:

    bash
    kden artifact sign \
      registry.example.com//konfidence.io/payment-hub:1.0.0 \
      --signer-spec signer-spec.yaml \
      --signature-name my-artifact-sig

    An exit code of 0 confirms that signing succeeded.

Optional: Update the artifact alias ​

If you use a mutable alias, point it to the signed component version. Signing creates a new manifest digest. Run the alias command after signing so the alias points to the signed component version:

bash
kden artifact alias registry.example.com//konfidence.io/payment-hub:1.0.0 edge

The assembly example below uses this alias. If you skip this step, use the signed component version registry.example.com//konfidence.io/payment-hub:1.0.0 in the VectorTemplate instead.

Create credential Secrets for assembly ​

If the required Secrets already exist, skip the creation commands and reference those Secrets in your VectorTemplate. Otherwise, coordinate their creation with your administrator using one of the following examples. The Secrets store key material and registry credentials. Choose either one combined Secret or separate Secrets, then reference them through spec.credentials.ocm.refs in your VectorTemplate. Konfidence merges the listed Secrets into a single credential graph.

Secrets must be in the same namespace as the custom resource that references them. Use your project namespace for both the Secrets and the VectorTemplate. To identify your project, list the available projects:

bash
kubectl get project -A

Use the namespace assigned to your project wherever the examples show <project-namespace>. Read it from the project's status.namespace field:

bash
kubectl get project <project-name> -o jsonpath='{.status.namespace}'

For details about project namespaces, see Create a project.

Signing requires a private key and fails immediately if it is missing. If verification credentials contain no RSA key material, verification falls back to the system root trust store: CA-issued signatures pass, while self-signed or internal keys fail.

Option A: Use one Secret ​

  1. Create a Secret containing both signing key pairs and the registry credentials:

    bash
    kubectl apply -n <project-namespace> -f - <<'EOF'
    apiVersion: v1
    kind: Secret
    metadata:
      name: my-creds
      namespace: <project-namespace>
    stringData:
      .ocmconfig: |
        type: generic.config.ocm.software/v1
        configurations:
          - type: credentials.config.ocm.software/v1
            consumers:
              - identities:
                  - type: RSA/v1alpha1
                    signature: my-artifact-sig
                    algorithm: RSASSA-PSS
                credentials:
                  - type: RSACredentials/v1
                    privateKeyPEM: |
                      -----BEGIN RSA PRIVATE KEY-----
                      <base64-encoded artifact signing key>
                      -----END RSA PRIVATE KEY-----
                    publicKeyPEM: |
                      -----BEGIN CERTIFICATE-----
                      <base64-encoded artifact signing cert>
                      -----END CERTIFICATE-----
              - identities:
                  - type: RSA/v1alpha1
                    signature: my-vector-sig
                    algorithm: RSASSA-PSS
                credentials:
                  - type: RSACredentials/v1
                    privateKeyPEM: |
                      -----BEGIN RSA PRIVATE KEY-----
                      <base64-encoded vector signing key>
                      -----END RSA PRIVATE KEY-----
                    publicKeyPEM: |
                      -----BEGIN CERTIFICATE-----
                      <base64-encoded vector signing cert>
                      -----END CERTIFICATE-----
              - identities:
                  - type: OCIRegistry
                    hostname: registry.example.com
                credentials:
                  - type: Credentials/v1
                    properties:
                      username: konfidence
                      password: <password>
    EOF
  2. Reference the Secret under spec in your VectorTemplate. This snippet shows only the credential configuration:

    yaml
    credentials:
      ocm:
        refs:
          - name: my-creds

Option B: Use separate Secrets ​

  1. Create one Secret for signing keys and another for registry credentials:

    bash
    # Signing keys
    kubectl apply -n <project-namespace> -f - <<'EOF'
    apiVersion: v1
    kind: Secret
    metadata:
      name: my-signing-creds
      namespace: <project-namespace>
    stringData:
      .ocmconfig: |
        type: generic.config.ocm.software/v1
        configurations:
          - type: credentials.config.ocm.software/v1
            consumers:
              - identities:
                  - type: RSA/v1alpha1
                    signature: my-artifact-sig
                    algorithm: RSASSA-PSS
                credentials:
                  - type: RSACredentials/v1
                    privateKeyPEM: |
                      -----BEGIN RSA PRIVATE KEY-----
                      <base64-encoded artifact signing key>
                      -----END RSA PRIVATE KEY-----
                    publicKeyPEM: |
                      -----BEGIN CERTIFICATE-----
                      <base64-encoded artifact signing cert>
                      -----END CERTIFICATE-----
              - identities:
                  - type: RSA/v1alpha1
                    signature: my-vector-sig
                    algorithm: RSASSA-PSS
                credentials:
                  - type: RSACredentials/v1
                    privateKeyPEM: |
                      -----BEGIN RSA PRIVATE KEY-----
                      <base64-encoded vector signing key>
                      -----END RSA PRIVATE KEY-----
                    publicKeyPEM: |
                      -----BEGIN CERTIFICATE-----
                      <base64-encoded vector signing cert>
                      -----END CERTIFICATE-----
    EOF
    
    # OCI registry credentials
    kubectl apply -n <project-namespace> -f - <<'EOF'
    apiVersion: v1
    kind: Secret
    metadata:
      name: my-registry-creds
      namespace: <project-namespace>
    type: kubernetes.io/dockerconfigjson
    stringData:
      .dockerconfigjson: |
        {
          "auths": {
            "registry.example.com": {
              "username": "konfidence",
              "password": "<password>"
            }
          }
        }
    EOF
  2. Reference both Secrets under spec in your VectorTemplate. This snippet shows only the credential configuration:

    yaml
    credentials:
      ocm:
        refs:
          - name: my-signing-creds
          - name: my-registry-creds

Configure artifact verification and vector signing ​

Before VectorAssembly can verify an artifact, it must carry a signature. Run these steps locally or in CI — see Publish Artifacts for the full artifact publishing workflow.

Configure your VectorTemplate to verify its artifacts and sign the assembled vector. Each signing and verification phase is optional. If you omit verifyArtifacts, verifyVector, or signVector, the corresponding check or signing action is skipped.

  1. Set verifyArtifacts.signatures to the artifact signature name to check during assembly.
  2. Set signVector.signatures to the signature name to use for the assembled vector.
  3. Reference the Secrets from the previous section and apply the VectorTemplate.

The following assembly example uses the separate Secrets from Option B. If you chose Option A, use its credential reference instead. The example references the edge alias of the payment-hub artifact signed earlier.

bash
kubectl apply -n <project-namespace> -f - <<'EOF'
apiVersion: konfidence.cloud/v1alpha1
kind: VectorTemplate
metadata:
  name: my-vector
  namespace: <project-namespace>
spec:
  uploadTarget: registry.example.com//konfidence.io/my-app/vector
  components:
    - name: registry.example.com//konfidence.io/payment-hub:edge

  credentials:
    ocm:
      refs:
        - name: my-signing-creds
        - name: my-registry-creds

  # Verify every listed artifact carries this signature before assembling.
  verifyArtifacts:
    signatures:
      - name: my-artifact-sig

  # Sign the assembled vector with this key.
  signVector:
    signatures:
      - name: my-vector-sig

  # Verify the existing base vector before inheriting its artifacts.
  # verifyVector:
  #   signatures:
  #     - name: my-vector-sig
EOF

Any verification or signing failure stops the current reconciliation.

Optional: Verify a base vector ​

If you inherit artifacts from an existing base vector, enable the commented verifyVector block in the example to verify that vector. For the vector-building workflow, see Build vectors.

Optional: Pin signature parameters ​

Add optional fields to a Signature entry when you need exact algorithm parameters. The following partial example shows these fields for verifyVector:

yaml
verifyVector:
  signatures:
    - name: my-vector-sig
      algorithm: RSASSA-PSS
      hashAlgorithm: SHA-256
      normalisationAlgorithm: jsonNormalisation/v4alpha1
      signatureMediaType: application/x-pem-file
      issuer: "CN=konfidence-signer,O=Example Corp"

Only name is required. For valid values, see OCM signing and verification concepts.

Verify the result ​

Check the conditions of your VectorTemplate to confirm that assembly succeeded:

bash
kubectl get vectortemplate my-vector -n <project-namespace> -o jsonpath='{.status.conditions}'

A successful assembly shows type: Ready and status: True. The reason is VectorCreated on the first reconciliation and NoDriftDetected on subsequent reconciliations.

If assembly fails, check kubectl describe vectortemplate my-vector -n <project-namespace> for the condition and attached event.

Troubleshooting ​

Use the following checks for known assembly and signature-configuration problems:

SymptomLikely causeResolution or diagnostic check
VectorTemplate Ready=Unknown, reason DriftDetectionFailedCredential Secret missing, wrong key name, or not in the same namespaceCheck Events with kubectl describe vectortemplate my-vector -n <project-namespace>, then correct the Secret configuration with your administrator.
algorithm pin rejectionSigned with RSASSA-PKCS1-V1_5 but the CRD pins RSASSA-PSSAlign algorithm in the Secret consumer identity and CRD Signature entry.

After you correct the credential configuration, Konfidence retries assembly automatically on the next reconciliation. You do not need to trigger a retry manually. Check the conditions again as described in Verify the result.

Next steps ​

Deployment verification is configured separately on the operator. The VectorDeployment controller reads its cryptographic configuration from environment variables on the operator pod. That configuration is outside the assembly task covered here.

For the next parts of your application delivery workflow, see:

EU and German government funding logos

Funded by the European Union – NextGenerationEU.

The views and opinions expressed are solely those of the author(s) and do not necessarily reflect the views of the European Union or the European Commission. Neither the European Union nor the European Commission can be held responsible for them.