Assign a RAM role to an ECS instance so that applications running on it can call Key Management Service (KMS) APIs using automatically rotated temporary credentials — no hardcoded AccessKey required.
How it works
Instead of embedding long-term AccessKey credentials in your application, you attach a Resource Access Management (RAM) role to the ECS instance. The instance retrieves short-lived credentials from the metadata service, and the SDK automatically refreshes them before expiry. Your application never needs to manage credential rotation.
The setup involves four steps:
Create an instance RAM role and grant it KMS permissions.
Attach the role to an ECS instance.
(Optional) Retrieve a temporary credential to verify the setup.
Call KMS from your application using the SDK.
Instance RAM roles are only supported on ECS instances in a virtual private cloud (VPC).
Prerequisites
Before you begin, ensure that you have:
An ECS instance in a VPC
Permissions to create RAM roles and call ECS APIs
The KMS SDK, Encryption SDK, or Secrets Manager Client installed in your application
Step 1: Create an instance RAM role and grant KMS permissions
1. Create the RAM role.
Call the CreateRole operation of RAM using OpenAPI Explorer with the following parameters:
| Parameter | Value |
|---|---|
RoleName | EcsRamRoleTest |
AssumeRolePolicyDocument | See the policy document below |
Use the following trust policy to allow an ECS instance to assume the role:
{
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": [
"ecs.aliyuncs.com"
]
}
}
],
"Version": "1"
}2. Grant the role KMS permissions.
Call the AttachPolicyToRole operation of RAM using OpenAPI Explorer with the following parameters:
| Parameter | Value |
|---|---|
PolicyType | System |
PolicyName | AliyunKMSFullAccess |
RoleName | EcsRamRoleTest |
Step 2: Attach the RAM role to an ECS instance
Choose one of the following methods based on whether you are working with an existing instance or creating a new one.
Attach to an existing instance
Call the AttachInstanceRamRole operation of ECS using OpenAPI Explorer with the following parameters:
| Parameter | Value |
|---|---|
RegionId | ID of the region where the ECS instance resides |
RamRoleName | EcsRamRoleTest |
InstanceIds | Instance ID in ["i-bXXXXXXXX"] format |
Attach when creating a new instance
Call the CreateInstance operation of ECS using OpenAPI Explorer with the following parameters:
Parameter Value RegionIdcn-hangzhou(example)ImageIdcentos_7_03_64_40G_alibase_20170503.vhd(example)InstanceTypeecs.g6.large(example)VSwitchIdID of the vSwitch in your VPC — required, as instance RAM roles only work in VPCs RamRoleNameEcsRamRoleTestSet the instance password and start the instance.
Enable internet access for the instance from the ECS console or via API.
For information about authorizing a RAM user to assume this role, see Use an instance RAM role by calling API operations.
Step 3: (Optional) Retrieve a temporary credential
Retrieve the temporary credential to verify the role is attached correctly. The credential contains a token and is automatically refreshed on a regular basis.
Linux: Run the following command:
curl http://100.100.100.200/latest/meta-data/ram/security-credentials/EcsRamRoleTestWindows: See Overview of ECS instance metadata.
A successful response looks like this:
{
"AccessKeyId": "STS.J8XXXXXXXXXX4",
"AccessKeySecret": "9PjfXXXXXXXXXBf2XAW",
"Expiration": "2017-06-09T09:17:19Z",
"SecurityToken": "CAIXXXXXXXXXXXwmBkleCTkyI+",
"LastUpdated": "2017-06-09T03:17:18Z",
"Code": "Success"
}Step 4: Call KMS from your application
All three examples below use InstanceProfileCredentialsProvider, which automatically fetches and refreshes temporary credentials from the instance metadata service — no manual credential management needed.
KMS SDK
package com.aliyuncs.kms.examples;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.auth.AlibabaCloudCredentialsProvider;
import com.aliyuncs.auth.InstanceProfileCredentialsProvider;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.exceptions.ServerException;
import com.aliyuncs.kms.model.v20160120.*;
import com.aliyuncs.profile.DefaultProfile;
public class RamRoleTest {
public static void main(final String[] args) throws Exception {
String regionId = "<region-id>";
DefaultProfile profile = DefaultProfile.getProfile(regionId);
// Name of the instance RAM role attached to this ECS instance
String roleName = "<your-ecs-ram-role-name>"; // Enter EcsRamRoleTest.
// The provider fetches and refreshes temporary credentials automatically
AlibabaCloudCredentialsProvider provider = new InstanceProfileCredentialsProvider(roleName);
IAcsClient client = new DefaultAcsClient(profile, provider);
EncryptRequest request = new EncryptRequest();
// Key alias or key ID used to encrypt the plaintext
request.setKeyId("alias/Apollo/SalaryEncryptionKey");
request.setPlaintext("Hello world");
try {
EncryptResponse response = client.getAcsResponse(request);
System.out.println(new Gson().toJson(response));
} catch (ServerException e) {
e.printStackTrace();
} catch (ClientException e) {
System.out.println("ErrCode:" + e.getErrCode());
System.out.println("ErrMsg:" + e.getErrMsg());
System.out.println("RequestId:" + e.getRequestId());
}
}
}Encryption SDK
package com.aliyun.encryptionsdk.examples.credentials;
import com.aliyun.encryptionsdk.AliyunConfig;
import com.aliyun.encryptionsdk.AliyunCrypto;
import com.aliyun.encryptionsdk.exception.InvalidAlgorithmException;
import com.aliyun.encryptionsdk.exception.UnFoundDataKeyException;
import com.aliyun.encryptionsdk.model.CryptoResult;
import com.aliyun.encryptionsdk.provider.dataKey.DefaultDataKeyProvider;
import java.util.Collections;
import static org.junit.Assert.assertArrayEquals;
/**
* Authenticate using an instance RAM role via the Encryption SDK.
*/
public class EcsRamRoleSample {
private static final String PLAIN_TEXT = "this is test.";
private static final String cmkArn = "acs:kms:RegionId:UserId:key/CmkId";
private static final String ecRamRoleName = "EcsRamRoleTest";
public static void main(String[] args) {
AliyunConfig config = new AliyunConfig();
// Configure the RAM role — credentials are fetched automatically
config.withEcsRamRole(ecRamRoleName);
AliyunCrypto crypto = new AliyunCrypto(config);
DefaultDataKeyProvider defaultDataKeyProvider = new DefaultDataKeyProvider(cmkArn);
try {
CryptoResult<byte[]> encryptResult = crypto.encrypt(defaultDataKeyProvider, PLAIN_TEXT.getBytes(), Collections.singletonMap("sample", "Context"));
CryptoResult<byte[]> decryptResult = crypto.decrypt(defaultDataKeyProvider, encryptResult.getResult());
assertArrayEquals(decryptResult.getResult(), PLAIN_TEXT.getBytes());
} catch (InvalidAlgorithmException | UnFoundDataKeyException e) {
System.out.println("Failed.");
System.out.println("Error message: " + e.getMessage());
}
}
}Secrets Manager Client
package com.aliyuncs.kms.secretsmanager.examples;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.auth.InstanceProfileCredentialsProvider;
import com.aliyuncs.kms.secretsmanager.cacheclient.exception.CacheSecretException;
import com.aliyuncs.kms.secretsmanager.cacheclient.model.SecretInfo;
import com.aliyuncs.kms.secretsmanager.cacheclient.service.DefaultSecretManagerClientBuilder;
public class EcsSamples {
public static void main(String[] args) throws CacheSecretException {
String secretName = "<secret-name>";
String roleName = "<your-ecs-ram-role-name>";
String regionId = "<region-id>";
SecretCacheClient client = SecretCacheClientBuilder.newCacheClientBuilder(
DefaultSecretManagerClientBuilder.standard().withCredentialsProvider(new InstanceProfileCredentialsProvider(roleName)).withRegion(regionId)
.build()
).build();
SecretInfo secretInfo = client.getSecretInfo(secretName);
System.out.println("secretInfo:"+JSONObject.toJSONString(secretInfo));
}
}What's next
Use an instance RAM role by calling API operations — authorize a RAM user to assume the instance RAM role
Overview of ECS instance metadata — retrieve metadata on Windows instances