All Products
Search
Document Center

Container Service for Kubernetes:Use ack-secret-manager to import Alibaba Cloud OOS encryption parameters

Last Updated:Mar 26, 2026

Applications running in ACK clusters often need access to credentials, API keys, and other sensitive configuration stored in CloudOps Orchestration Service (OOS). Embedding those values in code or container images creates security and rotation risks. ack-secret-manager solves this by continuously syncing OOS encryption parameters into Kubernetes Secrets, so your application reads credentials from the cluster without any code changes.

image

How it works

ack-secret-manager uses two custom resource definitions (CRDs):

  • SecretStore — defines *how* ack-secret-manager authenticates with OOS (authorization config)

  • ExternalSecret — defines *what* to sync (which OOS parameter maps to which Kubernetes Secret key)

The component polls OOS on a configurable interval, writes the latest parameter value into a Kubernetes Secret, and keeps it in sync automatically. The resulting Kubernetes Secret has the same name and namespace as the ExternalSecret.

Security notes

Before enabling secret synchronization, assess the following risks:

  • File system exposure: When Secrets are mounted as files, a CVE (Common Vulnerabilities and Exposures) exploit in an application can allow directory traversal and leak the secrets.

  • Environment variable exposure: Misconfigured debug breakpoints or log permissions can expose secrets referenced as environment variables. Avoid this pattern.

  • Least privilege: Apply the least privilege principle when granting sync permissions. RRSA (RAM Roles for Service Accounts) enforces per-pod isolation — other pods cannot access secrets unless explicitly associated with the same RAM role.

For workloads that don't need to persist secrets, use RRSA to authorize pods and call the GetSecretParameter API directly from your application. This minimizes the exposure surface in the pod file system and Kubernetes Secrets.

Prerequisites

Before you begin, ensure that you have:

Step 1: Install ack-secret-manager

  1. Log on to the ACK console. In the left navigation pane, click Clusters.

  2. On the Clusters page, click the name of the target cluster. In the left-side pane, choose Applications > Helm.

  3. On the Helm page, click Deploy. In the Chart section, find and select ack-secret-manager, keep the default values for other parameters, and click Next. The confirmation message indicates that the chart installs in the kube-system namespace by default. Click Yes. To use a custom namespace, configure Application Name and Namespace in the Basic information step.

  4. In the Parameters step, select the latest chart version, configure the parameters below, and click OK. Enable RRSA authentication (recommended): Set rrsa.enable to true. Enable scheduled synchronization (optional): Configure throttling (required for large clusters): If your cluster has many ExternalSecrets, improper concurrency can trigger throttling on OOS or RAM.

    • command.disablePolling: Set to false to enable automatic parameter rotation.

    • command.pollingInterval: Sync frequency in seconds. In this example, this parameter is set to 120 seconds (every 2 minutes). You can adjust the value as needed.

    • command.maxConcurrentOosSecretPulls: Maximum OOS parameters synced per second. Default: 10.

    image

    image

    image

  5. After installation, you are redirected to the ack-secret-manager page. Verify that the following resources are created:

    image.png

Step 2: Authorize ack-secret-manager to access OOS

Create a SecretStore to grant ack-secret-manager access to OOS encryption parameters. Choose the authorization method based on your cluster type:

MethodCluster typesNotes
RRSA (recommended)ACK managed clusters, ACK Serverless clusters (Kubernetes 1.22+)Per-pod isolation; no AccessKey exposure
Worker RAM roleACK managed clusters, ACK dedicated clusters, registered clustersNot supported on ACK Serverless clusters
AccessKey pairAll cluster typesRequires storing an AccessKey secret in Kubernetes

Use RRSA to grant permissions

RRSA isolates permissions at the pod level, avoiding the credential-leak risks associated with AccessKey pairs.

  1. Enable the RRSA feature for your cluster. See Enable RRSA.

    Set rrsa.enable to true when installing ack-secret-manager.
  2. Create a RAM role with an OIDC identity provider (IdP) as the trusted entity. See Create a RAM role for an OIDC IdP. Use the following key parameters:

    ParameterValue
    Identity provider typeOIDC
    Identity providerSelect the provider named ack-rrsa-<cluster_id>, where <cluster_id> is your cluster ID
    Condition — oidc:issUse the default value
    Condition — oidc:audUse the default value
    Condition — oidc:subAdd a StringEquals condition. Set Key to oidc:sub and Value to system:serviceaccount:<namespace>:<serviceAccountName>. Replace <namespace> with the namespace where ack-secret-manager is installed (default: kube-system) and <serviceAccountName> with the service account name
  3. Create and attach a custom RAM policy to the RAM role. See Create custom policies and Grant permissions to a RAM role.

    {
        "Action": [
           "oos:GetSecretParameter",
           "kms:GetSecretValue"
        ],
        "Resource": [
            "*"
        ],
        "Effect": "Allow"
    }
  4. Create a SecretStore. Replace the placeholders and save the file as secretstore-rrsa.yaml:

    • {accountID}: The Alibaba Cloud account ID used to sync OOS parameters

    • {clusterID}: Your cluster ID

    • {roleName}: The RAM role name you created in step 2

    apiVersion: 'alibabacloud.com/v1alpha1'
    kind: SecretStore
    metadata:
      name: scdemo-rrsa
    spec:
      OOS:
        OOSAuth:
          oidcProviderARN: "acs:ram::{accountID}:oidc-provider/ack-rrsa-{clusterID}"
          ramRoleARN: "acs:ram::{accountID}:role/{roleName}"

    Apply the SecretStore:

    kubectl apply -f secretstore-rrsa.yaml

Grant permissions to the worker RAM role

This method applies to ACK managed clusters, ACK dedicated clusters, and registered clusters. ACK Serverless clusters have no worker RAM role and cannot use this method.

  1. Create a custom RAM policy. See Create custom policies.

    {
      "Action": [
        "oos:GetSecretParameter",
        "kms:GetSecretValue"
      ],
      "Resource": [
        "*"
      ],
      "Effect": "Allow"
    }
  2. Attach the policy to the cluster's worker RAM role. See Permissions of the worker RAM role of ACK managed clusters.

Use an AccessKey pair to assume a RAM role

This method applies to all ACK cluster types.

  1. Create a RAM role with an Alibaba Cloud account as the trusted entity. See Create a RAM role for a trusted Alibaba Cloud account.

  2. Create and attach a RAM policy that grants access to OOS encryption parameters. See Create custom policies and Grant permissions to a RAM role.

    {
      "Action": [
        "oos:GetSecretParameter",
        "kms:GetSecretValue"
      ],
      "Resource": [
        "*"
      ],
      "Effect": "Allow"
    }
  3. Create a RAM policy that allows assuming the RAM role, and attach it to the RAM user you want to use. Replace the ARN placeholder with the Alibaba Cloud Resource Name (ARN) of the RAM role you created in step 1.

    {
        "Statement": [
            {
                "Action": "sts:AssumeRole",
                "Effect": "Allow",
                "Resource": "acs:ram::***:role/****"
            }
        ],
        "Version": "1"
    }

    Attach the policy to the RAM user. See Grant permissions to RAM users.

  4. Create a Kubernetes Secret to store the RAM user's AccessKey pair. Replace the placeholder values with the actual Base64-encoded credentials and save the file as ramuser.yaml:

    apiVersion: v1
    data:
      accessKey: {AccessKey ID encoded in Base64}
      accessKeySecret: {AccessKey secret encoded in Base64}
    kind: Secret
    metadata:
      name: ramuser
      namespace: kube-system
    type: Opaque

    Apply the Secret:

    kubectl apply -f ramuser.yaml
  5. Create a SecretStore. Replace the placeholders and save the file as secretstore-ramrole.yaml:

    • {accountID}: The Alibaba Cloud account ID used to sync OOS parameters

    • {roleName}: The RAM role name you created in step 1

    • {secretName}: The name of the Kubernetes Secret that stores the AccessKey pair

    • {secretNamespace}: The namespace of that Secret

    • {secretKey}: The key within that Secret

    • {roleSessionName}: A custom session name string

    apiVersion: 'alibabacloud.com/v1alpha1'
    kind: SecretStore
    metadata:
      name: scdemo-ramrole
    spec:
      OOS:
        OOSAuth:
          accessKey:
            name: {secretName}
            namespace: {secretNamespace}
            key: {secretKey}
          accessKeySecret:
            name: {secretName}
            namespace: {secretNamespace}
            key: {secretKey}
          ramRoleARN: "acs:ram::{accountID}:role/{roleName}"
          ramRoleSessionName: {roleSessionName}

    Apply the SecretStore:

    kubectl apply -f secretstore-ramrole.yaml

Step 3: Sync OOS parameters to Kubernetes Secrets

After authorization is configured, create an ExternalSecret to specify which OOS parameters to sync and where to store them in Kubernetes.

  1. Create an ExternalSecret. Replace the placeholders and save the file as external.yaml:

    apiVersion: 'alibabacloud.com/v1alpha1'
    kind: ExternalSecret
    metadata:
      name: esdemo
    spec:
      provider: oos               # Sync from OOS (default is kms)
      data:
        - key: {OOS parameter name}           # Name of the OOS encryption parameter
          name: {Kubernetes secret key}        # Key in the resulting Kubernetes Secret
          secretStoreRef:                      # Omit if using the worker RAM role method
            name: {secret store name}          # Name of the SecretStore
            namespace: {secret store namespace}

    Apply the ExternalSecret:

    kubectl apply -f external.yaml
  2. Verify that the sync succeeded:

    kubectl get secret esdemo

    If a Kubernetes Secret is created, the OOS encryption parameter has been synced to your cluster.

Advanced configurations

Cross-account parameter synchronization

If your OOS instance and ACK cluster belong to different Alibaba Cloud accounts, use cross-account RRSA to sync parameters. The following example imports a parameter from Account A into an ACK cluster in Account B.

Account A configurations

  1. Use Account A to create a RAM role with Account B as the trusted entity. Select Other Alibaba Cloud Account and enter Account B's ID. See Create a RAM role for a trusted Alibaba Cloud account.

    Important

    When selecting the trusted Alibaba Cloud account, select Other Alibaba Cloud Account and enter the ID of Account B.

  2. Create and attach a RAM policy to grant OOS access. See Create custom policies and Grant permissions to a RAM role.

    {
        "Action": [
           "oos:GetSecretParameter",
           "kms:GetSecretValue"
        ],
        "Resource": [
            "*"
        ],
        "Effect": "Allow"
    }

Account B configurations

  1. Enable RRSA for the ACK cluster. See Enable RRSA.

    Set rrsa.enable to true when installing ack-secret-manager.
  2. Create a RAM role with an OIDC identity provider (IdP) as the trusted entity. Use the same parameters as described in the RRSA authorization section. See Create a RAM role for an OIDC IdP.

  3. Create a RAM policy that allows assuming Account A's RAM role, and attach it to the RAM role from step 2. Set Resource to the ARN of Account A's RAM role. To find the ARN, see How do I view the ARN of a RAM role?

    • <account-id>: Account A's ID (where the Key Management Service (KMS) instance is located)

    • <role-name>: The name of Account A's RAM role

    {
      "Statement": [
        {
          "Action": "sts:AssumeRole",
          "Effect": "Allow",
          "Resource": "acs:ram:*:<account-id>:role/<role-name>"
        }
      ],
      "Version": "1"
    }

    Attach the policy to Account B's RAM role. See Grant permissions to a RAM role.

  4. Create a SecretStore. Replace the placeholders and save the file as secretstore-cross-account.yaml:

    • {ACK-accountID}: Account B's ID

    • {clusterID}: Your cluster ID

    • {ACK-roleName}: The RAM role name created by Account B

    • {OOS-accountID}: Account A's ID

    • {OOS-roleName}: The RAM role name created by Account A

    • {roleSessionName}: A custom session name string

    apiVersion: 'alibabacloud.com/v1alpha1'
    kind: SecretStore
    metadata:
      name: scdemo-cross-account
    spec:
      OOS:
        OOSAuth:
          oidcProviderARN: "acs:ram::{ACK-accountID}:oidc-provider/ack-rrsa-{clusterID}"
          ramRoleARN: "acs:ram::{ACK-accountID}:role/{ACK-roleName}"
          remoteRamRoleARN: "acs:ram::{OOS-accountID}:role/{OOS-roleName}"
          remoteRamRoleSessionName: {roleSessionName}
  5. Create an ExternalSecret as described in Step 3: Sync OOS parameters to Kubernetes Secrets.

Parse structured parameters

Use jmesPath to extract specific fields from JSON or YAML-formatted OOS parameters into individual Kubernetes Secret keys.

Extract specific fields from a JSON parameter

If the following JSON value is stored in an OOS encryption parameter:

{"name":"tom","friends":[{"name":"lily"},{"name":"mark"}]}

Use jmesPath to map specific fields to named keys in the Kubernetes Secret. path is a JMESPath expression. objectAlias is the resulting key in the Kubernetes Secret.

apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
  name: es-json-demo
spec:
  provider: oos
  data:
    - key: {OOS parameter name}
      secretStoreRef:
        name: {secret store name}
        namespace: {secret store namespace}
      jmesPath:
        - path: "name"
          objectAlias: "myname"
        - path: "friends[0].name"
          objectAlias: "friendname"

Automatically parse a JSON parameter

If you don't know the structure of the JSON parameter, use dataProcess.extract to parse all fields automatically. Use dataProcess.replaceRule to rewrite keys that don't meet Kubernetes naming requirements.

For example, if the OOS parameter contains:

{"/name-invalid":"lily","name-invalid/":[{"name":"mark"}]}

The keys /name-invalid and name-invalid/ are invalid as Kubernetes Secret keys. Use replaceRule to rename them:

apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
  name: extract-secret
spec:
  provider: oos
  dataProcess:
    - extract:
        key: {OOS parameter name}
        secretStoreRef:
          name: {secret store name}
          namespace: {secret store namespace}
      replaceRule:
        - source: "^/.*d$"   # Keys starting with / and ending with d → renamed to "tom"
          target: "tom"
        - source: "^n.*/$"   # Keys starting with n and ending with / → renamed to "mark"
          target: "mark"

Extract specific fields from a YAML parameter

If the following YAML value is stored in an OOS encryption parameter:

name: tom
friends:
  - name: lily
  - name: mark

Use the same jmesPath approach as for JSON:

apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
  name: es-yaml-demo
spec:
  provider: oos
  data:
    - key: {OOS parameter name}
      secretStoreRef:
        name: {secret store name}
        namespace: {secret store namespace}
      jmesPath:
        - path: "name"
          objectAlias: "myname"
        - path: "friends[0].name"
          objectAlias: "friendname"

Automatically parse a YAML parameter

If the OOS parameter contains:

/name-invalid: lily
name-invalid/:
  - name: mark

Use the same dataProcess.extract and replaceRule approach as for JSON:

apiVersion: 'alibabacloud.com/v1alpha1'
kind: ExternalSecret
metadata:
  name: extract-secret
spec:
  provider: oos
  dataProcess:
    - extract:
        key: {OOS parameter name}
        secretStoreRef:
          name: {secret store name}
          namespace: {secret store namespace}
      replaceRule:
        - source: "^/.*d$"   # Keys starting with / and ending with d → renamed to "tom"
          target: "tom"
        - source: "^n.*/$"   # Keys starting with n and ending with / → renamed to "mark"
          target: "mark"

What's next

To protect Kubernetes Secrets synced from OOS and cached in your ACK cluster, enable the Secret encryption feature. See Use KMS to encrypt Kubernetes Secrets.