All Products
Search
Document Center

Key Management Service:Build and deploy KMS Agent across environments to retrieve secrets

Last Updated:Jun 09, 2025

This topic describes building and deploying the KMS Agent to retrieve secrets. Deployment environments include local, Linux Elastic Compute Service (ECS), sidecar container, and Container Service for Kubernetes (ACK).

Process

To ensure standardized deployment and secure invocation of the agent, follow these steps:

image

Step 1: Build a KMS Agent executable file

For optimal security and maintainability, we recommend building the executable in a separate build environment, then uploading it to the deployment environment.

  1. Install the Go environment.

  2. Download the source code and dependencies.

    1. Download and install Git.

    2. Run the following commands to download the source code and dependencies.

      git clone https://github.com/aliyun/alibabacloud-kms-agent
      go mod download

      The default filename is alibabacloud-kms-agent, which is saved in the project root by default.

  3. Compile the binary file.

    If the build environment matches the deployment environment, run the go build . command. For cross-platform compilation when build and deployment environments differ, refer to the following commands to generate 64-bit executable files:

    macOS (to build for Linux, Windows, 64-bit)

    CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build .
    CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build .

    Linux (to build for macOS, Windows, 64-bit)

    CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build .
    CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build .

    Windows (to build for macOS, Linux, 64-bit)

    SET CGO_ENABLED=0 SET GOOS=darwin SET GOARCH=amd64 go build .
    SET CGO_ENABLED=0 SET GOOS=linux SET GOARCH=amd64 go build .
  4. Verify that alibabacloud-kms-agent exists in the project root directory.image

Step 2: Create access credentials

Recommended access credentials by deployment environment:

  • Alibaba Cloud ECS deployment: ECS instance RAM Role.

  • Kubernetes container deployment: RAM Roles for Service Accounts (RRSA).

  • Other environments deployment: Environment variables.

Environment variables (AccessKey)

This section uses a RAM user's AccessKey pair as an example. Alibaba Cloud accounts have default administrator privileges for all resources, which cannot be modified. Because compromised AccessKeys risk significant security vulnerabilities, we strongly recommend against creating them for Alibaba Cloud accounts. Instead, create a RAM user solely for API access, generate its AccessKey pair, and implement the principle of least privilege.

  1. Log on to the RAM console. In the left-side navigation pane, choose Identities > Users, and click on the target RAM user.

  2. In the Authentication tab, click Create AccessKey and follow the instructions.

    image

  3. Grant the RAM role permissions to retrieve secrets.

    The permissions that the agent requires:

    • Retrieve secret values from KMS.

    • Decrypt the encrypted secrets using the decryption keys.

    Choose a method to complete the grant:

    • Method 1: Configure identity-based policies.

      For instructions, see Create a custom policy and Grant permissions to a RAM role.

      Example policy

      Replace the following parameters with the actual ones:

      • ${region}: The region ID to which the resource belongs.

      • ${account}: The Alibaba Cloud account to which the resource belongs.

      • example-secret: The secret name.

      • keyId-example: The decryption key ID.

      {
          "Version": "1",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "kms:GetSecretValue",
                  "Resource": "acs:kms:${region}:${account}:secret/example-secret"
              },
              {
                  "Effect": "Allow",
                  "Action": "kms:Decrypt",
                  "Resource": "acs:kms:${region}:${account}:key/keyId-example"
              }
          ]
      }
    • Method 2: Configure resource-based policies.

      This method allows you to configure access permissions for individual keys and secrets to control which Alibaba Cloud accounts, RAM users, and RAM roles have permissions to manage or use KMS keys and secrets. For more information, see Key policies and Secret policies.

ECS instance RAM role

  1. Log on to the RAM console, and create an instance RAM role whose Principal Type is an Alibaba Cloud service.

    • Principal Type: Select Cloud Service.

    • Principal Name: Select Elastic Compute Service / ECS.

  2. Grant the RAM role permissions to retrieve secrets.

    The permissions that the agent requires:

    • Retrieve secret values from KMS.

    • Decrypt the encrypted secrets using the decryption keys.

    Choose a method to complete the grant:

    • Method 1: Configure identity-based policies.

      For instructions, see Create a custom policy and Grant permissions to a RAM role.

      Example policy

      Replace the following parameters with the actual ones:

      • ${region}: The region ID to which the resource belongs.

      • ${account}: The Alibaba Cloud account to which the resource belongs.

      • example-secret: The secret name.

      • keyId-example: The decryption key ID.

      {
          "Version": "1",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "kms:GetSecretValue",
                  "Resource": "acs:kms:${region}:${account}:secret/example-secret"
              },
              {
                  "Effect": "Allow",
                  "Action": "kms:Decrypt",
                  "Resource": "acs:kms:${region}:${account}:key/keyId-example"
              }
          ]
      }
    • Method 2: Configure resource-based policies.

      This method allows you to configure access permissions for individual keys and secrets to control which Alibaba Cloud accounts, RAM users, and RAM roles have permissions to manage or use KMS keys and secrets. For more information, see Key policies and Secret policies.

  3. Log on to the ECS console, and attach the instance RAM role to an ECS instance. image

RRSA

ACK supports RRSA, which enables OpenAPI permission isolation at the pod level within a cluster. This provides fine-grained isolation of cloud resource access permissions and minimizes security risks.

  1. Enable RRSA.

  2. Create a RAM role.

    If you want to use an existing RAM role, you must modify its trust policy.

    Otherwise, create a new role on the RAM console. The main parameters are listed below. For detailed instructions, see Create a RAM role for an OIDC IdP.

    Parameter

    Description

    Identity Provider Type

    Select OIDC.

    Identity Provider

    Select an IdP. It is named in the ack-rrsa-<cluster_id> format.

    Conditions

    • oidc:iss: Use the default value.

    • oidc:aud: Use the default value.

    • oidc:sub: Manually add this condition.

      • Key: Select oidc:sub.

      • Operator: Select StringEquals.

      • Value: Enter system:serviceaccount:<namespace>:<serviceAccountName>.

        • <namespace>: Specify the namespace of the application.

        • <serviceAccountName>: Specify the name of the service account.

    RAM Role Name

    Set a name for the RAM role.

  3. Grant the RAM role permissions to retrieve secrets.

    The permissions that the agent requires:

    • Retrieve secret values from KMS.

    • Decrypt the encrypted secrets using the decryption keys.

    Choose a method to complete the grant:

    • Method 1: Configure identity-based policies.

      For instructions, see Create a custom policy and Grant permissions to a RAM role.

      Example policy

      Replace the following parameters with the actual ones:

      • ${region}: The region ID to which the resource belongs.

      • ${account}: The Alibaba Cloud account to which the resource belongs.

      • example-secret: The secret name.

      • keyId-example: The decryption key ID.

      {
          "Version": "1",
          "Statement": [
              {
                  "Effect": "Allow",
                  "Action": "kms:GetSecretValue",
                  "Resource": "acs:kms:${region}:${account}:secret/example-secret"
              },
              {
                  "Effect": "Allow",
                  "Action": "kms:Decrypt",
                  "Resource": "acs:kms:${region}:${account}:key/keyId-example"
              }
          ]
      }
    • Method 2: Configure resource-based policies.

      This method allows you to configure access permissions for individual keys and secrets to control which Alibaba Cloud accounts, RAM users, and RAM roles have permissions to manage or use KMS keys and secrets. For more information, see Key policies and Secret policies.

Step 3: Deploy KMS Agent

The agent supports the following deployment methods:

  • Local deployment: Deploy the agent locally using the binary and configuration file, suitable for small-scale or testing environments.

  • Linux environment deployment: Deploy the agent on a Linux server and manage it with systemd to ensure automatic operation at system startup. Below, we use deployment to an ECS instance as an example.

  • Sidecar container deployment: Use docker-compose to orchestrate the deployment and management of the agent sidecar and application containers.

  • ACK deployment: Deploy the agent as a sidecar container alongside the application container using Docker.

Local deployment

Here we use a RAM user's AccessKey as an example of access credentials.

  1. Configure environment variables to set up the authentication information required for the agent to operate.

    # AccessKey ID of the RAM user.
    export ALIBABA_CLOUD_ACCESS_KEY_ID=***
    # AccessKey Secret of the RAM user.
    export ALIBABA_CLOUD_ACCESS_KEY_SECRET=***
    # Path to the SSRF Token file created on the agent startup.
    export KMS_TOKEN='file:///var/run/kmstoken'
  2. Generate an SSRF Token and save it in the specified file.

    # Generate an SSRF token and store it in the file /var/run/kmstoken.
    ./alibabacloud-kms-agent token /var/run/kmstoken
  3. Modify the configuration file as needed.

    config.toml

    [Server]
    HttpPort = 2025
    
    [Kms]
    Region = "ap-southeast-1"
    
    [Cache]
    CacheType = "InMemory"
    CacheSize = 1000
    TtlSeconds = 300
    
    [Log]
    LogLevel = "Debug"
    LogPath = "./logs/"
    MaxSize = 100
    MaxBackups = 2
  4. Start the agent.

    ./alibabacloud-kms-agent agent ./config.toml

Linux (ECS) deployment

Here we use ECS instance RAM roles as an example of access credentials.

  1. Set environment variables to configure the authentication required for agent operation.

    # Name of the ECS instance RAM role..
    export ALIBABA_CLOUD_ECS_METADATA=***
    # Path to the SSRF Token file created on the agent startup.
    export KMS_TOKEN='file:///var/run/kmstoken'
  2. Install and start the agent.

    1. Enter the installation directory.

      cd alibabacloud-kms-agent/deploy/linux
    2. Upload the following files to the installation directory:

      • alibabacloud-kms-agent: The agent binary file built in the KMS Agent.

      • config.toml: The agent's configuration file, as shown below:

        config.toml

        [Server]
        HttpPort = 2025
        
        [Kms]
        Region = "ap-southeast-1"
        
        [Cache]
        CacheType = "InMemory"
        CacheSize = 1000
        TtlSeconds = 300
        
        [Log]
        LogLevel = "Debug"
        LogPath = "./logs/"
        MaxSize = 100
        MaxBackups = 2
      • alibabacloud-kms-agent.service: The systemd service file for managing the agent.

    3. Run the install.sh command as the root user.

      sudo bash -x ./install.sh
      • The install.sh script automatically generates an SSRF Token file for identity authentication between the application and agent, preventing SSRF attacks.

      • The agent uses systemd (alibabacloud-kms-agent.service) for automated startup and process monitoring.

    4. Set the User field in alibabacloud-kms-agent.service to the application user to enable access to the SSRF token and the agent.

Sidecar container deployment

Here we use a RAM user's AccessKey as an example of access credentials.

  1. Create two Dockerfiles for the containers.

  2. Compose a container orchestration file.

    This file configures the authentication information required for the agent as environment variables, as shown below:

        environment:
          # AccessKey ID of the RAM user.
          - ALIBABA_CLOUD_ACCESS_KEY_ID=<ak>
          # AccessKey Secret of the RAM user.
          - ALIBABA_CLOUD_ACCESS_KEY_SECRET=<sk>
          # Path to the SSRF Token file created on the agent startup.
          - KMS_TOKEN='file:///var/run/kmstoken'
  3. Modify the configuration file as needed.

    config.toml

    [Server]
    HttpPort = 2025
    
    [Kms]
    Region = "ap-southeast-1"
    
    [Cache]
    CacheType = "InMemory"
    CacheSize = 1000
    TtlSeconds = 300
    
    [Log]
    LogLevel = "Debug"
    LogPath = "./logs/"
    MaxSize = 100
    MaxBackups = 2
  4. Build and start the container.

    1. Put the alibabacloud-kms-agent binary file, the config.toml file, the Dockerfile.agent, and the Dockerfile.app in the same directory as the docker-compose.yml file.

      deploy/docker-compose/
      ├── alibabacloud-kms-agent
      ├── config.toml
      ├── Dockerfile.agent
      ├── Dockerfile.app
      └── docker-compose.yml
    2. Run the command docker-compose up --build.

  5. Log on to your application container and access the agent from within the container.

ACK deployment

Here, we use RRSA as an example of access credentials.

  1. Modify the configuration file as needed.

    config.toml

    [Server]
    HttpPort = 2025
    
    [Kms]
    Region = "ap-southeast-1"
    
    [Cache]
    CacheType = "InMemory"
    CacheSize = 1000
    TtlSeconds = 300
    
    [Log]
    LogLevel = "Debug"
    LogPath = "./logs/"
    MaxSize = 100
    MaxBackups = 2
  2. Build the agent sidecar container image.

    Navigate to the deploy/ack/agent directory, create a Dockerfile, and build the agent container image. Dockerfile reference.

    cd alibabacloud-kms-agent/deploy/ack/agent
    # Test upload to Alibaba Cloud container registry.
    docker build -t registry.<REGION_ID>.aliyuncs.com/<NAMESPACE>/<REPOSITORY>
    docker push registry.<REGION_ID>.aliyuncs.com/<NAMESPACE>/<REPOSITORY>:kmsagent-1.0
  3. Build the application container image.

    Navigate to the deploy/ack/app directory, create a Dockerfile, and build the application container image. Dockerfile reference.

    cd alibabacloud-kms-agent/deploy/ack/app
    docker build -t registry.cn-hangzhou.aliyuncs.com/<namespace>/<repository> .
    docker push registry.cn-hangzhou.aliyuncs.com/<namespace>/<repository>:app-1.0
  4. Create a Kubernetes YAML file to deploy the application and agent containers to ACK. YAML file reference.

    Use the alibabacloud-kms-agent/deploy/ack/demo.yaml file as a template. Modify it as needed and deploy both containers to your ACK cluster using kubectl apply -f <YAML_FILE_NAME>.yaml.

    This YAML file configures the authentication required for the agent as environment variables, as shown below:

              env:
                # Path to the SSRF Token file created on the agent startup.
                - name: KMS_TOKEN
                  value: 'file:///var/run/kmstoken'
                # Alibaba Cloud Resource Name (ARN) of the RAM role.
                - name: ALIBABA_CLOUD_ROLE_ARN
                  value: acs:ram::<account>:role/<rolename>
                # ARN of the OIDC identity provider. In this case, the ACK cluster ARN.
                - name: ALIBABA_CLOUD_OIDC_PROVIDER_ARN
                  value: acs:ram::<account>:oidc-provider/<ack cluster id>
                # File path containing the OIDC Token.
                - name: ALIBABA_CLOUD_OIDC_TOKEN_FILE
                  value: /var/run/secrets/ack.alibabacloud.com/rrsa-tokens/token
  5. Run the container application.

    1. Put the alibabacloud-kms-agent binary file, the config.toml file, the agent Dockerfile, and application Dockerfile in the same directory as the Kubernetes YAML file. See the example directory structure below:

      deploy/ack/
      ├── alibabacloud-kms-agent
      ├── config.toml
      ├── Dockerfile.agent
      ├── Dockerfile.app
      └── deployment-demo.yaml
    2. Run the container application. For detailed instructions, see Create Stateless Workload Deployment.

Step 4: Retrieve secrets

The agent retrieves the ACSCurrent version of secrets by default. To retrieve secret values of other versions, set versionStage or versionId.

Important

The agent only listens on 127.0.0.1 or localhost, restricting communication to applications or processes on the same machine. External network connections are prohibited, and the access endpoint cannot be changed to the application's local IP address. The examples below use localhost.

Sample code

curl

Replace <SecretId> in the example code with your actual secret name.

 # Read token from file
 curl -v -H "X-KMS-Token:$(</var/run/kmstoken)" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>'
 
 # Write token directly
 curl -v -H "X-KMS-Token:<token>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>'

Specify versionStage or versionId to retrieve a specific secret value. For example, to retrieve a secret value with a specific versionId, replace 0a7513ee719da740807b15b77500**** with your actual secret version.

 # Read token from file
 curl -v -H "X-KMS-Token:$(</var/run/kmstoken)" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>&versionId=0a7513ee719da740807b15b77500****'
 
 # Write token directly
 curl -v -H "X-KMS-Token:<token>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>&versionId=0a7513ee719da740807b15b77500****'

Go

Replace agent-test in the example code with your actual secret name.

package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
)

func main() {
	
	//You can specify versionStage or versionId to retrieve a specific secret value.
	//For example, to retrieve a secret value with a specific versionId, url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s&versionId=%s", "agent-test", "version-id").
	url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s", "agent-test")

	token, err := ioutil.ReadFile("/var/run/kmstoken")
	if err != nil {
		fmt.Printf("error reading token file: %v\n", err)
	}

	req, err := http.NewRequest("GET", url, nil)
	if err != nil {
		fmt.Printf("error creating request: %v\n", err)
	}

	req.Header.Add("X-KMS-Token", string(token))

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Printf("error sending request: %v \n", err)
	}
	defer resp.Body.Close()

	body, _ := ioutil.ReadAll(resp.Body)
	fmt.Printf("status code %d - %s \n", resp.StatusCode, string(body))
}