All Products
Search
Document Center

Container Service for Kubernetes:Use Notation and Ratify for OCI artifact signing and signature verification

Last Updated:Mar 26, 2026

Sign container images and OCI artifacts hosted in Container Registry using keys managed by Key Management Service (KMS), then enforce signature verification in your ACK cluster with Ratify. Any workload that uses an unsigned or tampered image is automatically blocked before deployment.

In this article, you'll learn how to:

  • Get or import an asymmetric key in KMS

  • Install the notation-alibabacloud-secret-manager plug-in

  • Build an image and sign it with a KMS key

  • Deploy Ratify and Gatekeeper in your cluster

  • Verify that unsigned images are rejected

Key concepts

notation-alibabacloud-secret-manager — A Notation plug-in developed in compliance with the open source Notation project specification. It retrieves keys and certificates from Key Management Service (KMS) to sign OCI artifacts hosted in Container Registry.

Ratify — A verification engine that runs inside a Kubernetes cluster. It validates OCI artifact signatures and software bill of materials (SBOM) metadata to ensure only artifacts that meet your security policies are deployed.

How it works

The signing and verification pipeline works as follows:

  1. You use the Notation CLI with the notation-alibabacloud-secret-manager plug-in to sign an image. The plug-in retrieves the private key from KMS and generates an X.509 certificate attached to the image as an OCI artifact in Container Registry.

  2. When a workload deployment request arrives, Gatekeeper intercepts it and asks Ratify to verify the image signature.

  3. Ratify fetches the signature from Container Registry and validates it against the trusted certificates configured in its KeyManagementProvider (KMP).

  4. Gatekeeper allows or blocks the deployment based on Ratify's verdict.

Prerequisites

Before you begin, ensure that you have:

Step 1: Get a KMS key

Key Management Service (KMS) is an all-in-one platform for credential management and data encryption. notation-alibabacloud-secret-manager supports two key sources: keys created directly in KMS and self-signed keys imported into KMS.

Option 1: Create a key in KMS

  1. Log in to the KMS consoleACK console. In the top navigation bar, select a region. In the left-side navigation pane, choose Resource > KeysKMS consoleKMS console.

  2. On the Keys page, click the Keys tab, select a KMS instance of the software key management type from the Instance ID drop-down list, and then click Create Key.

  3. In the Create Key panel, configure the following parameters and click OK. For more information, see Software-protected key.

    Parameter Description Example
    KMS Instance The KMS instance for which you want to create a key. kst-l\*\*\*
    Key Type Select Asymmetric Key. Asymmetric key
    Key Specifications Valid values: RSA_2048, RSA_3072, EC_P256 RSA_2048
    Key Usage Select Sign/Verify. SIGN/VERIFY
    Key Alias The alias of the key. Accepts letters, digits, underscores (_), hyphens (-), and forward slashes (/). test-key
    Tag Optional. A key-value pair used to classify and manage keys. None
  4. Create an Application Access Point (AAP) for the plug-in to authenticate with KMS.

    1. In the left-side navigation pane, choose Application Access > AAPs.

    2. On the Application Access tab, click Create AAP. Configure the following parameters:

      Parameter

      Description

      Mode

      Select Quick Creation.

      Scope (KMS Instance)

      Select the KMS instance you want to access.

      Application Access Point Name

      Enter a name for the AAP.

      Authentication Method

      Defaults to ClientKey and cannot be changed.

      Default Permission Policy

      Defaults to key/* secret/* and cannot be changed. The application can access all keys and secrets in the specified KMS instance.

    3. Click OK. The browser automatically downloads two files: Keep these files — you'll need them when configuring the plug-in environment variables.

      • Application Access Secret (ClientKeyContent): saved as clientKey_****.json

      • Password: saved as clientKey_****_Password.txt

Option 2: Import a self-signed key into KMS

If you have an existing private key, import it into KMS. This example uses OpenSSL to generate and encrypt the key material.

1. Create an asymmetric key placeholder

Follow the same steps as Option 1 to create an asymmetric key in KMS. This creates a key entry in the Pending Import state.

For Key Type, select Asymmetric Key. For Key Specifications, select RSA_2048, RSA_3072, or EC_P256. For Key Usage, select SIGN/VERIFY.

See Step 1: Create an asymmetric key.

2. Download the wrapping public key and import token

To import key material, you need a wrapping public key (to encrypt your key material) and an import token (to authorize the import).

  1. Find the key you created and click Details in the Actions column. On the Key Material tab, click Obtain Parameters for Import.

  2. In the Obtain Parameters to Import Key Material dialog, configure Public Key Type and Encryption Algorithm, then click Next. For encryption process details, see Example: Use OpenSSL to generate key material for RSA_2048.

    Key type Key specification Wrapping public key type Encryption algorithm
    Software-protected key RSA_2048, RSA_3072, EC_P256, EC_P256K RSA_2048 RSAES_OAEP_SHA_256_AES_256_ECB_PKCS7_PAD
  3. Download the wrapping public key and the import token to a secure location.

    • Public key format: DER format saves as publickey_****.bin`; PEM format saves as `publickey_****.pem.

    • Import token: saved as token_******.txt.

    Important

    The import token is valid for 24 hours and can be reused within that period. After 24 hours, download a new wrapping public key and import token. Always use the wrapping public key and import token from the same download — mixing files from different downloads is not supported.

3. Encrypt your key material

Three keys are involved in the encryption process:

Key Purpose Source
Target asymmetric key (TAK) The key to import as key material Your environment (on-premises KMI, HSM, or OpenSSL)
Import wrapping key (IWK) Encrypts the TAK. IWKpub is the wrapping public key you downloaded. KMS
Ephemeral symmetric key (ESK) A temporary key that encrypts the TAK private key. Destroy it immediately after export. Your environment
The TAK private key must be in PKCS #8 format (RFC 5208). For RSA keys, start from RFC 3447; for ECC keys, start from RFC 5915. Convert to PKCS #8 before proceeding.

Example: Encrypt RSA_2048 key material using OpenSSL

  1. Create a TAK private key and convert it to PKCS #8 format:

    openssl genrsa -out TakPrivPkcs1.pem 2048
    openssl pkcs8 -topk8 -inform PEM -in TakPrivPkcs1.pem -outform der -nocrypt -out TakPrivPkcs8.bin
  2. Create an AES-256 ESK:

    openssl rand -out EskAes256.bin 32
  3. Encrypt the ESK with the IWK public key using RSAES-OAEP (SHA-256 for both MGF1 and the hash algorithm). Replace PublicKey.pem with the name of the public key file you downloaded from the KMS console.

    openssl pkeyutl -encrypt -pubin -inkey PublicKey.pem -in EskAes256.bin -pkeyopt \
    rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256 -out \
    CipherEsk.bin
  4. Encrypt the TAK private key with the ESK using ECB mode and PKCS #7 padding:

    xxd -l 32 -c 32 -ps EskAes256.bin | xargs -I {} openssl enc -aes-256-ecb -e -K {} -in \
    TakPrivPkcs8.bin -nosalt -out CipherTakPriv.bin
  5. Assemble the encrypted key material as Cipher(ESK) || Cipher(TAKpriv) and encode in Base64. The resulting EncryptedKeyMaterial_base64.txt contains the key material to upload.

    cat CipherEsk.bin CipherTakPriv.bin > EncryptedKeyMaterial.bin
    openssl enc -e -base64 -A -in EncryptedKeyMaterial.bin -out EncryptedKeyMaterial_base64.txt

4. Import the key material

On the key details page, click Import Key Material. In the Import Wrapped Key Material dialog, configure the following parameters and click OK.

After the import completes, the key status changes from Pending Import to Enabling.

kms.png
Parameter Description
Wrapped Key Material Upload the EncryptedKeyMaterial_base64.txt file generated in step 3.
Import Token Upload the token file you downloaded in step 2.
Key Material Expired On Select Never Expire or set a custom expiration time.
Important

If you set an expiration time, KMS deletes the key material when it expires. To reuse the same key after expiration, reimport the same key material.

Step 2: Install notation-alibabacloud-secret-manager

Install notation-alibabacloud-secret-manager in the same region and VPC as your KMS instance. To access a KMS instance from multiple VPCs in the same region, see Configure multi-VPC access to KMS instances within the same region.
  1. Download the plug-in for your OS. For OS versions not listed below, download from the releases page.

    • Linux (ARM64): ``bash wget https://notation-alibabacloud-secret-manager.oss-cn-hangzhou.aliyuncs.com/dist/v0.1.2/notation-alibabacloud-secret-manager_Linux_arm64.tar.gz ``

    • Linux (x86_64): ``bash wget https://notation-alibabacloud-secret-manager.oss-cn-hangzhou.aliyuncs.com/dist/v0.1.2/notation-alibabacloud-secret-manager_Linux_x86_64.tar.gz ``

  2. Create the plug-in directory:

    mkdir -p /root/.config/notation/plugins/alibabacloud.secretmanager.plugin/
  3. Extract the archive into the plug-in directory. Replace <Version number> with the actual version string from the downloaded filename.

    tar -xvf notation-alibabacloud-secret-manager_Linux_<Version number>.tar.gz \
      -C /root/.config/notation/plugins/alibabacloud.secretmanager.plugin/
  4. Verify the plug-in is installed correctly:

    notation plugin ls

    The plug-in alibabacloud.secretmanager.plugin should appear in the output.

  5. Set the environment variables for KMS authentication. notation-alibabacloud-secret-manager supports multiple credential methods — for CI/CD pipelines and additional options, see Credentials.

    Environment variable Description Example
    ALIBABA_CLOUD_ACCESS_KEY_ID AccessKey ID of your Alibaba Cloud account XXXXXX
    ALIBABA_CLOUD_ACCESS_KEY_SECRET AccessKey secret of your Alibaba Cloud account XXXXXX
    ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT VPC endpoint of the dedicated KMS instance kst-hzxxxxxxxxxx.cryptoservice.kms.aliyuncs.com
    ALIBABA_CLOUD_KMS_CLIENTKEY_FILEPATH Path to the client key file. Create a file (for example, /root/clientkey) and copy the content from clientKey_KAAP.****.json downloaded when you created the AAP. /root/clientkey
    ALIBABA_CLOUD_KMS_PASSWORD Password for the AAP. Copy the content from clientKey_KAAP.****_Password.txt downloaded when you created the AAP. XXXXXX
    ALIBABA_CLOUD_KMS_CA_FILEPATH Path to the CA certificate file. Create a file and copy the content from PrivateKmsCA_xxxxx.pem downloaded in Step 4: Download the CA certificate of the KMS instance. /root/privatekmsca
    export ALIBABA_CLOUD_ACCESS_KEY_ID=<your-access-key-id>
    export ALIBABA_CLOUD_ACCESS_KEY_SECRET=<your-access-key-secret>
    export ALIBABA_CLOUD_KMS_INSTANCE_ENDPOINT=<your-kms-endpoint>
    export ALIBABA_CLOUD_KMS_CLIENTKEY_FILEPATH=<your-clientkey-filepath>
    export ALIBABA_CLOUD_KMS_PASSWORD=<your-password>
    export ALIBABA_CLOUD_KMS_CA_FILEPATH=<your-ca-filepath>

Step 3: Build and sign an image

Build and push the image

  1. Build an image using Container Registry. See Use a Container Registry Enterprise Edition instance to build an image or Build and push a multi-arch image to a Container Registry Enterprise Edition instance.

    Container Registry Enterprise Edition supports OCI Image and Distribution Specification 1.1.0, which lets you use tools like OCI Registry As Storage (ORAS) to manage and distribute non-image artifacts. See Using OCI v1.1.0 specification to manage and associate container images and their derivative artifacts.
  2. Configure VPC or internet access control for your Container Registry Enterprise Edition instance. See Network access control.

  3. Get the password for your Container Registry Enterprise Edition instance. If you've forgotten it, reset it by configuring access credentials. See Configure access credentials for a Container Registry Enterprise Edition instance.

Sign the image

notation-alibabacloud-secret-manager retrieves the private key and certificate from KMS to sign images in Container Registry. All sign commands use --plugin alibabacloud.secretmanager.plugin with the --id parameter set to your KMS key ID.

Important

Sign images by digest, not by tag. Tags are mutable and can be overwritten, which makes tag-based signatures unreliable for security enforcement.

  1. Log in to your image repository:

    ./notation login --username=<username> <registry-domain>

    Example:

    ./notation login --username=tsh_ram@11380257155*** test-for-doc-registry.cn-hangzhou.cr.aliyuncs.com
  2. Sign the image. Replace <dirPath> with the directory where you want to store the generated certificate (for example, /root).

    ./notation sign --id <keyId> --plugin alibabacloud.secretmanager.plugin \
      test-for-doc-registry.cn-hangzhou.cr.aliyuncs.com/test/nginx:2.11 \
      --plugin-config output_cert_dir=<dirPath>

    Expected output:

    Successfully signed test-for-doc-registry.cn-hangzhou.cr.aliyuncs.com/test/nginx@sha256:f57e1908e63538ad5159fa99443d0492d23b9d34ba7******
  3. To sign an artifact by digest (recommended for production):

    Parameter Description
    id The ID of the KMS key.
    plugin-config output_cert_dir Directory to export the X.509 certificate generated during signing with a KMS key.
    plugin-config ca_certs Path to the certificate generated when using a self-signed key imported to KMS.
    notation sign --id <keyId> --plugin alibabacloud.secretmanager.plugin \
      <myRegistry>/<myRepo>@<digest> \
      --plugin-config output_cert_dir=<dirPath>

Step 4: Deploy Ratify and Gatekeeper

Install Ratify and Gatekeeper

  1. Enable Gatekeeper-based policy governance in your cluster. See Enable policy governance.

  2. Install Ratify via Helm.

    1. Create the ratify namespace: ``bash kubectl create ns ratify ``

    2. In the ACK console, click Clusters in the left-side navigation pane. Find your cluster and click its name. In the left-side navigation pane, choose Applications > Helm.

    3. On the Helm page, click Deploy. In the Basic Information step, configure the following parameters, select the ratify Helm chart, and click Next.

      Parameter Example
      Application Name ratify
      Namespaces Select the ratify namespace.
      Source Marketplace (default)
      Chart Set Use Scenarios to All and Supported Architecture to amd64. Search for ratify and select it.
    4. In the Parameters step, select a chart version and configure the following parameters. Click OK when done.

      Important

      The notationCert parameter is deprecated. Use notationCerts instead to specify an array of verification certificates for the Notation verifier.

      Parameter Description Default Recommended value
      ServiceAccount.create Creates a ServiceAccount named ratify-admin when set to true. Set to false if you create the ServiceAccount manually for RRSA. true Keep default
      ServiceAccount.name Name of the Ratify ServiceAccount. ratify-admin Keep default
      ServiceAccount.annotations Custom annotations. Add pod-identity.alibabacloud.com/role-name: <Your-RRSA-role> to enable RRSA. Replace <Your-RRSA-role> with your RRSA role name. {} Set for RRSA
      oras.authProviders.k8secretsEnabled Enables Kubernetes Secrets Provider for image repository authentication. false Keep default
      oras.authProviders.alibabacloudAcrBasicEnabled Enables Container Registry Provider for image repository authentication. false true
      oras.cache.enabled Enables ORAS store caching for ListReferrers and GetSubjectDescriptor. Disable if you require strong data consistency. true Keep default
      oras.cache.ttl Time-to-live (TTL) of the ORAS store cache (seconds). 10 Keep default
      alibabacloudAcrConfig.defaultInstanceId ID of the default Container Registry instance. Required. Set to the ID of your Container Registry Enterprise Edition instance.

      `

      Required
      alibabacloudAcrConfig.acrInstancesConfig List of Container Registry instances if you pull images from multiple registries. Specify instanceName and instanceId for each. [] Set as needed
      upgradeCRDs.enabled Enables Ratify CustomResourceDefinition (CRD) upgrades via pre-install Helm chart hooks. Set to false if you don't need to upgrade the Ratify CRD. Note that true triggers pre-install hooks, which may slow down installation. true Keep default
      featureFlags.RATIFY_CERT_ROTATION Enables automatic TLS certificate generation and rotation. false Set to true to enable automatic certificate rotation
      notationCerts Array of public key certificates and certificate chains for the Notation verifier's built-in cert store. Specify the KMS verification certificates generated when you signed your image. Required
  3. In the left-side navigation pane, choose Security > Policy Governance, then click the My Policies tab. Confirm that the RatifyVerification policy exists.

    image

Configure RRSA to pull private image signatures

Ratify supports RAM Roles for Service Accounts (RRSA) to authenticate with Container Registry when pulling private image signatures. See Use RRSA to authorize different pods to access different cloud services.

  1. On the Add-ons page of your ACK cluster, install ack-pod-identity-webhook.

  2. Create a RAM role named ratify-role with IdP as the trusted entity type. Use ack-ram-tool to automate role creation with the following trust policy. Replace the placeholders with your actual OIDC values and the namespace and ServiceAccount you specify when installing Ratify.

    {
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "oidc:aud": "sts.aliyuncs.com",
          "oidc:iss": "<oidc_issuer_url>",
          "oidc:sub": "system:serviceaccount:<namespace>:<service_account>"
        }
      },
      "Effect": "Allow",
      "Principal": {
        "Federated": [
          "<oidc_provider_arn>"
        ]
      }
    }
  3. Attach the AliyunContainerRegistryFullAccess policy to ratify-role.

  4. Apply the following YAML to create the namespace and ServiceAccount with RRSA annotation. If you already created a ServiceAccount for Ratify, add the pod-identity.alibabacloud.com/role-name: ratify-role annotation to its configuration.

    ---
    apiVersion: v1
    kind: Namespace
    metadata:
      name: ratify
      labels:
        pod-identity.alibabacloud.com/injection: 'on'
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: ratify-admin
      namespace: ratify
      annotations:
        pod-identity.alibabacloud.com/role-name: ratify-role
    ---

    After Ratify is deployed, the ALIBABA_CLOUD_ROLE_ARN, ALIBABA_CLOUD_OIDC_PROVIDER_ARN, and ALIBABA_CLOUD_OIDC_TOKEN_FILE environment variables are automatically injected into Ratify pod templates.

Step 5: Verify the signature

Deploy a test workload to confirm the policy is working:

  • Signed image: the Deployment succeeds. Ratify validates the signature against the trusted certificates and Gatekeeper allows the deployment.

  • Unsigned image: the Deployment is blocked by Ratify. Run the following command to inspect the rejection reason:

    kubectl get deploy ${unsigned_deploy_name} -n ${namespace} -o yaml

    The following figure shows an example of signature verification logs.

    image

Ratify configuration reference

Ratify provides built-in and external verifiers for different artifact types. The following sections show sample configurations for the resources Ratify uses.

Notation Verifier configuration

After installation, Ratify automatically creates a Notation verifier based on the template below. Modify the trustPolicyDoc section to match your verification requirements. You can add the name and artifactType fields to the verifier configuration to specify the artifact types you want to verify. You can configure cluster-wide or namespaced verifiers. See Ratify verifier documentation.

apiVersion: config.ratify.deislabs.io/v1beta1
kind: Verifier
metadata:
  name: verifier-notation
spec:
  artifactTypes: application/vnd.cncf.notary.signature
  name: notation
  parameters:
    trustPolicyDoc:
      trustPolicies:
      - name: default
        registryScopes:
        - '*'
        signatureVerification:
          level: strict
        trustStores:
        - ca:certs
        trustedIdentities:
        - '*'
      version: "1.0"
    verificationCertStores:
      certs:
      - ratify-notation-inline-cert
  version: 1.0.0
status:
  issuccess: true

KeyManagementProvider (KMP)

Specify custom public keys or X.509 certificates for verifiers using KeyManagementProvider (KMP) resources. A Notation verifier or a Cosign verifier is automatically associated with a corresponding KMP during signature verification. See Ratify KMP documentation.

apiVersion: config.ratify.deislabs.io/v1beta1
kind: KeyManagementProvider
metadata:
  name: ratify-notation-inline-cert
spec:
  parameters:
    contentType: certificate
    value: |
      -----BEGIN CERTIFICATE-----
      XXXXXX
      XXXXXX
      XXXXXX
      -----END CERTIFICATE-----
  type: inline

ORAS Store configuration

After installation, add the authProvider parameter to the default ORAS store to connect Ratify to your private Container Registry repositories.

apiVersion: config.ratify.deislabs.io/v1beta1
kind: Store
metadata:
  name: store-oras
spec:
  name: oras
  parameters:
    authProvider:
      acrInstancesConfig:
      - instanceName: name1
        instanceId: cri-aaaaaaaaaaaa
      - instanceName: name2
        instanceId: cri-bbbbbbbbbbbb
      defaultInstanceId: cri-ccccccccc
      name: alibabacloudAcrBasic
Parameter Required Description
name No The authProvider.name value for Container Registry. Fixed to alibabacloudAcrBasic.
acrInstancesConfig No List of Container Registry instances with their instanceName and instanceId. Ratify matches the instance ID based on the image repository name in your workload.
defaultInstanceId Yes ID of the default Container Registry instance. If Ratify cannot match an instance from acrInstancesConfig, it falls back to this ID and uses Alibaba Cloud Credentials to retrieve temporary credentials.

What's next

References