Similar to providing temporary badges to visitors for limited access within a building, Resource Access Management (RAM) roles provided by Alibaba Cloud enable users to assume temporary identities for managing operations within authorized scopes. This is useful for cross-account access, role-based single sign-on (SSO), and temporary authorization scenarios.
Scenarios
We will demonstrate the operation flow in a typical cross-account access scenario. Imagine your company runs an e-commerce website hosted on Alibaba Cloud Elastic Compute Service (ECS). While the IT department handles routine maintenance, external partners may be required for specific technical issues or specialized tasks. To protect cloud resource security, sharing accounts valid for a long term (such as Alibaba Cloud accounts and RAM users) with external partners is not advisable.
The process for authorizing cross-account access using RAM roles is as follows:
Account A represents the Alibaba Cloud account of your company.
Account B represents the Alibaba Cloud account of the external partner.
Account A creates a RAM role and grants permissions to Account B to assume the role.
Account B creates a RAM user and grants permissions to the user to assume the role.
The RAM user of Account B assumes the RAM role of Account A to perform operations on the resources of Account A.
Procedure
Step 1: Account A creates a RAM role and grants permissions to it
1. Create a RAM role
Log on to the RAM console by using Account A, create a RAM role with a trusted entity type of Alibaba Cloud account, and specify the account ID (UID) of Account B in the Select Trusted Alibaba Cloud Account field. For more information about how to create a RAM role, see Create a RAM role for a trusted Alibaba Cloud account.
2. Grant permissions to the RAM role
Create a policy that permits viewing ECS instance details and logging on to ECS instances by using Workbench, and attach this policy to the RAM role. For more information about how to manage permissions, see Create custom policies.
Step 2: Account B creates a RAM user and grants permissions to the user
1. Create a RAM user
Log on to the RAM console by using Account B, create a RAM user, and ensure that Console Access and OpenAPI Access are enabled. For more information, see Create a RAM user.
2. Grant permissions to the RAM user
To assume a RAM role, the RAM user must be granted the necessary permissions. Account B must attach the AliyunSTSAssumeRoleAccess
policy to the RAM user, enabling the user to assume any RAM role. For more information, see Grant permissions to a RAM user.
To restrict a RAM user to assume a specific RAM role, see Can I specify the RAM role that a RAM user can assume?
Step 3: Assume a RAM role
Assume a role by using consoles
Log on to the RAM User Logon page with the RAM user created by Account B.
Hover over the profile picture in the upper right corner and click Switch Identity.
On the Switch Role page, enter the required information and click Submit to log on. In this example, enter the UID of Account A and the RAM role name.
Verify that the access permission is assigned.
Log on to the ECS console to check the ECS instance information.
Verification 1: The RAM user is able to assume the RAM role of Account A to view the ECS instance information and log on to the instance by using Workbench.
Verification 2: After Account A revokes permissions, the RAM user cannot view the ECS instance information under Account A.
Assume a role by using program code
You can also access the resources of Account A by using program code. Refer to the following steps:
When you create the RAM user of Account B, you will get the AccessKey pair of the user. Configure the AccessKey pair in the system environment variables. For information about how to configure an AccessKey pair in environment variables of different operating systems, see Configure environment variables in Linux, macOS, and Windows.
Call the
AssumeRole
operation using the RAM user of Account B, input the ARN of the RAM role of Account A, and obtain a temporary STS Token with identity credentials.Use the STS Token to call the API operations and access the resources of Account A.
Java sample code:
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>ecs20140526</artifactId>
<version>5.4.4</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>sts20150401</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>credentials-java</artifactId>
<version>0.3.10</version>
</dependency>
import com.aliyun.ecs20140526.models.DescribeInstancesRequest;
import com.aliyun.ecs20140526.models.DescribeInstancesResponse;
import com.aliyun.sts20150401.Client;
import com.aliyun.sts20150401.models.AssumeRoleRequest;
import com.aliyun.sts20150401.models.AssumeRoleResponse;
import com.aliyun.sts20150401.models.AssumeRoleResponseBody;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.google.gson.Gson;
/**
* Obtain temporary access credentials by assuming a RAM role, and then use these credentials to access ECS resources.
*/
public class Sample {
public static void main(String[] args) {
// For reference only, be sure to select the endpoint of a specific region according to the actual business situation
String stsEndpoint = "sts.cn-shanghai.aliyuncs.com";
String ecsEndpoint = "ecs.cn-shanghai.aliyuncs.com";
// Query ECS instance information in cn-shanghai
String regionId = "cn-shanghai";
// The ARN of the RAM role to assume.
String ramRoleArn = "acs:ram::14************16:role/cooperativepartnerrole";
// Use the RAM user of Account B to assume the RAM role of Account A and obtain temporary access credentials.
AssumeRoleResponse assumeRoleResponse = playRamRole(stsEndpoint, ramRoleArn);
// Call the API operation to view the resources of Account A.
accessResources(assumeRoleResponse, ecsEndpoint, regionId);
}
/**
* Access resources using temporary access credentials.
*
* @param assumeRoleResponse The response object containing temporary access credentials.
*/
private static void accessResources(AssumeRoleResponse assumeRoleResponse, String ecsEndpoint, String regionId) {
try {
// Extract temporary access credential information.
AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials assumeRoleResponseBodyCredentials = assumeRoleResponse.body.credentials;
com.aliyun.credentials.models.Config credentialsConfig = new com.aliyun.credentials.models.Config()
.setType("sts") // Credential type.
.setAccessKeyId(assumeRoleResponseBodyCredentials.accessKeyId)
.setAccessKeySecret(assumeRoleResponseBodyCredentials.accessKeySecret)
.setSecurityToken(assumeRoleResponseBodyCredentials.securityToken);
com.aliyun.credentials.Client credentialClient = new com.aliyun.credentials.Client(credentialsConfig);
// Create an ECS client.
Config ecsConfig = new Config()
.setEndpoint(ecsEndpoint)
.setCredential(credentialClient);
com.aliyun.ecs20140526.Client ecsClient = new com.aliyun.ecs20140526.Client(ecsConfig);
DescribeInstancesRequest describeInstancesRequest = new DescribeInstancesRequest()
.setRegionId(regionId);
RuntimeOptions runtimeOptions = new RuntimeOptions();
// Call the DescribeInstances operation and get the response.
DescribeInstancesResponse response = ecsClient.describeInstancesWithOptions(describeInstancesRequest, runtimeOptions);
// Print the response result.
System.out.println(new Gson().toJson(response.body));
} catch (Exception e) {
throw new RuntimeException("AccessResources failed: " + e.getMessage());
}
}
/**
* Assume a RAM role to obtain temporary access credentials.
*
* @return The response object containing temporary access credentials.
*/
private static AssumeRoleResponse playRamRole(String stsEndpoint, String ramRoleArn) {
try {
// Create an StsClient object and call the AssumeRole operation to obtain an STS Token
Config config = new Config()
// System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID") indicates obtaining the value of AccessKey ID from the environment variable
.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"))
// System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET") indicates obtaining the value of AccessKey Secret from the environment variable
.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
config.endpoint = stsEndpoint;
Client client = new Client(config);
// Create an AssumeRole request object, specifying the ARN of the RAM role to assume and the role session name.
AssumeRoleRequest assumeRoleRequest = new AssumeRoleRequest()
.setRoleArn(ramRoleArn)
.setRoleSessionName("CooperativePartner");
RuntimeOptions runtime = new RuntimeOptions();
return client.assumeRoleWithOptions(assumeRoleRequest, runtime);
} catch (Exception e) {
throw new RuntimeException("play RAM role failed: " + e.getMessage());
}
}
}
Result: The program returns a list of ECS resources owned by Account A in the Hangzhou region.
{
"instances":{
"instance":[
{
"creationTime":"2024-10-23T09:12Z",
"expiredTime":"2099-12-31T15:59Z",
"hostName":"iZ********************pZ",
"imageId":"m-uf****************jf",
"instanceChargeType":"PostPaid",
"instanceId":"i-uf****************ap",
"instanceName":"launch-advisor-20241023-c6",
"instanceNetworkType":"vpc",
"instanceType":"ecs.c6.xlarge",
...
// Some parameters are omitted
...
"vpcAttributes":{
"natIpAddress":"",
"privateIpAddress":{
"ipAddress":[
"17*.**.**.*15"
]
},
"vSwitchId":"vsw-uf*****************tk",
"vpcId":"vpc-uf*****************kr"
},
"zoneId":"cn-shanghai-b"
}
]
},
"nextToken":"",
"pageNumber":1,
"pageSize":10,
"requestId":"C1468F7E********************7A3A712",
"totalCount":1
}
References
RAM is a service provided by Alibaba Cloud that manages user identities and access permissions to resources. For more information, see What is RAM?
For information about how RAM users can assume roles, see Assume a RAM role.
For information about role-based SSO, see Role-based SSO.