All Products
Search
Document Center

Resource Access Management:Use an STS token to access Alibaba Cloud

Last Updated:Apr 29, 2026

This topic describes a security pattern that allows a mobile app to use a temporary STS token obtained for a RAM role to access Alibaba Cloud resources directly.

Background

In this scenario, an enterprise develops a mobile app that must upload and download data directly to and from Object Storage Service (OSS). The app runs on end-user mobile devices, which are considered untrusted environments.

The solution must meet the following requirements:

  • Direct data transfer: To reduce latency and server load, the mobile app must communicate directly with OSS instead of proxying traffic through an application server.

  • Secure credential management: To mitigate security risks, long-term credentials, such as access keys, must not be embedded in the mobile app.

  • Risk control: To follow the principle of least privilege, each mobile app must be granted only the minimum permissions necessary to perform its tasks, and only for a limited time.

Solution

When a mobile app (App) connects directly to OSS to upload or download data, it requests credentials from an application server. The application server, acting as a RAM user, assumes a RAM role, calls the STS API AssumeRole operation to obtain an STS token, and passes the STS token to the app. The app uses the STS token to access OSS.

移动设备应用访问阿里云

  1. The app requests credentials from the application server.

  2. Use Alibaba Cloud account A to create a RAM role and grant appropriate permissions to the role.

    For more information, see Create a RAM role and grant permissions.

  3. Use Alibaba Cloud Account A to create a RAM user for the application server, and allow the application server to assume the RAM role as the RAM user.

  4. The application server calls the STS AssumeRole operation to obtain an STS token for the RAM role.

  5. An application server can further restrict the permissions of an STS token, providing more granular control over the permissions of each App.

    For more information, see Limiting the permissions of an STS token.

  6. When an app needs to directly connect to OSS to upload or download data, you can use an STS token to access OSS for direct data transfer.

Create a RAM role and grant permissions

Assume that the ID of the cloud account is 123456789012****.

  1. Use Alibaba Cloud account A to create a RAM role named oss-objectmanager with Cloud Account as the principal.

    Note

    When you create the RAM role, select Current Account as the trusted entity. This sets the role's trust policy to allow only principals within the same cloud account to assume the role.

    For more information, see Create a RAM role for a trusted Alibaba Cloud account.

    After the RAM role is created, you can view its ARN and trust policy on the role details page.

    • The ARN of the RAM role is acs:ram::123456789012****:role/oss-objectmanager.

    • The trust policy of the RAM role is as follows.

      Note

      This policy specifies that only RAM users under Alibaba Cloud account A can assume the RAM role.

      {
        "Statement": [
          {
            "Action": "sts:AssumeRole",
            "Effect": "Allow",
            "Principal": {
              "RAM": [
                "acs:ram::123456789012****:root"
              ]
            }
          }
        ],
        "Version": "1"
      }
  2. Grant permissions to the RAM role. For the RAM role oss-objectmanager, grant the management permission for OSS AliyunOSSFullAccess.

    For more information, see Grant permissions to a RAM role.

Create a RAM user and allow role assumption

  1. Use Alibaba Cloud Account A to create a RAM user named appserver for the application server.

    For more information, see Create a RAM user.

  2. Grant the AliyunSTSAssumeRoleAccess permission to the created RAM user. This allows the RAM user to assume a RAM role.

    For more information, see Grant permissions to a RAM user.

Obtain an STS token

  1. The application server uses a RAM user's AccessKey to call the STS AssumeRole API.

    Note
    • Before you use Alibaba Cloud CLI, you must install it on your application server and configure it with the RAM user's credentials. For more information, see STS CLI reference.

    • This example does not specify the Policy parameter. Therefore, the returned STS token has all the permissions of the oss-objectmanager RAM role. You can also further restrict the permissions of the STS token. For more information, see Limit the permissions of an STS token.

    The following is an example of calling AssumeRole by using the Alibaba Cloud CLI:

    aliyun sts AssumeRole --RoleArn 'acs:ram::123456789012****:role/oss-objectmanager' --RoleSessionName 'client-001'
  2. The STS service returns an STS token to the application server. The returned STS token contains AccessKeyId, AccessKeySecret, and SecurityToken.

    The following code provides a sample 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"
     }
    Note

    The SecurityToken expires after a specified period. If a mobile app requires access beyond the token's lifetime, it must request a new STS token from the application server before the current one expires.

Limit the permissions of an STS token

When you call AssumeRole, you can include the Policy parameter to pass an inline policy. This policy restricts the permissions of the returned STS token. The resulting permissions are the intersection of the role's permission policy and the inline policy.

The following example grants permission to download only the objects that match the prefix sample-bucket/2015/01/01/*.jpg.

  • Sample request

    aliyun sts AssumeRole --RoleArn 'acs:ram::123456789012****:role/oss-objectmanager' --RoleSessionName 'client-002' --Policy '{"Version":"1", "Statement": [{"Effect":"Allow", "Action":"oss:GetObject", "Resource":"acs:oss:*:*:sample-bucket/2015/01/01/*.jpg"}]}'
    Note

    By default, an STS token is valid for 3,600 seconds. You can use the DurationSeconds parameter to specify a different expiration time. For more information, see AssumeRole.

  • Sample response

    {
       "AssumedRoleUser": {
           "AssumedRoleId": "391578752573****:client-002",
           "Arn": "acs:ram::123456789012****:role/oss-objectmanager/client-002"
       },
       "Credentials": {
           "AccessKeySecret": "yourAccessKeySecret",
           "SecurityToken": "yourSecurityToken",
           "Expiration": "2016-01-13T15:03:39Z",
           "AccessKeyId": "yourAccessKeyId"
       }, 
       "RequestId": "98835D9B-86E5-4BB5-A6DF-9D3156ABA567"
    }

Use an STS token to access OSS

  1. The application server passes the STS token to the App.

  2. The app uses an STS token to access OSS.

    This example shows how to integrate the OSS SDK for Android into an Android app and use an STS token to download an object from OSS.

    // yourEndpoint: Your bucket's region endpoint. For example, for the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com.
    String endpoint = "yourEndpoint";
    // yourRegion: Your bucket's region ID. For example, for the China (Hangzhou) region, set the region ID to cn-hangzhou.
    String region = "yourRegion";
    
    // The temporary access key ID and access key secret obtained from STS.
    String accessKeyId = "yourAccessKeyId";
    String accessKeySecret = "yourAccessKeySecret";
    // The security token obtained from STS.
    String securityToken = "yourSecurityToken";
    
    OSSCredentialProvider credentialProvider = new OSSStsTokenCredentialProvider(accessKeyId, accessKeySecret, securityToken);
    ClientConfiguration config = new ClientConfiguration();
    config.setSignVersion(SignVersion.V4);
    // Create an OSSClient instance.
    OSSClient oss = new OSSClient(getApplicationContext(), endpoint, credentialProvider);
    oss.setRegion(region);
    // Construct a request to download the object.
    GetObjectRequest get = new GetObjectRequest("sample-bucket", "2015/01/01/grass.jpg");
    
    OSSAsyncTask task = oss.asyncGetObject(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
        @Override
         // This callback is invoked when the GetObject request is successful.
         // The GetObjectResult object contains an input stream that you must process.
        public void onSuccess(GetObjectRequest request, GetObjectResult result) {
            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 that is read from the stream.
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        // This callback is invoked when the GetObject request fails. Handle the exception.
        public void onFailure(GetObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
            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();