All Products
Search
Document Center

Key Management Service:Use KMS Agent to retrieve secrets

Last Updated:Mar 07, 2025

The KMS Agent is a client-side HTTP proxy that simplifies secret retrieval by centralizing KMS interactions. Applications retrieve secrets through local HTTP requests instead of direct SDK integration, minimizing code changes and ensuring uniform security policies. It handles credential management (configured once for all applications), in-memory caching, and periodic secret refreshes to reduce SDK call frequency and network overhead. It can be deployed in local environments, virtual machines such as Elastic Compute Service (ECS), and containerized systems. This topic describes the agent's operation and how to use it to retrieve secrets.

How it works

The agent prioritizes cached data to efficiently retrieve secrets and improve performance. It comprises four components: HTTP server, cache, KMS client, and log. The process is as follows:

image
  1. Applications send HTTP requests to the agent.  

    More

    The agent's HTTP server includes built-in protection against Server-Side Request Forgery (SSRF) attacks. At startup, it creates an SSRF token file (/var/run/kmstoken). Applications making HTTP requests to the agent must include this token in the request header for authentication and processing. The requests must be path-based (GET /v1/secretId) or query-based (GET /secretsmanager/get?secretId=<secretid>).

  2. The agent checks in-memory cache for the secret.

    If the requested secret is found and valid, it's immediately returned. Secret values are not encrypted in the cache.

  3. If the secret is not in the cache or is expired, the agent uses the KMS client to fetch it from the configured KMS.

    More

    The agent uses Alibaba Cloud's Default credential provider chain to access KMS. This lets you use the same code to get credentials for different environments using application-independent configurations. It connects to KMS through either a shared or dedicated gateway, with built-in CA certificates for dedicated gateways.

  4. If the KMS is unreachable, the agent falls back to using the cached version of the secret, if there is one.

    This ensures availability even during temporary KMS outage.

All operations are logged in JSON format using the Zap logging framework, with configurable file size and retention policies. You can configure these four components with a configuration file as shown below. See alibabacloud-kms-agent for the source code.

KMS Agent configuration file

# All configuration parameters. 

[Server]
# Optional. Default value: 2025 (Listens on 127.0.0.1:2025). 
# Specify the port that the agent listens on.
HttpPort = 2025

# Optional. Default value: ["X-KMS-Token", "X-Vault-Token"].
# Specify the authentication token used to access the system that the agent accesses. Access fails without the correct header.
SSRFHeaders = ["X-KMS-Token", "X-Vault-Token"]

# Optional. Default value: ["KMS_TOKEN", "KMS_SESSION_TOKEN", "KMS_CONTAINER_AUTHORIZATION_TOKEN"]. 
# The variable value can be a specific value or a file path such as file:///var/run/awssmatoken. The agent retrieves the SSRF token from the SSRFEnvVariables, compares it to the token carried in the application's access header, and allows access only if they match.
SSRFEnvVariables = ["KMS_TOKEN", "KMS_SESSION_TOKEN", "KMS_CONTAINER_AUTHORIZATION_TOKEN"]

# Optional. Default value: "/v1/".
# The URI prefix for path-based access requests.
PathPrefix = "/v1/"

# Optional. Default value: 800.
# The maximum number of concurrent requests allowed.
MaxConn = 800

# Optional. Default value: 0.
# 0: Secret content is returned in the format of Alibaba Cloud KMS GetSecretvalue API Response. 1: Secret content is returned in the format of AWS Secret Manager GetSecretvalue API Response. 2: Secret content is returned in the format of HashiCorp KV structure.
ResponseType = 0

# Optional. Default value is true.
# If it's true, returns expired cached secrets when cache expires and remote KMS access fails.
IgnoreTransientErrors = true

[Kms]
# Optional. Default value: cn-hangzhou.
# The region of KMS to be accessed.
Region = "ap-southeast-1"

# Optional. Default value: kms.cn-hangzhou.aliyuncs.com.
# The endpoint supports the shared gateway endpoint and dedicated gateway endpoint. 
# For more information on endpoint, see: https://www.alibabacloud.com/help/en/kms/key-management-service/developer-reference/classic-kms-sdkclassic-kms-sdk/#3b8b6b498e958.
Endpoint = "kms.ap-southeast-1.aliyuncs.com"

[Cache]
# Optional. Default value: InMemory. 
# The cache type. Only memory cache is supported.
CacheType = "InMemory"

# Optional. Default value: 1000.  
# The maximum number of secrets that can be stored in the cache. 0 indicates that each request accesses the remote KMS.
CacheSize = 1000

# Optional. Default value: 300.
# The Time To Live (TTL) for the secrets stored in the cache. Unit: seconds. 0 indicates no caching.
TtlSeconds = 300

# Optional. Default value: false.
# The cache eviction policy. Valid values: false: When CacheSize is reached, the earliest secrets are deleted. true: When CacheSize is reached, the least recently used secrets are deleted. 
EnableLRU = false

[Log]
# Optional. Default value: Debug.
# The level of detail reported in logs. Valid values: Debug, Info, Warn and Error. 
LogLevel = "Debug"

# Optional. Default value: ./logs/. The directory is in the application startup directory.
# Specify the directory of logs.
LogPath = "./logs/"


# Optional. Default value: 100.
# The maximum size of a log file. Unit: MB.
MaxSize = 100

# Optional. Default value: 2.
# The maximum number of log files.
MaxBackups = 2

Compatibility

The agent supports the key-value (KV) storage structures of AWS Secrets Manager and HashiCorp Vault, enabling seamless migration to Alibaba Cloud. All you need to do is update the endpoint to the Alibaba Cloud KMS endpoint and configure the agent.

Supported response formats

  • Alibaba Cloud KMS

    {
       "CreateTime": "2025-01-03T07:59:17Z",
       "RequestId": "cc315250-04c9-4caf-a055-6648f36598b9",
       "SecretData": "{\"k3\":\"v3\"}",
       "SecretDataType": "text",
       "SecretName": "agent-test",
       "SecretType": "Generic",
       "VersionId": "v2",
       "VersionStages": {
          "VersionStage": [
             "ACSCurrent"
          ]
       }
    }
  • AWS Secrets Manager

     {
       "ARN": "",
       "Name": "agent-test",
       "VersionId": "v2",
       "SecretString": "{\"k3\":\"v3\"}",
       "VersionStages": [
          "ACSCurrent"
       ],
       "CreatedDate": "2025-01-03T07:59:17Z"
    }
  • HashiCorp Vault

    {
       "data": {
          "k3": "v3"
       }
    }

Stability and Reliability

The agent ensures a robust and stable connection to KMS.

  • Automatic health checks

    Automatically verifies the KMS connection on startup. If the connection fails, the agent will not start, preventing unnecessary requests and resource consumption.

  • Resilient error handling

    • Automatic retries: Uses Alibaba Cloud SDK V2 to communicate with KMS. In case of network errors, it leverages the SDK's built-in retry logic to automatically resend requests. For rate-limiting errors (HTTP 429) and server errors (HTTP 500), it employs exponential backoff (maximum 3 retries).

    • Use of expired cache: Uses locally cached data to maintain application uptime during temporary KMS outages (network issues or server problems), even if the cache has expired. Enabled by default. You can further customize this feature using the IgnoreTransientErrors parameter.

  • High availability

    • Linux systems: Managed by systemd on Linux, ensuring automatic restarts if the agent process crashes.

    • Sidecar container: Deployed as an init container, the agent failing will trigger a container restart, guaranteeing application stability.

How to use the agent?

Step 1: Build the KMS Agent binary

  1. Install the Golang environment.

  2. Download the source code and dependencies.

    git clone https://github.com/aliyun/alibabacloud-kms-agent
    go mod download
  3. Cross-platform compile the binary file.

    This lets you create binaries for different operating systems and architectures in your local environment, enhancing development efficiency, supporting multi-platform deployment, reducing dependencies, and increasing security.

    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 .

Step 2: 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. Use the 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.

  • Container Service for Kubernetes (ACK) deployment: Deploy the agent as a sidecar container alongside the application container using Docker.

Local deployment

  1. Create access credentials.

    Use 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 AccessKeys for Alibaba Cloud accounts. Instead, create a RAM user solely for API access, generate its AccessKey, 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 desired RAM user.

    2. In the Authentication tab, click Create Accesskey and follow the instructions to complete the creation.

    3. Grant the RAM user permissions to retrieve KMS secrets.

      The agent requires permissions to retrieve secrets values from KMS during the secrets caching process. If the secret value is encrypted by using a key, the kms:Decrypt access must also be granted on the key.

      • Method 1: Through identity-based policies

        For details, see Create custom policies and Grant permissions to a RAM user.

        Permission policy example

        Replace the following parameters with the actual values:

        • ${region} : The region of the resource.

        • ${account}: The Alibaba Cloud account owning the resource.

        • example-secret: The secret name.

        • keyId-example: The 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: Through resource-based policies

        KMS supports resource-based policies, which allow you to set access permissions for keys and secrets. For more information, see Key policies and Secret policies.

  2. Set environment variables and configure the authentication details required for agent operation.

    export ALIBABA_CLOUD_ACCESS_KEY_SECRET=***
    export ALIBABA_CLOUD_ACCESS_KEY_ID=***
    export KMS_TOKEN='file:///var/run/kmstoken'
  3. Generate the SSRF Token and store 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
  4. Modify the configuration file based on your business needs.

    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
  5. Start the agent.

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

Linux environment (ECS) deployment

  1. Create identity credentials.

    We recommend using the ECSRole to access KMS.

    Use ECS instance RAM role

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

      • Select Trusted Entity: Select Alibaba Cloud Service.

      • Role Type: Select Normal Service Role.

      • Select Trusted Service: Select Elastic Compute Service.

    2. Grant the RAM role access to retrieve KMS secrets.

      The agent requires permissions to retrieve secrets values from KMS during the secrets caching process. If the secret value is encrypted by using a key, the kms:Decrypt access must also be granted on the key.

      • Method 1: Through identity-based policies

        For details, see Create custom policies and Grant permissions to a RAM role.

        Permission policy example

        Replace the following parameters with the actual values:

        • ${region} : The region of the resource.

        • ${account}: The Alibaba Cloud account owning the resource.

        • example-secret: The secret name.

        • keyId-example: The 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: Through resource-based policies

        KMS supports resource-based policies, which allow you to set access permissions for 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

  2. Install and start the agent.

    1. Enter the installation directory.

      cd alibabacloud-kms-agent/deploy/linux
    2. Check the following files are present in the installation directory:

      • alibabacloud-kms-agent: The agent binary file.

      • 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.

    4. Configure the alibabacloud-kms-agent.service User parameter to match the application user, enabling access to KMS.

Sidecar container deployment

  1. Create access credentials.

    Use 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 AccessKeys for Alibaba Cloud accounts. Instead, create a RAM user solely for API access, generate its AccessKey, 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 desired RAM user.

    2. In the Authentication tab, click Create Accesskey and follow the instructions to complete the creation.

    3. Grant the RAM user permissions to retrieve KMS secrets.

      The agent requires permissions to retrieve secrets values from KMS during the secrets caching process. If the secret value is encrypted by using a key, the kms:Decrypt access must also be granted on the key.

      • Method 1: Through identity-based policies

        For details, see Create custom policies and Grant permissions to a RAM user.

        Permission policy example

        Replace the following parameters with the actual values:

        • ${region} : The region of the resource.

        • ${account}: The Alibaba Cloud account owning the resource.

        • example-secret: The secret name.

        • keyId-example: The 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: Through resource-based policies

        KMS supports resource-based policies, which allow you to set access permissions for keys and secrets. For more information, see Key policies and Secret policies.

  2. Create Dockerfiles.

    Navigate to the deploy/docker-compose/ directory, and create two Dockerfiles:

  3. Create the container orchestration file.

    docker-compose.yaml reference.

  4. Modify the configuration file based on your business needs.

    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
  5. Build and start containers.

    1. Place the following files in the same directory as your docker-compose.yaml file:

      • alibabacloud-kms-agent (binary)

      • config.toml (configuration file)

      • Dockerfile.agent

      • Dockerfile.app

    2. Run the command docker-compose up --build.

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

ACK deployment

  1. Create identity credentials.

    We recommend using RAM Roles for Service Accounts (RRSA) to access KMS. For instructions, see Enable RRSA.

  2. Create a RAM role.

    If you want to use an existing RAM role, you must grant the required permissions to the RAM role.

    The following table describes the parameters. For details, see Create a RAM role for an OIDC IdP.

    Parameter

    Description

    Identity Provider Type

    Select OIDC.

    Identity Provider

    Select an IdP. The IdP is named in the ack-rrsa-<cluster_id> format. <cluster_id> indicates the ID of your cluster.

    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 permissions to the RAM role.

    The agent requires permissions to retrieve secrets values from KMS during the secrets caching process. If the secret value is encrypted by using a key, the kms:Decrypt access must also be granted on the key.

    • Method 1: Through identity-based policies

      For details, see Create custom policies and Grant permissions to a RAM role.

      Permission policy example

      Replace the following parameters with the actual values:

      • ${region} : The region of the resource.

      • ${account}: The Alibaba Cloud account owning the resource.

      • example-secret: The secret name.

      • keyId-example: The 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: Through resource-based policies

      KMS supports resource-based policies, which allow you to set access permissions for keys and secrets. For more information, see Key policies and Secret policies.

  4. Modify the configuration file based on your business needs.

    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
  5. Build the agent sidecar container image.

    1. Navigate to the alibabacloud-kms-agent/deploy/ack/agent directory, and create a Dockerfile.

      Dockerfile reference.

    2. Build the agent container image.

    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
  6. Build the application container image.

    1. Navigate to the alibabacloud-kms-agent/deploy/ack/app directory, and create a Dockerfile.

      Dockerfile reference.

    2. Build the application container image.

    The example below pushes to an Alibaba Cloud container registry. Replace placeholders with your actual values.

    cd alibabacloud-kms-agent/deploy/ack/app
    # 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>:app-1.0
  7. Create a Kubernetes YAML file to deploy the application and agent containers to ACK.

    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.

Step 3: Retrieve secrets

curl

The agent defaults to retrieving secrets from the current ACSC version, as shown in the example below.

To retrieve secrets from other versions, append versionStage or versionId parameters after secretId=<SecretId>. The command will look like this: curl -v -H ... secretId=<SecretId>&versionStage=<versionStage>&versionId=<versionId>'.

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

Go

The agent defaults to retrieving secrets from the current ACSC version, as shown in the example below. In actual use, replace agent-test in the example code with your actual secret name.

You can specify versionStage or versionId to retrieve specific secret values. For example, to retrieve secrets for a specified versionId, replace the line url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s", "agent-test") in the code below with url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s&versionId=%s", "agent-test", "version-id").

package main

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

func main() {
	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))
}