The Alibaba Cloud SDK uses the Credentials tool to centrally manage credentials, such as your AccessKey and STS Token. This topic describes the supported credential types and their configuration methods.
Prerequisites
-
The Credentials tool requires Java 8 or later. For more information, see Alibaba Cloud SDK Maintenance Policy.
-
For the V2.0 Alibaba Cloud SDK, see V2.0 SDK and V1.0 SDK.
Install Credentials
Use the latest Credentials dependency package to access all features.
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>credentials-java</artifactId>
<version>latest-version</version>
</dependency>
<!-- If you use credentials-java alone, you must also include the Tea dependency package. -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>tea</artifactId>
<version>latest-version</version>
</dependency>
For the latest version of the Credentials dependency package, see GitHub or Maven Repository. For the latest version of the Tea dependency package, see GitHub or Maven Repository.
Credential types and parameters
The com.aliyun.credentials.models.Config class defines the credential types and configuration parameters that the Credentials tool supports. The type parameter specifies the credential type, and different types require different configuration parameters. This table describes the valid values for type and their supported parameters. In the table, indicates a mandatory parameter, - indicates an optional parameter, and indicates that the parameter is unsupported.
Credential types and parameters not listed in this table are deprecated.
|
Parameter |
|||||||
|
accessKeyId: The access key ID. |
|
|
|
|
|
|
|
|
accessKeySecret: The secret access key. |
|
|
|
|
|
|
|
|
securityToken: The security token. |
|
|
- |
|
|
|
|
|
roleArn: The ARN of the RAM role. |
|
|
|
|
|
|
|
|
roleSessionName: A custom session name. The default format is |
|
|
- |
|
- |
|
|
|
roleName: The name of the RAM role. |
|
|
|
- |
|
|
|
|
disableIMDSv1: Specifies whether to use the enhanced security mode. The default value is |
|
|
|
- |
|
|
|
|
bearerToken: The bearer token. |
|
|
|
|
|
|
|
|
policy: The custom permission policy. |
|
|
- |
|
- |
|
|
|
roleSessionExpiration: The session expiration time in seconds. The default value is 3,600. The value must be between 900 and the maximum session duration of the RAM role. |
|
|
- |
|
- |
|
|
|
oidcProviderArn: The ARN of the OIDC identity provider. |
|
|
|
|
|
|
|
|
oidcTokenFilePath: The file path to the OIDC token. |
|
|
|
|
|
|
|
|
externalId: The external ID for the RAM role. This parameter helps prevent the confused deputy problem. For more information, see Use an external ID to prevent the confused deputy problem. |
|
|
- |
|
|
|
|
|
credentialsURI: The URI of the external credential. |
|
|
|
|
|
|
|
|
STSEndpoint: The service endpoint for Security Token Service (STS). This parameter supports VPC endpoints and public endpoints. For a list of possible values, see Service endpoints. The default value is |
|
|
- |
|
- |
|
|
|
timeout: The read timeout in milliseconds. The default value is 5,000. |
|
|
- |
- |
- |
- |
|
|
connectTimeout: The connection timeout in milliseconds. The default value is 10,000. |
|
|
- |
- |
- |
- |
|
Using the Credentials tool
The previous section describes the credential types and configuration parameters supported by the Credentials tool. The following sections provide code examples showing how to use the tool. Select the method that best fits your scenario.
-
Hard-coding an AccessKey in your project creates security risks. Improperly managed repository permissions can expose all resources in your account. It is recommended to store the AccessKey in environment variables or configuration files.
-
Use a singleton pattern with the Credentials tool. This pattern enables the tool's built-in credential caching to prevent rate limiting from frequent API calls and avoid resource waste from creating multiple instances. For more information, see Automatic refresh of session credentials.
Method 1: Default credential chain
This is the default method used in the sample code on the OpenAPI Portal.
If you do not pass any configuration parameters when initializing the Credentials tool, it retrieves credentials from the default credential chain. To use this method, ensure that your application's runtime environment is configured with at least one of the credential retrieval methods supported by the default credential chain.
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
// If no configuration parameters are specified, the tool retrieves credentials from the default credential chain.
Client credentialClient = new Client();
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// If you are using a cloud product V2.0 SDK, use com.aliyun.teaopenapi.models.Config to pass the credential.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// The code for initializing the cloud product client with the config object is omitted.
}
}
Method 2: AK
The Credentials tool uses the AccessKey you provide as the access credential.
An Alibaba Cloud account (root account) has full permissions over all its resources, so an exposed AK poses a significant security risk. Do not use the AK of a root account.
Use the AK of a RAM user with least-privilege permissions.
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("access_key");
// Required. This example retrieves the AccessKey ID from an environment variable.
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// Required. This example retrieves the AccessKey secret from an environment variable.
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// If you are using a cloud product V2.0 SDK, use com.aliyun.teaopenapi.models.Config to pass the credential.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// The code for initializing the cloud product client with the config object is omitted.
}
}
Method 3: STS token
The Credentials tool uses the static STS token you provide as the access credential.
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) {
Config credentialConfig = new Config();
credentialConfig.setType("sts");
// Required. This example retrieves the AccessKey ID from an environment variable.
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// Required. This example retrieves the AccessKey secret from an environment variable.
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// Required. This example retrieves the temporary security token from an environment variable.
credentialConfig.setSecurityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN"));
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// If you are using a cloud product V2.0 SDK, use com.aliyun.teaopenapi.models.Config to pass the credential.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// The code for initializing the cloud product client with the config object is omitted.
}
}
Method 4: AK and RAM role ARN
The Credentials tool uses your AK and RAM role ARN to call the AssumeRole API and obtain an STS token, which serves as the access credential. Credentials obtained this way support automatic refresh. For more information, see Automatic refresh of session credentials.
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("ram_role_arn");
// Required. This example retrieves the AccessKey ID from an environment variable.
credentialConfig.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
// Required. This example retrieves the AccessKey secret from an environment variable.
credentialConfig.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// Optional. Allows the use of temporary credentials to assume another RAM role.
credentialConfig.setSecurityToken(System.getenv("ALIBABA_CLOUD_SECURITY_TOKEN"));
// Required. The ARN of the RAM role to assume. Example: acs:ram::123456789012****:role/adminrole. You can also set this by using the ALIBABA_CLOUD_ROLE_ARN environment variable.
credentialConfig.setRoleArn("<RoleArn>");
// Optional. The role session name. Default format: credentials-java-. You can also set this by using the ALIBABA_CLOUD_ROLE_SESSION_NAME environment variable.
credentialConfig.setRoleSessionName("<RoleSessionName>");
// Optional. A more restrictive permission policy. Not required. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}.
credentialConfig.setPolicy("<Policy>");
// Optional. An external ID to prevent the confused deputy problem.
credentialConfig.setExternalId("<ExternalId>");
// Optional. The session expiration time in seconds. Default value: 3600.
credentialConfig.setRoleSessionExpiration(3600);
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// If you are using a cloud product V2.0 SDK, use com.aliyun.teaopenapi.models.Config to pass the credential.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// The code for initializing the cloud product client with the config object is omitted.
}
}
Method 5: ECS instance RAM role
If your application runs on an Elastic Compute Service (ECS) or Elastic Container Instance (ECI) instance with an assigned RAM role, the Credentials tool retrieves an STS token from the instance metadata to use as the access credential. When accessing instance metadata, the tool first retrieves the name of the RAM role assigned to the instance. You can specify the RAM role name by using the roleName parameter or the ALIBABA_CLOUD_ECS_METADATA environment variable to reduce retrieval time and improve efficiency. Credentials obtained this way support automatic refresh. For more information, see Automatic refresh of session credentials.
By default, the Credentials tool accesses instance metadata in secured mode (IMDSv2). If this access fails, use the disableIMDSv1 parameter or the ALIBABA_CLOUD_IMDSV1_DISABLED environment variable to control the fallback behavior:
-
If set to
false(default), the tool falls back to normal mode to retrieve the credential. -
If set to
true, the tool only uses secured mode and throws an exception if access fails.
Whether your server supports IMDSv2 depends on its configuration.
To disable credential access from instance metadata, set the ALIBABA_CLOUD_ECS_METADATA_DISABLED=true environment variable.
-
For more information about instance metadata, see Instance metadata.
-
To learn how to grant a RAM role to an ECS or ECI instance, see Step 1: Create a RAM role and Grant an instance RAM role to an ECI instance.
-
You need credentials-java version 0.3.10 or later to obtain temporary credentials in secured mode.
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("ecs_ram_role");
// Optional. The name of the RAM role granted to the ECS instance. If not specified, the tool retrieves it automatically. We recommend setting this parameter to reduce the number of requests. You can also set this by using the ALIBABA_CLOUD_ECS_METADATA environment variable.
credentialConfig.setRoleName("<RoleName>");
// Optional. Set to true to enforce secured mode. Default value: false. The tool first attempts to get credentials in secured mode. If it fails, it falls back to normal mode.
credentialConfig.setDisableIMDSv1(false);
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// If you are using a cloud product V2.0 SDK, use com.aliyun.teaopenapi.models.Config to pass the credential.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// The code for initializing the cloud product client with the config object is omitted.
}
}
Method 6: OIDC role ARN
If you use OIDC for authentication and have created a RAM role for an OIDC identity provider, you can provide the OIDC provider ARN, OIDC token file path, and RAM role ARN to the Credentials tool. The tool then automatically calls the AssumeRoleWithOIDC API to obtain an STS token for the RAM role, which is used as the access credential. Credentials obtained this way support automatic refresh. For more information, see Automatic refresh of session credentials. For example, if your application runs in a Container Service for Kubernetes (ACK) cluster with RRSA enabled, the Credentials tool can read the OIDC configuration from the pod's environment variables and call the AssumeRoleWithOIDC API to obtain an STS token. You can then use this STS token to access Alibaba Cloud services.
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("oidc_role_arn");
// Required. The RAM role ARN. You can also set this by using the ALIBABA_CLOUD_ROLE_ARN environment variable.
credentialConfig.setRoleArn("<RoleArn>");
// Required. The ARN of the OIDC identity provider. You can also set this by using the ALIBABA_CLOUD_OIDC_PROVIDER_ARN environment variable.
credentialConfig.setOidcProviderArn("<OidcProviderArn>");
// Required. The OIDC token file path. You can also set this by using the ALIBABA_CLOUD_OIDC_TOKEN_FILE environment variable.
credentialConfig.setOidcTokenFilePath("<OidcTokenFilePath>");
// Optional. The role session name. You can also set this by using the ALIBABA_CLOUD_ROLE_SESSION_NAME environment variable.
credentialConfig.setRoleSessionName("<RoleSessionName>");
// Optional. A more restrictive permission policy. Not required. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
credentialConfig.setPolicy("<Policy>");
// Optional. The session expiration time in seconds. Default value: 3600.
credentialConfig.setRoleSessionExpiration(3600);
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// If you are using a cloud product V2.0 SDK, use com.aliyun.teaopenapi.models.Config to pass the credential.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// The code for initializing the cloud product client with the config object is omitted.
}
}
Method 7: Credentials URI
You can encapsulate the Security Token Service (STS) behind a service URI, allowing external services to obtain an STS token without exposing sensitive information like AKs. The Credentials tool can then use this URI to fetch an STS token to use as the access credential. Credentials obtained this way support automatic refresh. For more information, see Automatic refresh of session credentials.
The URI must meet the following conditions:
-
Supports GET requests.
-
Returns an HTTP 2xx status code.
-
The response body must return a JSON object with the following structure:
{ "Code": "Success", "AccessKeySecret": "yourAccessKeySecret", "AccessKeyId": "STS.****************", "Expiration": "2021-09-26T03:46:38Z", "SecurityToken": "yourSecurityToken" }
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("credentials_uri");
// Required. The URI for retrieving external credentials. Format: http://local_or_remote_uri/. You can also set this by using the ALIBABA_CLOUD_CREDENTIALS_URI environment variable.
credentialConfig.setCredentialsUri("<CredentialsUri>");
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// If you are using a cloud product V2.0 SDK, use com.aliyun.teaopenapi.models.Config to pass the credential.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// The code for initializing the cloud product client with the config object is omitted.
}
}
Method 8: Bearer token
Currently, only Alibaba Cloud Call Center (CCC) supports bearer token authentication.
import com.aliyun.credentials.Client;
import com.aliyun.credentials.models.Config;
import com.aliyun.credentials.models.CredentialModel;
public class DemoTest {
public static void main(String[] args) throws Exception {
Config credentialConfig = new Config();
credentialConfig.setType("bearer");
// Required. Enter your bearer token.
credentialConfig.setBearerToken("<BearerToken>");
Client credentialClient = new Client(credentialConfig);
CredentialModel credential = credentialClient.getCredential();
String accessKeyId = credential.getAccessKeyId();
String accessKeySecret = credential.getAccessKeySecret();
String securityToken = credential.getSecurityToken();
// If you are using the CCC V2.0 SDK, use com.aliyun.teaopenapi.models.Config to pass the credential.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
config.setCredential(credentialClient);
config.setEndpoint("<Endpoint>");
// The code for initializing the cloud product client with the config object is omitted.
}
}
Default credential provider chain
The default credential provider chain is a fallback mechanism that searches for a credential by checking a predefined sequence of locations. The search continues until a credential is found. If no credential is found after checking all locations, a CredentialException is thrown. The search order is as follows:
1. System properties
The provider chain first checks for a credential in Java system properties.
-
If the alibabacloud.accessKeyId and alibabacloud.accessKeySecret system properties are defined, the provider chain uses an AccessKey as the default credential.
-
If the alibabacloud.accessKeyId, alibabacloud.accessKeySecret, and alibabacloud.sessionToken system properties are defined, the provider chain uses an STS token as the default credential.
You can specify these values by adding the following JVM parameters when you run your Java program:
-Dalibabacloud.accessKeyId=your-access-key-id -Dalibabacloud.accessKeySecret=your-access-key-secret
2. Environment variables
If no credential is found in the system properties, the provider chain then checks for environment variables.
-
If both ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET are present and not empty, the provider chain uses them as the default credential.
-
If ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, and ALIBABA_CLOUD_SECURITY_TOKEN are also set, the provider chain uses an STS token as the default credential.
3. OIDC RAM role
If no credential has been found, the provider chain checks for the following environment variables related to an OIDC RAM role:
-
ALIBABA_CLOUD_ROLE_ARN: The ARN of the RAM role.
-
ALIBABA_CLOUD_OIDC_PROVIDER_ARN: The ARN of the OIDC provider.
-
ALIBABA_CLOUD_OIDC_TOKEN_FILE: The file path of the OIDC token.
If all three environment variables are present and not empty, the provider chain uses these values to call the AssumeRoleWithOIDC API of the Security Token Service (STS) to obtain an STS token.
4. Shared credentials file
This feature requires credentials-java version 0.3.8 or later.
If no credential has been found, the provider chain attempts to load the shared credentials file, config.json, from its default location and uses the credential specified in the file.
-
Linux/macOS:
~/.aliyun/config.json -
Windows:
C:\Users\USER_NAME\.aliyun\config.json
To configure a credential this way, you can use the Alibaba Cloud CLI or manually create a config.json file in the appropriate path. The following example shows the content format:
{
"current": "<PROFILE_NAME>",
"profiles": [
{
"name": "<PROFILE_NAME>",
"mode": "AK",
"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>"
},
{
"name": "<PROFILE_NAME1>",
"mode": "StsToken",
"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
"sts_token": "<SECURITY_TOKEN>"
},
{
"name":"<PROFILE_NAME2>",
"mode":"RamRoleArn",
"access_key_id":"<ALIBABA_CLOUD_ACCESS_KEY_ID>",
"access_key_secret":"<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
"ram_role_arn":"<ROLE_ARN>",
"ram_session_name":"<ROLE_SESSION_NAME>",
"expired_seconds":3600
},
{
"name":"<PROFILE_NAME3>",
"mode":"EcsRamRole",
"ram_role_name":"<RAM_ROLE_ARN>"
},
{
"name":"<PROFILE_NAME4>",
"mode":"OIDC",
"oidc_provider_arn":"<OIDC_PROVIDER_ARN>",
"oidc_token_file":"<OIDC_TOKEN_FILE>",
"ram_role_arn":"<ROLE_ARN>",
"ram_session_name":"<ROLE_SESSION_NAME>",
"expired_seconds":3600
},
{
"name":"<PROFILE_NAME5>",
"mode":"ChainableRamRoleArn",
"source_profile":"<PROFILE_NAME>",
"ram_role_arn":"<ROLE_ARN>",
"ram_session_name":"<ROLE_SESSION_NAME>",
"expired_seconds":3600
}
]
}
|
Parameter |
Description |
|
current |
Specify the credential name to retrieve the corresponding credential configuration. The credential name is the value of the |
|
profiles |
Contains a collection of credential configurations. The
|
5. Instance RAM role
If no credential has been found, the provider chain attempts to retrieve an STS token for the instance RAM role from the instance metadata. This token is then used as the default credential. To do this, the chain first retrieves the name of the RAM role assigned to the instance and then uses that role to obtain the corresponding STS token. To reduce credential retrieval time and improve efficiency, you can specify the RAM role name directly by using the ALIBABA_CLOUD_ECS_METADATA environment variable.
By default, the provider chain accesses instance metadata in security-hardened mode (IMDSv2). If an exception occurs in security-hardened mode, you can use the ALIBABA_CLOUD_IMDSV1_DISABLED environment variable to control the fallback behavior:
-
When the value is
false(default), the system attempts to switch to legacy mode to retrieve the credential. -
When the value is
true, security-hardened mode is enforced. If access fails in this mode, an exception is thrown.
Additionally, you can prevent the provider chain from accessing instance metadata for credentials by setting the ALIBABA_CLOUD_ECS_METADATA_DISABLED=true environment variable.
-
For more information about instance metadata, see Instance metadata.
-
To learn how to grant a RAM role to an ECS or ECI instance, see Step 1: Create a RAM role and Grant an instance RAM role to an ECI instance.
-
To obtain a temporary credential in security-hardened mode, you must use
credentials-javaversion 0.3.10 or later.
6. CredentialsURI
If no credential has been found, the provider chain checks for the ALIBABA_CLOUD_CREDENTIALS_URI environment variable. If this variable is set and points to a valid URI, the chain accesses the URI to retrieve an STS token.
Session credential auto-refresh
Session credential types, such as ram_role_arn, ecs_ram_role, oidc_role_arn, and credentials_uri, support automatic refresh through a built-in mechanism in the credential provider. When a credential client retrieves a credential for the first time, the provider stores it in a cache. In subsequent operations, the same client instance automatically retrieves the credential from this cache. If the cached credential has expired, the client instance fetches a new one and updates the cache accordingly.
For ecs_ram_role credentials, the credential provider proactively refreshes them 15 minutes before they expire.
The following example uses the singleton pattern to create a credential client. It demonstrates the refresh mechanism by fetching a credential at different time intervals and calling an OpenAPI operation to verify that the credential is usable.
import com.aliyun.credentials.models.CredentialModel;
import com.aliyun.ecs20140526.Client;
import com.aliyun.ecs20140526.models.DescribeRegionsRequest;
import com.aliyun.ecs20140526.models.DescribeRegionsResponse;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import java.util.Date;
import java.util.concurrent.*;
public class Sample {
/**
* The Credential class uses the singleton pattern to manage the Alibaba Cloud credential client instance.
*/
private static class Credential {
private static volatile com.aliyun.credentials.Client instance;
private Credential() {
}
public static com.aliyun.credentials.Client getInstance() {
if (instance == null) {
synchronized (Credential.class) {
if (instance == null) {
try {
com.aliyun.credentials.models.Config config = new com.aliyun.credentials.models.Config();
config.setType("ram_role_arn");
config.setAccessKeyId(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
config.setAccessKeySecret(System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
config.setRoleArn(System.getenv("ALIBABA_CLOUD_ROLE_ARN"));
config.setRoleSessionName("RamRoleArnTest");
config.setRoleSessionExpiration(3600);
instance = new com.aliyun.credentials.Client(config);
} catch (Exception e) {
throw new RuntimeException("Credential initialization failed: " + e.getMessage(), e);
}
}
}
}
return instance;
}
}
/**
* The EcsClient class uses the singleton pattern to manage the ECS client.
*/
private static class EcsClient {
private static volatile Client instance;
private EcsClient() {
}
public static Client getInstance(com.aliyun.credentials.Client credentialClient) {
if (instance == null) {
synchronized (EcsClient.class) {
if (instance == null) {
try {
Config ecsConfig = new Config();
ecsConfig.setEndpoint("ecs.cn-hangzhou.aliyuncs.com");
ecsConfig.setCredential(credentialClient);
instance = new Client(ecsConfig);
} catch (Exception e) {
throw new RuntimeException("ECS client initialization failed: " + e.getMessage(), e);
}
}
}
}
return instance;
}
}
public static void main(String[] args) {
// Initializes a scheduled thread pool.
ScheduledThreadPoolExecutor scheduler = new ScheduledThreadPoolExecutor(
1,
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
scheduler.setKeepAliveTime(0L, TimeUnit.SECONDS);
scheduler.allowCoreThreadTimeOut(false); // Do not allow core threads to time out.
// Defines the execution logic as a Runnable task.
Runnable task = () -> {
try {
com.aliyun.credentials.Client credentialClient = Credential.getInstance();
CredentialModel credential = credentialClient.getCredential();
System.out.println(new Date());
System.out.printf("AK ID:%s, AK Secret:%s, STS Token:%s%n", credential.accessKeyId, credential.accessKeySecret, credential.securityToken);
// This example calls an ECS operation to verify that the credential is usable. You can adapt this for your use case.
Client ecsClient = EcsClient.getInstance(credentialClient);
DescribeRegionsRequest request = new DescribeRegionsRequest();
RuntimeOptions runtime = new RuntimeOptions();
DescribeRegionsResponse response = ecsClient.describeRegionsWithOptions(request, runtime);
System.out.printf("Invoke result:%s%n", response.statusCode);
} catch (Exception e) {
throw new RuntimeException("ECS client execution failed: " + e.getMessage(), e);
}
};
try {
// Run the task for the first time (immediately).
scheduler.execute(task);
// Schedule the second task to run after a 600-second delay.
scheduler.schedule(task, 600, TimeUnit.SECONDS);
// Schedule the third task to run after 4,200 seconds.
scheduler.schedule(task, 4200, TimeUnit.SECONDS);
// Schedule the fourth task to run after 4,300 seconds.
scheduler.schedule(task, 4300, TimeUnit.SECONDS);
} finally {
// Shut down the thread pool after all tasks complete.
scheduler.shutdown();
try {
if (!scheduler.awaitTermination(4500, TimeUnit.SECONDS)) {
scheduler.shutdownNow();
}
} catch (InterruptedException e) {
scheduler.shutdownNow();
Thread.currentThread().interrupt();
}
}
}
}
Wed May 28 13:33:43 CST 2025
AK ID:STS.NWWcxxx2xbcw, AK Secret:5p3FMoRjxxx7KPm9k5mNf89, STS
Token:CAISxAJ1q6Ft5B2yfSJIr5TiJI7/vapF1IaoR6vcqFAsebcel6fIlTz2IHhMeXZoA+4YsPw2mmFW6/sdlqdJQpp
/QkjJRNF20plM7VtLjwYFIpbng4YfgbiJREKxaXeiruKwDsz9SNTCAITxxxFly6Ee4CFdkf3jm5bHu0WB0qCkk7FO/trLT8L6P5U2DvBWSMyo2eF6TK3F3RNL5gJCnKUM1/QcpGif5I
/DXQEIvUTYbreL6L9mNxRkY6UgHKpJvCxxBmi0fUW5fe3VvPUtVYk900xxxX9IIPPt3pm4K8Qdpz0agAEZc36x
/FgKbLSDQh4DZiv0gPracQVKbiHF7snw5rRXtu4PJHyGSOZfR8a3H7sxxxp0GR7TbZwX48kHARr95UXTTVi0bn+kS6UfjCJASAA
Invoke result:200
Wed May 28 13:43:39 CST 2025
AK ID:STS.NWWcxxx2xbcw, AK Secret:5p3FMoRjxxx7KPm9k5mNf89, STS
Token:CAISxAJ1q6Ft5B2yfSJIr5TiJI7/vapF1IaoR6vcqFAsebcel6fIlTz2IHhMeXZoA+4YsPw2mmFW6/sdlqdJQpp
/QkjJRNF20plM7VtLjwYFIpbng4YfgbiJREKxaXeiruKwDsz9SNTCAIxxxFly6Ee4CFdkf3jm5bHu0WB0qCkk7FO/trLT8L6P5U2DvBWSMyo2eF6TK3F3RNL5gJCnKUM1/QcpGif5I
/DXQEIvUTYbreL6L9mNxRkY6UgHKpJvCxxBmi0fUW5fe3VvPUtVYk900xxxX9IIPPt3pm4K8Qdpz0agAEZc36x
/FgKbLSDQh4DZiv0gPracQVKbiHF7snw5rRXtu4PJHyGSOZfR8a3H7sxxxp0GR7TbZwX48kHARr95UXTTVi0bn+kS6UfjCJASAA
Invoke result:200
Wed May 28 14:43:40 CST 2025
AK ID:STS.NXF5xxxbMWQ9b, AK Secret:8sLqjJ39PyxxxG65t6onfid7, STS
Token:CAISxAJ1q6Ft5B2yfSJIr5vzfovNrLLVwpinMHSDkmoQQu1huJSSgDz2IHhMeXZoA+4YsPw2mmFW6/sdlqdJQpp
/QkjJRNF20plM7VsbkQYHIpbng4YfgbiJREKxaXeiruKwDsz9SNTCAIxxxFly6Ee4CFdkf3jm5bHu0WB0qCkk7FO/trLT8L6P5U2DvBWSMyo2eF6TK3F3RNL5gJCnKUM1/QcpGif5I
/DXQEIvUTYbreL6L9mNxRkY6UgHKpJvCxxBmi0fUW5fe3VvPUtVYk900xxxE7NJKbtm6l6aMQdpz0agAFkyTyo8rjEFLKPKG6DdLq7fkrBDqe7PtCiBD
+dZVf1xhPof9i8DluMHBXNp6m13SbpKR5ROYta43jKyzqQaiI3oE64kxxxBbHAti3yAA
Invoke result:200
Wed May 28 14:45:19 CST 2025
AK ID:STS.NXF5xxxbMWQ9b, AK Secret:8sLqjJ39PyxxxG65t6onfid7, STS
Token:CAISxAJ1q6Ft5B2yfSJIr5vzfovNrLLVwpinMHSDkmoQQu1huJSSgDz2IHhMeXZoA+4YsPw2mmFW6/sdlqdJQpp
/QkjJRNF20plM7VsbkQYHIpbng4YfgbiJREKxaXeiruKwDsz9SNTCAIxxxFly6Ee4CFdkf3jm5bHu0WB0qCkk7FO/trLT8L6P5U2DvBWSMyo2eF6TK3F3RNL5gJCnKUM1/QcpGif5I
/DXQEIvUTYbreL6L9mNxRkY6UgHKpJvCxxBmi0fUW5fe3VvPUtVYk900xxxE7NJKbtm6l6aMQdpz0agAFkyTyo8rjEFLKPKG6DdLq7fkrBDqe7PtCiBD
+dZVf1xhPof9i8DluMHBXNp6m13SbpKR5ROYta43jKyzqQaiI3oE64kxxxBbHAti3yAA
Invoke result:200
Analysis based on the log output:
-
On the first call, the cache is empty. The system retrieves a credential based on your configuration and then stores it in the cache.
-
The second call uses the same credential as the first, indicating it was retrieved from the cache.
-
On the third call, the cached credential has expired. Its expiration time (
RoleSessionExpiration) is 3,600 seconds, but this call is made 4,200 seconds after the first one. Consequently, the SDK's automatic refresh mechanism fetches a new credential and updates the cache. -
The fourth call uses the same credential as the third, confirming that the cache was updated.
Related documents
-
For an overview of the basic concepts of RAM, see Basic concepts.
-
To create an AccessKey, see Create an AccessKey.
-
To programmatically create RAM users, AccessKeys, and RAM roles; define permission policies; and grant permissions, see RAM SDK overview.
-
To programmatically assume a role, see STS SDK overview.
-
For details about the RAM and STS APIs, see the API reference.
-
Best practices for using access credentials to call Alibaba Cloud OpenAPI