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:
Applications send HTTP requests to the agent.
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.
If the secret is not in the cache or is expired, the agent uses the KMS client to fetch it from the configured KMS.
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
Compatibility
Stability and Reliability
How to use the agent?
Step 1: Build the KMS Agent binary
Download the source code and dependencies.
git clone https://github.com/aliyun/alibabacloud-kms-agent go mod download
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.
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
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.
Log on to the RAM console. In the left-side navigation pane, choose Identities > Users, and click on the desired RAM user.
In the Authentication tab, click Create Accesskey and follow the instructions to complete the creation.
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.
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.
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'
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
Modify the configuration file based on your business needs.
Start the agent.
./alibabacloud-kms-agent agent ./config.toml
Linux environment (ECS) deployment
Create identity credentials.
We recommend using the ECSRole to access KMS.
Install and start the agent.
Enter the installation directory.
cd alibabacloud-kms-agent/deploy/linux
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.
alibabacloud-kms-agent.service: The systemd service file for managing the agent.
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.Configure the
alibabacloud-kms-agent.service
User
parameter to match the application user, enabling access to KMS.
Sidecar container deployment
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.
Log on to the RAM console. In the left-side navigation pane, choose Identities > Users, and click on the desired RAM user.
In the Authentication tab, click Create Accesskey and follow the instructions to complete the creation.
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.
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.
Create Dockerfiles.
Navigate to the
deploy/docker-compose/
directory, and create two Dockerfiles:Dockerfile.agent: Builds the agent sidecar container. Dockerfile.agent reference.
Dockerfile.app: Builds your application container. Dockerfile.app reference.
Create the container orchestration file.
Modify the configuration file based on your business needs.
Build and start containers.
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
Run the command
docker-compose up --build
.
Log on to your application container and access the agent from within the container.
ACK deployment
Create identity credentials.
We recommend using RAM Roles for Service Accounts (RRSA) to access KMS. For instructions, see Enable RRSA.
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.
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.
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.
Modify the configuration file based on your business needs.
Build the agent sidecar container image.
Navigate to the
alibabacloud-kms-agent/deploy/ack/agent
directory, and create aDockerfile
.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
Build the application container image.
Navigate to the
alibabacloud-kms-agent/deploy/ack/app
directory, and create aDockerfile
.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
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 usingkubectl 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))
}