When you call API operations to manage cloud resources using Alibaba Cloud SDKs, you must configure valid credential information. The Credentials tool of Alibaba Cloud provides a set of easy-to-use features and supports various types of credentials, including the default credential, AccessKey pairs, and Security Token Service (STS) tokens. The Credentials tool helps you obtain and manage credentials. This topic describes how to configure different types of credentials and the order based on which the Credentials tool obtains the default credential. You can develop a thorough knowledge of configuring and managing credentials in Alibaba Cloud SDKs. This ensures that you can perform operations on cloud resources in an efficient and secure manner.
Background information
A credential is a set of information that a user uses to prove their identity. When a user logs on to a system, they must provide the correct credentials for identity verification. Common credential types include the following:
A permanent AccessKey (AK) of an Alibaba Cloud account or a Resource Access Management (RAM) user. An AccessKey is a key pair that consists of an AccessKey ID and an AccessKey secret.
A temporary STS token of an Alibaba Cloud RAM role. It is a temporary identity credential with custom validity periods and access permissions. For more information, see What is STS?.
A Bearer Token. It is a token type for identity verification and authorization.
Prerequisites
Go version 1.10.x or later is required to use the Credentials tool.
Alibaba Cloud SDK for Go V2 is required. For more information, see Use Alibaba Cloud SDK for Go in an IDE.
Install the Credentials tool
You can use
go getto download and install the tool.$ go get -u github.com/aliyun/credentials-goIf you use
depto manage dependency packages, run the following command.dep ensure -add github.com/aliyun/credentials-go
Use the latest version of the Credentials dependency package to ensure that all credential types are supported.
Credentials tool configuration parameters
The configuration parameters for the Credentials tool are defined in the Config struct of the github.com/aliyun/credentials-go/credentials package. The credential type is specified by the required type parameter. After you specify the credential type, you must provide the corresponding parameters. The following table describes the valid values for type and the parameters supported by each credential type. A √ indicates a required parameter, a - indicates an optional parameter, and a × indicates an unsupported parameter.
Credential types and parameters that are not listed in the following table are not recommended.
Type | access_key | sts | ram_role_arn | ecs_ram_role | oidc_role_arn | credentials_uri | bearer |
AccessKeyId: The access credential ID. | √ | √ | √ | × | × | × | × |
AccessKeySecret: The access credential secret. | √ | √ | √ | × | × | × | × |
SecurityToken: The STS token. | × | √ | - | × | × | × | × |
RoleArn: The Alibaba Cloud Resource Name (ARN) of the RAM role. | × | × | √ | × | √ | × | × |
RoleSessionName: The custom session name. The default format is | × | × | - | × | - | × | × |
RoleName: The RAM role name. | × | × | × | - | × | × | × |
DisableIMDSv1: Specifies whether to enforce the secure mode. The default value is | × | × | × | - | × | × | × |
BearerToken: The bearer token. | × | × | × | × | × | × | √ |
Policy: The custom permission policy. | × | × | - | × | - | × | × |
RoleSessionExpiration: The session expiration time. The default value is 3600 seconds. | × | × | - | × | - | × | × |
OIDCProviderArn: The ARN of the OIDC IdP. | × | × | × | × | √ | × | × |
OIDCTokenFilePath: The file path of the OIDC token. | × | × | × | × | √ | × | × |
ExternalId: The external ID of the role. This parameter is used to prevent the confused deputy problem. For more information, see Use ExternalId to prevent the confused deputy problem. | × | × | - | × | × | × | × |
Url: The URI of the credential. You must assign a value to this parameter by calling SetURLCredential(v string). | × | × | × | × | × | √ | × |
STSEndpoint: The Endpoint of STS. It supports VPC and Internet Endpoints. For more information about the valid values, see Endpoints. The default value is | × | × | - | × | - | × | × |
Timeout: The read timeout for HTTP requests. The default value is 5000 milliseconds. | × | × | - | - | - | - | × |
ConnectTimeout: The connection timeout for HTTP requests. The default value is 10000 milliseconds. | × | × | - | - | - | - | × |
Initialize the credential client
You can use one of the following methods to initialize a Credentials client as needed:
If you use a plaintext AccessKey pair in a project, the AccessKey pair may be leaked due to improper permission management on the code repository. This may threaten the security of all resources within the account to which the AccessKey pair belongs. We recommend that you store the AccessKey pair in environment variables or configuration files.
We recommend that you initialize the Credentials client in single-instance mode. This mode not only enables the credential caching feature of the SDK, but also effectively prevents traffic control issues and waste of performance resources caused by multiple API calls. For more information, see the Automatic update mechanism of session credentials section of this topic.
Method 1: Use the default credential provider chain
When you initialize the credential client without passing any parameters, Credentials initializes the client using the default credential provider chain. For more information about how default credentials are read, see Default credential provider chain.
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func main() {
// Do not specify parameters or pass nil.
credential, err := credentials.NewCredential(nil)
config := &openapi.Config{}
config.Credential = credential
// The code for initializing the cloud product client using the config is omitted. For more information, see the API call example.
}API call example
Method 2: Use an AK
This method lets you create an AccessKey pair to initialize a Credentials client. For more information, see Create an AccessKey pair.
An Alibaba Cloud account has full permissions on resources within the account. AccessKey pair leaks of an Alibaba Cloud account pose critical threats to the system.
Therefore, we recommend that you use an AccessKey pair of a RAM user that is granted permissions based on the principle of least privilege (PoLP) to initialize a Credentials client.
import (
"fmt"
"os"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func main() {
config := new(credentials.Config).
SetType("access_key").
SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")).
SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"))
akCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = akCredential
// The code for initializing the cloud product client using the config is omitted. For more information, see the API call example.
}API call example
Method 3: Use an STS token
This method lets you use a static STS token to initialize a Credentials client. For more information about how to obtain an STS token, see What is STS? The following example shows how to initialize a Credentials client using an STS token. The example does not show how to obtain an STS token.
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
"os"
)
func main() {
config := new(credentials.Config).
SetType("sts").
// Obtain the AccessKey ID from an environment variable.
SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")).
// Obtain the AccessKey secret from an environment variable.
SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")).
// Obtain the temporary STS credential from an environment variable.
SetSecurityToken(os.Getenv("ALIBABA_CLOUD_SECURITY_TOKEN"))
stsCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = stsCredential
// The code for initializing the cloud product client using the config is omitted. For more information, see the API call example.
}
API call example
Method 4: Use an AK and RamRoleArn
This method is implemented based on STS tokens. When you specify the ARN of a RAM role, the Credentials tool obtains an STS token from STS. You can also assign a value to SetPolicy to restrict the RAM role to a smaller set of permissions.
package main
import (
"fmt"
"os"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func main() {
config := new(credentials.Config).
SetType("ram_role_arn").
SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")).
SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")).
// The ARN of the RAM role to assume. Example: acs:ram::123456789012****:role/adminrole. You can set RoleArn using the ALIBABA_CLOUD_ROLE_ARN environment variable.
SetRoleArn("<RoleArn>").
// The role session name. You can set RoleSessionName using the ALIBABA_CLOUD_ROLE_SESSION_NAME environment variable.
SetRoleSessionName("<RoleSessionName>").
// Optional. Set a more restrictive permission policy. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
SetPolicy("<Policy>").
// Optional. Set the session expiration time.
SetRoleSessionExpiration(3600).
// Optional. The external ID of the role. This parameter is provided by an external party to identify the role and is used to prevent the confused deputy problem.
SetExternalId("ExternalId").
// Optional. The default value is sts.aliyuncs.com. We recommend that you use a region-specific STS domain name. Select a region that is closer to you to ensure network connectivity.
SetSTSEndpoint("sts.cn-hangzhou.aliyuncs.com")
arnCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = arnCredential
// The code for initializing the cloud product client using the config is omitted. For more information, see the API call example.
}
For more information about ExternalId, see Use ExternalId to prevent the confused deputy problem.
API call example
Method 5: Use an ECS instance RAM role
ECS and ECI instances can have instance RAM roles attached. Programs running on the instances can automatically retrieve the STS tokens for the roles through the Credentials tool to initialize the credential client.
By default, the Credentials tool accesses the Instance Metadata Service (IMDS) of ECS in secure mode (IMDSv2). If an exception occurs in secure mode, the tool uses the normal mode as a fallback to retrieve access credentials. You can also set the disableIMDSv1 parameter or the ALIBABA_CLOUD_IMDSV1_DISABLE environment variable to specify the exception handling logic:
If the value is false (default), the tool continues to retrieve access credentials in normal mode.
If the value is true, the tool can only retrieve access credentials in secure mode. An exception is thrown if the attempt fails.
Whether the server supports IMDSv2 depends on your server configuration.
You can also disable credential access to ECS metadata by setting the ALIBABA_CLOUD_ECS_METADATA_DISABLED=true environment variable.
To obtain temporary identity credentials in secure mode, the version of credentials-go must be 1.3.10 or later.
For more information about ECS instance metadata, see Instance metadata.
For more information about how to grant RAM roles to ECS and ECI instances, see Create a RAM role and grant it to an ECS instance and Grant an instance RAM role to an ECI instance.
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func _main(args []*string) {
// Initialize the Credentials client with EcsRamRole.
credentialsConfig := new(credentials.Config).
// The credential type.
SetType("ecs_ram_role").
// Optional. The name of the ECS role. If you do not specify this parameter, the role name is automatically obtained. We recommend that you specify this parameter to reduce the number of requests. You can set RoleName using the ALIBABA_CLOUD_ECS_METADATA environment variable.
SetRoleName("<RoleName>")
// Optional. Default value: false. If you set this parameter to true, the secure mode is enforced. If you set this parameter to false, the system first tries to obtain credentials in secure mode. If the attempt fails, the system switches to the normal mode (IMDSv1).
// credentialsConfig.SetDisableIMDSv1(true)
credentialClient, err := credentials.NewCredential(credentialsConfig)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = credentialClient
// The code for initializing the cloud product client using the config is omitted. For more information, see the API call example.
}
API call example
Method 6: Use OIDCRoleArn
To ensure the security of cloud resources and enable untrusted applications to securely obtain required STS tokens, you can use the RAM Roles for Service Accounts (RRSA) feature to grant minimum necessary permissions to an application. ACK creates and mounts corresponding OpenID Connect (OIDC) token files for different application pods, and passes relevant configuration information to environment variables. The Credentials tool obtains the configuration information from the environment variables and calls the AssumeRoleWithOIDC operation of STS to obtain the STS token for attached roles.
The following environment variables are injected into the pod:
ALIBABA_CLOUD_ROLE_ARN: the ARN of the RAM role.
ALIBABA_CLOUD_OIDC_PROVIDER_ARN: the ARN of the OIDC identity provider (IdP).
ALIBABA_CLOUD_OIDC_TOKEN_FILE: the path of the OIDC token file.
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
"os"
)
func main() {
config := new(credentials.Config).
SetType("oidc_role_arn").
// The ARN of the OIDC IdP. You can set OidcProviderArn using the ALIBABA_CLOUD_OIDC_PROVIDER_ARN environment variable.
SetOIDCProviderArn(os.Getenv("ALIBABA_CLOUD_OIDC_PROVIDER_ARN")).
// The file path of the OIDC token. You can set OidcTokenFilePath using the ALIBABA_CLOUD_OIDC_TOKEN_FILE environment variable.
SetOIDCTokenFilePath(os.Getenv("ALIBABA_CLOUD_OIDC_TOKEN_FILE")).
// The ARN of the RAM role. You can set RoleArn using the ALIBABA_CLOUD_ROLE_ARN environment variable.
SetRoleArn(os.Getenv("ALIBABA_CLOUD_ROLE_ARN")).
// The role session name. You can set RoleSessionName using the ALIBABA_CLOUD_ROLE_SESSION_NAME environment variable.
SetRoleSessionName(os.Getenv("ALIBABA_CLOUD_ROLE_SESSION_NAME")).
// Optional. Set a more restrictive permission policy. Example: {"Statement": [{"Action": ["*"],"Effect": "Allow","Resource": ["*"]}],"Version":"1"}
SetPolicy("<Policy>").
// Optional. Set the session expiration time.
SetRoleSessionExpiration(3600).
// Optional. The default value is sts.aliyuncs.com. We recommend that you use a region-specific STS domain name. Select a region that is closer to you to ensure network connectivity.
SetSTSEndpoint("sts.cn-hangzhou.aliyuncs.com")
oidcCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = oidcCredential
// The code for initializing the cloud product client using the config is omitted. For more information, see the API call example.
}
API call example
Method 7: Use a URI credential
This method lets you encapsulate an STS token in your application and provide a custom URI to external resources. Other services can obtain the STS token only through the URI. This minimizes the risk of AccessKey exposure. The Credentials tool lets you obtain the STS token by calling the service URI to initialize the Credentials client.
package main
import (
"github.com/aliyun/credentials-go/credentials"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
)
func main() {
config := new(credentials.Config).
SetType("credentials_uri").
// The URI of the credential. The format is http://local_or_remote_uri/. You can set CredentialsUri using the ALIBABA_CLOUD_CREDENTIALS_URI environment variable.
SetURLCredential("<CredentialsUri>")
uriCredential, err := credentials.NewCredential(config)
config := &openapi.Config{}
config.Credential = uriCredential
// The code for initializing the cloud product client using the config is omitted. For more information, see the API call example.
}
The address must meet the following requirements:
Supports GET requests.
The response body has the following structure:
{ "AccessKeySecret": "AccessKeySecret", "AccessKeyId": "AccessKeyId", "Expiration": "2021-09-26T03:46:38Z", "SecurityToken": "SecurityToken" }
API call example
Method 8: Use a Bearer Token
Currently, only Cloud Call Center (CCC) supports credential initialization with a Bearer Token.
package main
import (
"fmt"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials"
)
func main() {
config := new(credentials.Config).
SetType("bearer").
// Enter your Bearer Token.
SetBearerToken("<BearerToken>")
bearerCredential, err := credentials.NewCredential(config)
if err != nil {
return
}
config := &openapi.Config{}
config.Credential = bearerCredential
// The code for initializing the cloud product client using the config is omitted. For more information, see the API call example.
}API call example
Method 9: Use CLIProfileCredentialsProvider
This method obtains access credentials from the Alibaba Cloud CLI credential configuration file (config.json).
package main
import (
"github.com/aliyun/credentials-go/credentials"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
"github.com/aliyun/credentials-go/credentials/providers"
)
func main() {
// CLIProfileCredentialsProvider
provider, err := providers.NewCLIProfileCredentialsProviderBuilder().
// The credential name. This parameter is optional. You can configure this parameter in multiple ways. The priorities are listed in descending order: the explicitly specified profileName -> the profileName specified by the ALIBABA_CLOUD_CONFIG_FILE environment variable -> the current profile in the config.json file.
WithProfileName("<PROFILE_NAME>").
// The path of the configuration file. The file must be a .json file. This parameter is optional. You can configure this parameter in multiple ways. The priorities are listed in descending order: the explicitly specified profileFile -> the profileFile specified by the ALIBABA_CLOUD_CONFIG_FILE environment variable -> the default ~/.aliyun/config.json file.
WithProfileFile("<PROFILE_FILE_PATH>").
Build()
if err != nil {
return
}
credential := credentials.FromCredentialsProvider("cli_profile", provider)
config := &openapi.Config{}
config.Credential = credential
// The code for initializing the cloud product client using the config is omitted. For more information, see the API call example.
}You can configure credentials using Alibaba Cloud CLI or manually create a config.json configuration file in the following path:
Linux:
~/.aliyun/config.jsonWindows:
C:\Users\USER_NAME\.aliyun\config.json
The following shows the format of the file:
{
"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
},
{
"name": "<PROFILE_NAME6>",
"mode": "CloudSSO",
"cloud_sso_sign_in_url": "https://******/login",
"access_token": "eyJraWQiOiJiYzViMzUwYy******",
"cloud_sso_access_token_expire": 1754316142,
"cloud_sso_access_config": "ac-00s1******",
"cloud_sso_account_id": "151266******"
}
]
}
In the config.json configuration file, you can use mode to specify different credentials:
AK: Uses the user's AccessKey as the credential.
StsToken: Uses an STS token as the credential.
RamRoleArn: Uses the ARN of a RAM role to obtain the credential.
EcsRamRole: Uses the RAM role attached to an ECS instance to obtain the credential.
OIDC: Uses an OIDC ARN and an OIDC token to obtain the credential.
ChainableRamRoleArn: Uses a role chain. It specifies the name of another credential in the
config.jsonfile throughsource_profileto obtain a new credential.CloudSSO: The credential obtained by a CloudSSO user using Alibaba Cloud CLI.
NoteCloudSSO credentials require version 1.4.7 or later of
github.com/aliyun/credentials-go. The configuration can only be obtained through Alibaba Cloud CLI. For more information, see Use the CLI to log on to CloudSSO and access Alibaba Cloud resources.
After the configuration is complete, Credentials initializes the credential client with the credential that corresponds to the specified credential name.
API call example
Default credential provider chain
If the credential types used in the development and production environments are different, you typically write branch code to retrieve different credentials based on the current environment. The default credential provider chain of the Credentials tool lets you use the same code and control how credentials are retrieved in different environments through configurations outside the program. When you use NewCredential() to initialize the credential client without passing any parameters, the Alibaba Cloud SDK tries to retrieve the relevant credential information in the following order.
1. Environment variables
If no credential information is found in the system attributes, the Credentials continues to check the environment variables.
If both the ALIBABA_CLOUD_ACCESS_KEY_ID and ALIBABA_CLOUD_ACCESS_KEY_SECRET environment variables are specified, they are used as the default credential.
If ALIBABA_CLOUD_ACCESS_KEY_ID, ALIBABA_CLOUD_ACCESS_KEY_SECRET, and ALIBABA_CLOUD_SECURITY_TOKEN are specified, the STS token is used as the default credential.
2. OIDC RAM role
If no credentials with a higher priority are found, the Credentials tool checks the following environment variables that are related to the RAM role of the OIDC IdP:
ALIBABA_CLOUD_ROLE_ARN: the ARN of the RAM role.
ALIBABA_CLOUD_OIDC_PROVIDER_ARN: the ARN of the OIDC IdP.
ALIBABA_CLOUD_OIDC_TOKEN_FILE: the file path of the OIDC token.
If the preceding three environment variables are specified and valid, the Credentials tool uses the environment variables to call the AssumeRoleWithOIDC operation of STS to obtain an STS token as the default credential.
3. config.json configuration file
If no credential information with a higher priority is retrieved, the Credentials tool tries to load the config.json configuration file. The default full path of this configuration file is as follows:
Linux/macOS:
~/.aliyun/config.jsonWindows:
C:\Users\USER_NAME\.aliyun\config.json
Starting with version github.com/aliyun/credentials-go@1.4.4, you can use the ALIBABA_CLOUD_CONFIG_FILE environment variable to customize the path of the config.json configuration file. This environment variable has a higher priority than the default path.
To configure access credentials in this way, you can use Alibaba Cloud CLI to configure credentials or manually create a config.json configuration file in the corresponding path. The following code provides an example of the file 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
},
{
"name": "<PROFILE_NAME6>",
"mode": "CloudSSO",
"cloud_sso_sign_in_url": "https://******/login",
"access_token": "eyJraWQiOiJiYzViMzUwYy******",
"cloud_sso_access_token_expire": 1754316142,
"cloud_sso_access_config": "ac-00s1******",
"cloud_sso_account_id": "151266******"
},
{
"name": "<PROFILE_NAME7>",
"mode": "OAuth",
"access_key_id": "<ALIBABA_CLOUD_ACCESS_KEY_ID>",
"access_key_secret": "<ALIBABA_CLOUD_ACCESS_KEY_SECRET>",
"sts_token": "<SECURITY_TOKEN>",
"region_id": "<REGION_ID>",
"output_format": "json",
"language": "<zh|en>",
"sts_expiration": "<STS_EXPIRATION>",
"oauth_access_token": "<OAUTH_ACCESS_TOKEN>",
"oauth_refresh_token": "<OAUTH_REFRESH_TOKEN>",
"oauth_access_token_expire": 1754316142,
"oauth_site_type": "<CN|EN>"
}
]
}In the config.json configuration file, you can use mode to specify different credentials:
AK: Uses the user's AccessKey as the credential.
StsToken: Uses an STS token as the credential.
RamRoleArn: Uses the ARN of a RAM role to obtain the credential.
EcsRamRole: Uses the RAM role attached to an ECS instance to obtain the credential.
OIDC: Uses an OIDC ARN and an OIDC token to obtain the credential.
ChainableRamRoleArn: Uses a role chain. It specifies the name of another credential in the
config.jsonfile throughsource_profileto obtain a new credential.OAuth: The credential obtained using the CLI through OAuth logon.
CloudSSO: The credential obtained by a CloudSSO user using Alibaba Cloud CLI.
OAuth credentials require version 1.4.8 or later of
github.com/aliyun/credentials-go. The configuration can only be obtained through Alibaba Cloud CLI. For more information, see Use the CLI to obtain an OAuth credential.CloudSSO credentials require version 1.4.7 or later of
github.com/aliyun/credentials-go. The configuration can only be obtained through Alibaba Cloud CLI. For more information, see Use the CLI to log on to CloudSSO and access Alibaba Cloud resources.
After the configuration is complete, Credentials initializes the credential client with the credential specified by current in the configuration file. You can also specify a credential name using the ALIBABA_CLOUD_PROFILE environment variable. For example, set the value of ALIBABA_CLOUD_PROFILE to client1.
4. ECS instance RAM role
If no credential information with a higher priority is retrieved, Credentials tries to retrieve a credential using the RAM role attached to an ECS instance. By default, Credentials accesses the IMDS of ECS in secure mode (IMDSv2) to retrieve the STS token of the ECS instance RAM role as the default credential. The program automatically accesses the IMDS of ECS to obtain the RoleName information and then retrieves the credential. This process involves two requests. To reduce the number of requests, you can specify the instance RAM role name by setting the ALIBABA_CLOUD_ECS_METADATA environment variable. If an exception occurs in secure mode, the tool uses the normal mode as a fallback to retrieve access credentials. You can also set the ALIBABA_CLOUD_IMDSV1_DISABLE environment variable to specify the exception handling logic:
If the value is false, the tool continues to retrieve access credentials in normal mode.
If the value is true, the tool can only retrieve access credentials in secure mode. An exception is thrown if the attempt fails.
Whether the server supports IMDSv2 depends on your server configuration.
You can also disable credential access to ECS metadata by setting the ALIBABA_CLOUD_ECS_METADATA_DISABLED=true environment variable.
For more information about ECS instance metadata, see Instance metadata.
For more information about how to grant RAM roles to ECS and ECI instances, see Create a RAM role and grant it to an ECS instance and Grant an instance RAM role to an ECI instance.
5. Credentials tool URI
If no valid credential is obtained using the preceding methods, the Credentials tool checks the ALIBABA_CLOUD_CREDENTIALS_URI environment variable. If this environment variable exists and specifies a valid URI, the Credentials tool initiates an HTTP requests to obtain an STS token as the default credential.
Auto-refresh mechanism for session-based credentials
Session credentials include ARNs of RAM roles (RamRoleArn), RAM roles of ECS instances, RAM roles of OIDC IdPs (OIDCRoleArn), and credential URIs. The Credentials tool provides a built-in automatic update mechanism for session credentials. After a credential is obtained from the first call, the Credentials tool stores the credential in the cache. In subsequent calls, the credential is read from the cache as long as the credential is not expired. Otherwise, the Credentials tool makes a call to obtain the credential again, and updates the credential in the cache.
For RAM roles of ECS instances, the Credentials tool updates the credential 15 minutes before the cache time-to-live (TTL) ends.
In the following example, the Credentials client is created in single-instance mode and is used to initialize the cloud service client. Then, an API operation is called during different time periods to check whether internal cache is used and whether the credential is refreshed after the cache expires.
package main
import (
"fmt"
"log"
"os"
"sync"
"time"
openapi "github.com/alibabacloud-go/darabonba-openapi/v2/client"
ecs20140526 "github.com/alibabacloud-go/ecs-20140526/v7/client"
util "github.com/alibabacloud-go/tea-utils/v2/service"
"github.com/alibabacloud-go/tea/tea"
"github.com/aliyun/credentials-go/credentials"
)
// Credential is a singleton struct used to manage Alibaba Cloud credential instances.
type Credential struct {
instance credentials.Credential
once sync.Once
}
var credentialInstance = &Credential{}
func GetCredentialInstance() credentials.Credential {
credentialInstance.once.Do(func() {
cfg := &credentials.Config{
Type: tea.String("ram_role_arn"),
AccessKeyId: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")),
AccessKeySecret: tea.String(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")),
RoleArn: tea.String(os.Getenv("ALIBABA_CLOUD_ROLE_ARN")),
RoleSessionName: tea.String("RamRoleArnTest"),
RoleSessionExpiration: tea.Int(3600),
}
var err error
credentialInstance.instance, err = credentials.NewCredential(cfg)
if err != nil {
log.Fatalf("Credential initialization failed: %v", err)
}
})
return credentialInstance.instance
}
// EcsClient is a singleton struct used to manage ECS client instances.
type EcsClient struct {
instance *ecs20140526.Client
once sync.Once
}
var ecsClientInstance = &EcsClient{}
func GetEcsClientInstance(cred credentials.Credential) *ecs20140526.Client {
ecsClientInstance.once.Do(func() {
cfg := &openapi.Config{
Endpoint: tea.String("ecs.cn-hangzhou.aliyuncs.com"),
Credential: cred,
}
var err error
ecsClientInstance.instance, err = ecs20140526.NewClient(cfg)
if err != nil {
log.Fatalf("ECS client initialization failed: %v", err)
}
})
return ecsClientInstance.instance
}
// Execute the main task.
func runTask() {
cred := GetCredentialInstance()
credentialModel, err := cred.GetCredential()
if err != nil {
log.Printf("Failed to get credential: %v", err)
return
}
fmt.Println(time.Now())
fmt.Printf("AK ID: %s, AK Secret: %s, STS Token: %s\n",
*credentialModel.AccessKeyId,
*credentialModel.AccessKeySecret,
*credentialModel.SecurityToken)
ecsClient := GetEcsClientInstance(cred)
req := &ecs20140526.DescribeRegionsRequest{}
runtime := &util.RuntimeOptions{}
resp, err := ecsClient.DescribeRegionsWithOptions(req, runtime)
if err != nil {
log.Printf("ECS API call failed: %v", err)
return
}
fmt.Printf("Invoke result: %d\n", *resp.StatusCode)
}
func main() {
done := make(chan bool)
// Start a goroutine to execute the scheduled task.
go func() {
tick := time.NewTicker(1 * time.Second)
defer tick.Stop()
executionCount := 0
delays := []time.Duration{0, 600, 3600, 100} // Delay time in seconds.
for {
select {
case <-tick.C:
if executionCount < len(delays) {
delay := delays[executionCount]
time.Sleep(delay * time.Second)
runTask()
executionCount++
} else {
close(done)
return
}
}
}
}()
<-done
fmt.Println("All tasks completed. Exiting...")
}

Log analysis:
In the first call, the system obtains the credential based on the configurations because the credential is not cached. After the system obtains the credential, the credential is stored in the cache.
The second call uses the same credential as the first call, which indicates that the credential is obtained from the cache.
In the third call, the credential has expired because the third call is 4,200 seconds later than the first call while the credential TTL (RoleSessionExpiration) is set to 3,600 seconds. The SDK obtains the credential again based on the automatic update mechanism and stored the credential in the cache.
The fourth call uses the same credential as the third call, which indicates that the credential is updated after cache expiration.
References
For more information about RAM, see Terms.
For more information about how to create an AccessKey pair, see Create an AccessKey pair.
For more information about how to create a RAM user, an AccessKey pair, a RAM role, and a policy and grant permissions to a RAM user, see RAM SDK overview.
For more information about how to assume a role using a program, see STS SDK overview.
For more information about RAM and STS-related API operations, see API Reference.
Best practices for using an access credential to call API operations