You can create a Resource Access Management (RAM) role for an Elastic Compute Service (ECS) instance in a virtual private cloud (VPC). Then, applications on the ECS instance can access Key Management Service (KMS) by using an SDK or a temporary access credential provided by Security Token Service (STS).

Step 1: Create an instance RAM role and grant the required permissions to the role

  1. Create an instance RAM role.
    Call the CreateRole operation of RAM to create the EcsRamRoleTest RAM role by using OpenAPI Explorer. Specify the following request parameters for the operation:
    • RoleName: the name of the instance RAM role. In this example, enter EcsRamRoleTest.
    • AssumeRolePolicyDocument: the content of the policy that specifies an ECS instance to assume the RAM role. In this example, enter the following content:
      {
          "Statement": [
              {
                  "Action": "sts:AssumeRole", 
                  "Effect": "Allow", 
                  "Principal": {
                      "Service": [
                          "ecs.aliyuncs.com"
                      ]
                  }
              }
          ], 
          "Version": "1"
      }
  2. Grant the instance RAM role the permissions to access KMS.
    Call the AttachPolicyToRole operation of RAM to attach the AliyunKMSFullAccess system policy to the EcsRamRoleTest RAM role by using OpenAPI Explorer. Specify the following request parameters for the operation:
    • PolicyType: the type of the policy. Set this parameter to System, which indicates a system policy.
    • PolicyName: the name of the system policy. In this example, enter AliyunKMSFullAccess, which indicates a system policy for KMS.
    • RoleName: the name of the instance RAM role. In this example, enter EcsRamRoleTest.

Step 2: Assign the instance RAM role to an ECS instance

You can use one of the following methods to assign the instance RAM role to an ECS instance:
  • Assign the instance RAM role to an existing ECS instance.

    Call the AttachInstanceRamRole operation of ECS to assign the instance RAM role to an existing ECS instance in a VPC by using OpenAPI Explorer. Specify the following request parameters for the operation:

    • RegionId: the ID of the region where the ECS instance resides.
    • RamRoleName: the name of the instance RAM role. In this example, enter EcsRamRoleTest.
    • InstanceIds: the ID of the ECS instance in a VPC. Set this parameter to a value in the ["i-bXXXXXXXX"] format.
  • Specify the instance RAM role when you create an ECS instance.
    1. Create an instance.
      Call the CreateInstance operation of ECS to create an ECS instance by using OpenAPI Explorer. Specify the following request parameters for the operation:
      • RegionId: the ID of the region where you want to create the ECS instance. In this example, enter cn-hangzhou.
      • ImageId: the ID of the image used to create the ECS instance. In this example, enter centos_7_03_64_40G_alibase_20170503.vhd.
      • InstanceType: the type of the ECS instance. In this example, enter ecs.g6.large.
      • VSwitchId: the ID of the vSwitch in the VPC where you want to create the ECS instance.
        Note You can assign instance RAM roles to ECS instances only in VPCs. Therefore, this parameter is required.
      • RamRoleName: the name of the instance RAM role. In this example, enter EcsRamRoleTest.

      You can also authorize a RAM user to assume the RAM role. For more information, see Use an instance RAM role by calling API operations.

    2. Set the password and start the ECS instance.
    3. Allow the ECS instance to access the Internet in the ECS console or by calling an API operation.

Step 3: (Optional) Obtain a temporary access credential

You can obtain a temporary access credential for the RAM role. The credential contains a token and is updated on a regular basis. The credential allows you to use the permissions and resources granted to the RAM role. To obtain a temporary access credential, perform the following steps:

  1. Query the temporary access credential of the EcsRamRoleTest RAM role.
    • Linux ECS instance: Run the curl http://100.100.100.200/latest/meta-data/ram/security-credentials/EcsRamRoleTest command.
    • Windows ECS instance: For more information, see Overview of ECS instance metadata.
  2. Obtain the temporary access credential.
    Example of a temporary access credential:
    {
       "AccessKeyId" : "STS.J8XXXXXXXXXX4",
       "AccessKeySecret" : "9PjfXXXXXXXXXBf2XAW",
       "Expiration" : "2017-06-09T09:17:19Z",
       "SecurityToken" : "CAIXXXXXXXXXXXwmBkleCTkyI+",
       "LastUpdated" : "2017-06-09T03:17:18Z",
       "Code" : "Success"
    }

Step 4: Access KMS by using an SDK

You can use an SDK to access KMS in one of the following methods:

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);

        // Specify the RAM role. 
        String roleName = "<your-ecs-ram-role-name>"; // Enter EcsRamRoleTest. 

        // Configure the credential provider of the instance RAM role. 
        AlibabaCloudCredentialsProvider provider = new InstanceProfileCredentialsProvider(roleName);

        IAcsClient client = new DefaultAcsClient(profile, provider);

        EncryptRequest request = new EncryptRequest();

        // Specify the CMK alias or CMK ID that is used to encrypt "Hello world". 
        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 an ECS instance based on an instance RAM role. 
  */
 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();
         // Specify the RAM role. 
         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));
     }
 }