This tutorial describes how to securely grant a mobile application temporary, limited-privilege access to your Alibaba Cloud resources. This is achieved by using the Security Token Service (STS) to vend short-term credentials, which avoids the high-risk practice of embedding long-term AccessKey pairs in your application.
Scenario
Imagine you are developing a mobile application that needs to upload photos and download videos directly to and from a bucket in Object Storage Service (OSS). To provide a good user experience, the app must interact directly with OSS. However, because the app runs on end-user devices, it is considered an untrusted environment.
The solution must meet the following security requirements:
No hard-coded credentials: The application binary must not contain any long-term AccessKey pairs.
Least privilege: Each application user should only have the permissions necessary to perform their tasks (such as accessing only their own objects in a bucket).
Time-limited access: The credentials should expire automatically after a short period to limit the impact of a potential compromise.
Solution overview
This scenario is a classic use case for the token vending machine (TVM) pattern. In this pattern, you create a trusted backend application server that "vends" temporary credentials to your mobile app. The mobile app never holds long-term credentials.
The workflow is as follows:

The mobile app authenticates with your application server using its own logon mechanism (such as username/password or a third-party social logon).
After successful authentication, your application server, which has its own secure long-term credentials, calls the AssumeRole operation.
STS validates the request and returns a set of temporary credentials (an AccessKey ID, an AccessKey secret, and a security token).
Your application server sends these temporary credentials back to the mobile app.
The mobile app uses the temporary credentials to log on and send requests directly to the authorized Alibaba Cloud service (in this case, OSS).
Prerequisites
You have an Alibaba Cloud account with administrator permissions to manage RAM.
You have an application server (the TVM) where you can securely run backend code.
You have the Alibaba Cloud CLI or an appropriate SDK installed on your application server.
Step 1: Create a RAM role and a RAM user for your application server
First, you need to create the necessary RAM identities: a role that defines the permissions for your mobile app, and a user that represents your application server.
Create a RAM role:
In the RAM console, navigate to and click Create Role.
For Principal Type, select Cloud Account.
For Principal Name, select Current Account. This creates a trust policy allowing identities from within your own account to assume this role.
Click OK. In the Create Role dialog box, enter a RAM Role Name (such as
MobileApp-OSS-Access-Role) and attach a policy (such as theAliyunOSSFullAccesssystem policy). In a production environment, you should use a custom policy with more restrictive permissions.Click OK. Note the ARN of the role you just created (such as
acs:ram::123456789012:role/MobileApp-OSS-Access-Role).
For more information, see Create a RAM role for a trusted Alibaba Cloud account and Manage a RAM role's permissions.
Create a RAM user for the application server:
In the RAM console, navigate to and click Create User.
Create a user (such as
app-server-user) and be sure to select Permanent AccessKey to generate an AccessKey pair. Securely save these credentials.Find the
app-server-userand attach theAliyunSTSAssumeRoleAccesssystem policy to it. This grants the user permission to call theAssumeRoleoperation.
For more information, see Create a RAM user and Grant permissions to a RAM user.
Step 2: Implement the token vending logic on the application server
Your application server code will use the credentials of the app-server-user to call the AssumeRole operation and obtain an STS token.
Configure your application server with the AccessKey ID and secret of the
app-server-user. Use a secure method such as environment variables or a secrets management service.In your server's logic (such as in an API endpoint that the mobile app calls after logon), call the
AssumeRoleoperation. You must provide the ARN of the role you want to assume and a unique session name.Example using the Alibaba Cloud CLI:
aliyun sts AssumeRole --RoleArn 'acs:ram::123456789012****:role/oss-objectmanager' --RoleSessionName 'client-001'STS will return a JSON object containing the temporary credentials.
Example response:
{ "AssumedRoleUser": { "AssumedRoleId": "391578752573****:client-001", "Arn": "acs:ram::123456789012****:role/oss-objectmanager/client-001" }, "Credentials": { "AccessKeySecret": "yourAccessKeySecret", "SecurityToken": "yourSecurityToken", "Expiration": "2016-01-13T15:02:37Z", "AccessKeyId": "yourAccessKeyId" }, "RequestId": "E1779AAB-E7AF-47D6-A9A4-53128708B6CE" }Your application server should then send the
Credentialsobject back to the authenticated mobile app client.
Advanced: Scope down permissions with session policies
For even greater security, you can dynamically generate a policy that further restricts the permissions of the STS token for each session. The final permissions of the token will be the intersection of the role's permission policy and the session policy you provide.
For example, to grant a specific user access only to their own objects within a bucket, you can pass a session policy in the AssumeRole call.
aliyun sts AssumeRole \
--RoleArn 'acs:ram::123456789012****:role/oss-objectmanager' \
--RoleSessionName 'client-002' \
--Policy '{"Version":"1", "Statement": [{"Effect":"Allow", "Action":["oss:GetObject", "oss:PutObject"], "Resource":"acs:oss:*:*:my-app-bucket/users/user-123/*"}]}'The resulting STS token will only allow GetObject and PutObject actions within the users/user-123/ prefix of the my-app-bucket bucket, even though the role itself has full OSS access.
Step 3: Use the STS token in the mobile app to access OSS
Once the mobile app receives the temporary credentials from your application server, it can use them to initialize the OSS SDK and make authenticated requests.
The following example shows how to use an STS token with the OSS SDK for Android to download an object.
// Set yourEndpoint to the endpoint of the region where the bucket is located.
// For example, for China East 1 (Hangzhou), set the endpoint to https://oss-cn-hangzhou.aliyuncs.com.
String endpoint = "yourEndpoint";
// Set yourRegion to the region where the bucket is located.
// For example, for China East 1 (Hangzhou), set the region to cn-hangzhou.
String region = "yourRegion";
// The credentials received from your application server.
String accessKeyId = "yourAccessKeyId";
String accessKeySecret = "yourAccessKeySecret";
String securityToken = "yourSecurityToken";
// Initialize the STS credential provider.
OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider(accessKeyId, accessKeySecret, securityToken);
ClientConfiguration config = new ClientConfiguration();
config.setSignVersion(SignVersion.V4);
// Create the OSSClient instance.
OSSClient oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider);
oss.setRegion(region);
// Prepare the request to download an object.
GetObjectRequest get = new GetObjectRequest("sample-bucket", "2015/01/01/grass.jpg");
OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
@Override
public void onSuccess(GetObjectRequest request, GetObjectResult result) {
// Request successful.
Log.d("asyncGetObject", "DownloadSuccess");
Log.d("Content-Length", "" + result.getContentLength());
try (InputStream inputStream = result.getObjectContent()) {
byte[] buffer = new byte[2048];
int len;
while ((len = inputStream.read(buffer)) != -1) {
// Process the data.
}
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
// When a GetObject request is successful, it returns a GetObjectResult.
// The GetObjectResult contains an InputStream instance, which you must handle.
public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
// Handle failures.
if (clientExcepion != null) {
// Client-side exception, such as a network error.
clientExcepion.printStackTrace();
}
if (serviceException != null) {
// Server-side exception.
Log.e("ErrorCode", serviceException.getErrorCode());
Log.e("RequestId", serviceException.getRequestId());
Log.e("HostId", serviceException.getHostId());
Log.e("RawMessage", serviceException.getRawMessage());
}
}
});
// Cancel the task.
// task.cancel();
// Wait for the task to complete.
// task.waitUntilFinished(); STS tokens expire. Your mobile application must include logic to detect when a token is about to expire and request a new one from your application server to ensure uninterrupted access.