To use the Object Storage Service (OSS) SDK for Go to initiate a request, you must configure access credentials. Alibaba Cloud services use access credentials to verify identity information and access permissions. You can select different types of access credentials based on your authentication and authorization requirements. This topic describes how to configure temporary access credentials and long-term access credentials.
Considerations
-
For more information about the regions and endpoints supported by OSS, see OSS regions and endpoints.
-
To create an AccessKey for a RAM user, see Create an AccessKey.
-
Use the latest version of the OSS Go SDK V2 to ensure that the code samples in this topic can run properly. .
Credential provider selection
OSS supports multiple methods to initialize a credential provider. You can select a suitable method based on your actual authentication and authorization requirements.
Credential provider initialization method | Applicable scenarios | Is a pre-provided AK or STS token required | Underlying credential | Credential validity period | Credential rotation or refresh method |
Applications are deployed and run in a secure and stable environment that is not vulnerable to external attacks and need to access cloud services for a long period of time without frequent credential rotation | Yes | AK | Long-term | Manual rotation | |
Applications are deployed and run in an untrusted environment, in which case you want to manage the credential validity and the resources that can be accessed | Yes | STS token | Temporary | Manual refresh | |
Applications require access to cloud services, such as cross-account access | Yes | STS token | Temporary | Automatic refresh | |
Applications are deployed and run on Elastic Compute Service (ECS) instances, Elastic Container Instance, or Container Service for Kubernetes (ACK) worker nodes | No | STS token | Temporary | Automatic refresh | |
Untrusted applications are deployed and run on ACK worker nodes | No | STS token | Temporary | Automatic refresh | |
If none of the preceding methods meet your requirements, you can use a custom method to obtain access credentials | Custom | Custom | Custom | Custom | |
If you initialize a Credentials client without specifying an initialization method, the Credentials tool obtains credentials based on the order of the default credential provider chain | Custom | Custom | Custom | Custom |
Common configuration examples
Use the AK of a RAM user
If your application is deployed in a secure and stable environment that is not vulnerable to external attacks and requires long-term access to OSS, you can use an AccessKey pair of your Alibaba Cloud account or a RAM user to initialize a credential provider. Take note that this method requires you to manually maintain an AccessKey pair. This poses security risks and increases maintenance complexity.
-
An Alibaba Cloud account has full access to all resources of the account. Leaks of the Alibaba Cloud account AccessKey pair pose critical security threats. We recommend that you use the AccessKey pair of a RAM user that is granted permissions based on the principle of least privilege.
-
To create an AccessKey for a RAM user, visit Create an AccessKey. The AccessKey pair of a RAM user is displayed only when the RAM user is created. Save the AccessKey pair in a timely manner. If you forget the AccessKey pair, create a new AccessKey pair for rotation.
Environment variables
-
Configure environment variables for the AccessKey pair of the RAM user.
Linux
Run the following commands on the CLI to add the configurations of the environment variables to the
~/.bashrc
file:echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bashrc
Run the following command to apply the changes:
source ~/.bashrc
Run the following commands to check whether the environment variables take effect:
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
macOS
Run the following command in the terminal to view the default shell type:
echo $SHELL
Configure environment variables based on the default shell type.
Zsh
Run the following commands to add the configurations of the environment variables to the
~/.zshrc
file:echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.zshrc
Run the following command to apply the changes:
source ~/.zshrc
Run the following commands to check whether the environment variables take effect:
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Bash
Run the following commands to add the configurations of the environment variables to the
~/.bash_profile
file:echo "export OSS_ACCESS_KEY_ID='YOUR_ACCESS_KEY_ID'" >> ~/.bash_profile echo "export OSS_ACCESS_KEY_SECRET='YOUR_ACCESS_KEY_SECRET'" >> ~/.bash_profile
Run the following command to apply the changes:
source ~/.bash_profile
Run the following commands to check whether the environment variables take effect:
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET
Windows
CMD
Run the following commands in CMD:
setx OSS_ACCESS_KEY_ID "YOUR_ACCESS_KEY_ID" setx OSS_ACCESS_KEY_SECRET "YOUR_ACCESS_KEY_SECRET"
Run the following commands to check whether the environment variables take effect:
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET%
PowerShell
Run the following commands in PowerShell:
[Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_ID", "YOUR_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::SetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", "YOUR_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
Run the following commands to check whether the environment variable takes effect:
[Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_ID", [EnvironmentVariableTarget]::User) [Environment]::GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET", [EnvironmentVariableTarget]::User)
-
After you modify the system environment variables as described above, restart or refresh your compilation and runtime environments, such as the IDE, command-line tool, desktop applications, and services in the background, to ensure that the latest system environment variables are loaded.
-
Obtain credentials from environment variables.
package main import ( "log" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" ) func main() { // Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou region := "cn-hangzhou" // Obtain a credential from the environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables are configured provider := credentials.NewEnvironmentVariableCredentialsProvider() // Load the default configurations and specify the credential provider and region cfg := oss.LoadDefaultConfig(). WithCredentialsProvider(provider). WithRegion(region) // Create an OSS client client := oss.NewClient(cfg) log.Printf("ossclient: %v", client) }
Static credentials
The following sample code shows how to hardcode the static credentials in your application to explicitly specify the AccessKey pair that you want to use to access OSS.
Do not embed access credentials in production applications. This method is used only for testing purposes.
package main
import (
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
func main() {
// Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou
region := "cn-hangzhou"
// Specify the AccessKey ID and AccessKey secret of the RAM user
accessKeyID := "LTAI5tQQx1DWEYK7********"
accessKeySecret := "s5LkMqKmmKbt3zjs7MNJTj********"
// Use the NewStaticCredentialsProvider method to directly specify the AccessKey pair
provider := credentials.NewStaticCredentialsProvider(accessKeyID, accessKeySecret)
// Load the default configurations and specify the credential provider and region
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(provider).
WithRegion(region)
// Create an OSS client
client := oss.NewClient(cfg)
log.Printf("ossclient: %v", client)
}
Use temporary access credentials provided by STS
If your application needs to access OSS temporarily, you can use temporary access credentials, which consist of an AccessKey pair and a security token, obtained from Security Token Service (STS) to initialize a credential provider. Take note that this method requires you to manually maintain a security token. This poses security risks and increases maintenance complexity. If you want to prolong access after the existing STS token expires, you must manually refresh the STS token.
-
To obtain temporary access credentials provided by STS in a simple and quick manner by using OpenAPI, see AssumeRole - Obtain the temporary access credentials of the assumed role.
-
To obtain temporary access credentials provided by STS by using an SDK, see Use temporary access credentials provided by STS to access OSS.
-
You must specify a validity period for the STS token when you generate the token. An expired STS token cannot be used.
-
For more information about the endpoints of STS, see Service endpoints.
Environment variables
-
Configure environment variables for temporary access credentials.
Mac OS X/Linux/Unix
Warning-
Note that the temporary access credentials (AccessKey ID, AccessKey secret, and STS token) provided by STS are used instead of the AccessKey ID and AccessKey secret of the RAM user.
-
The AccessKey ID obtained from STS starts with STS. Example: STS.L4aBSCSJVMuKg5U1****.
export OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID> export OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET> export OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>
Windows
Warning-
Note that the temporary access credentials (AccessKey ID, AccessKey secret, and STS token) provided by STS are used instead of the AccessKey pair (AccessKey ID and AccessKey secret) of the RAM user.
-
The AccessKey ID obtained from STS starts with STS. Example: STS.L4aBSCSJVMuKg5U1****.
set OSS_ACCESS_KEY_ID=<STS_ACCESS_KEY_ID> set OSS_ACCESS_KEY_SECRET=<STS_ACCESS_KEY_SECRET> set OSS_SESSION_TOKEN=<STS_SECURITY_TOKEN>
-
-
Obtain credentials from environment variables.
package main import ( "log" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" ) func main() { // Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou region := "cn-hangzhou" // Obtain a credential from the environment variables. Before you run the sample code, make sure that the OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, and OSS_SESSION_TOKEN environment variables are configured provider := credentials.NewEnvironmentVariableCredentialsProvider() // Load the default configurations and specify the credential provider and region cfg := oss.LoadDefaultConfig(). WithCredentialsProvider(provider). WithRegion(region) // Create an OSS client client := oss.NewClient(cfg) log.Printf("ossclient: %v", client) }
Static credentials
You can hardcode the static credentials in your application to explicitly specify the AccessKey pair that you want to use to access OSS.
Do not embed access credentials in production applications. This method is used only for testing purposes.
package main
import (
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
func main() {
// Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou
region := "cn-hangzhou"
// Specify the AccessKey ID, AccessKey secret, and STS token that are provided by STS, rather than the AccessKey ID and AccessKey secret of the RAM user
// The AccessKey ID obtained from STS starts with STS. Example:
accessKeyID := "LTAI5tQQx1DWEYK7********"
accessKeySecret := "s5LkMqKmmKbt3zjs7MNJTj********"
stsToken= "CAISv**********************"
// Use the NewStaticCredentialsProvider method to directly specify the AccessKey pair and STS token
provider := credentials.NewStaticCredentialsProvider(accessKeyID, accessKeySecret, stsToken)
// Load the default configurations and specify the credential provider and region
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(provider).
WithRegion(region)
// Create an OSS client
client := oss.NewClient(cfg)
log.Printf("ossclient: %v", client)
}
More scenario-specific configuration examples
Use RAMRoleARN
If your application needs to be authorized to access OSS, such as when accessing the OSS resources of another Alibaba Cloud account, you can use RAMRoleARN to initialize a credential provider. The underlying logic of this method is to use an STS token. The Credentials tool obtains an STS token based on the ARN of the RAM role and refreshes the STS token by calling the AssumeRole operation before the session expires. Additionally, you can restrict the RAM role to a smaller set of permissions by assigning a value to the policy
.
-
An Alibaba Cloud account has full access to all resources of the account. Leaks of the Alibaba Cloud account AccessKey pair pose critical security threats. We recommend that you use the AccessKey pair of a RAM user that is granted permissions based on the principle of least privilege.
-
To create an AccessKey for a RAM user, visit Create an AccessKey. The AccessKey pair of a RAM user is displayed only when the RAM user is created. Save the AccessKey pair in a timely manner. If you forget the AccessKey pair, create a new AccessKey pair for rotation.
-
To obtain RAMRoleARN, visit CreateRole - Create a role.
-
Add the credentials dependency.
go get github.com/aliyun/credentials-go/credentials
-
Configure access credentials.
package main import ( "context" "log" "os" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" openapicred "github.com/aliyun/credentials-go/credentials" ) func main() { // Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou region := "cn-hangzhou" config := new(openapicred.Config). // Set the credential type to ram_role_arn SetType("ram_role_arn"). // Obtain the AccessKey ID and AccessKey secret of the RAM user from the environment variables SetAccessKeyId(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")). SetAccessKeySecret(os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")). // By default, the values of the parameters are directly entered for the following operations. You can also add environment variables and use os.Getenv("<variable name>") to specify the corresponding parameters // Obtain the ARN of the RAM role from the environment variables. The ARN is the ID of the role. Format: acs:ram::$accountID:role/$roleName SetRoleArn("ALIBABA_CLOUD_ROLE_ARN"). // By default, the canonical name of the RoleArn environment variable is ALIBABA_CLOUD_ROLE_ARN // Specify a custom session name for the role to distinguish different tokens SetRoleSessionName("ALIBABA_CLOUD_ROLE_SESSION_NAME"). // By default, the canonical name of the RoleSessionName environment variable is ALIBABA_CLOUD_ROLE_SESSION_NAME // Optional. Specify the permissions of the security token SetPolicy("Policy"). // Optional. Specify the validity period of the security token SetRoleSessionExpiration(3600) arnCredential, gerr := openapicred.NewCredential(config) provider := credentials.CredentialsProviderFunc(func(ctx context.Context) (credentials.Credentials, error) { if gerr != nil { return credentials.Credentials{}, gerr } cred, err := arnCredential.GetCredential() if err != nil { return credentials.Credentials{}, err } return credentials.Credentials{ AccessKeyID: *cred.AccessKeyId, AccessKeySecret: *cred.AccessKeySecret, SecurityToken: *cred.SecurityToken, }, nil }) // Load the default configurations and specify the credential provider and region cfg := oss.LoadDefaultConfig(). WithCredentialsProvider(provider). WithRegion(region) // Create an OSS client client := oss.NewClient(cfg) log.Printf("ossclient: %v", client) }
Use ECSRAMRole
If your application is running on an ECS instance, ECI instance, or a Worker node of Container Service for Kubernetes, it is advisable to use an ECS RAM role to initialize the credentials provider. This approach utilizes an STS token and allows the association of a role with an ECS instance, ECI instance, or Worker node of Container Service for Kubernetes for automatic STS token refresh within the instance. By using this method, there is no need to supply an AccessKey pair or STS token, thus reducing the risks of manual credential management. For information on obtaining an ECS RAM role, see CreateRole - 创建角色.
-
Add the credentials dependency.
go get github.com/aliyun/credentials-go/credentials
-
Configure access credentials.
package main import ( "context" "log" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" openapicred "github.com/aliyun/credentials-go/credentials" ) func main() { // Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou region := "cn-hangzhou" config := new(openapicred.Config). // Set the credential type to ecs_ram_role SetType("ecs_ram_role"). // Optional. Specify the role name. If you do not specify the role name, OSS automatically generates a role name. We recommend that you specify a role name to reduce the number of requests SetRoleName("RoleName") arnCredential, gerr := openapicred.NewCredential(config) provider := credentials.CredentialsProviderFunc(func(ctx context.Context) (credentials.Credentials, error) { if gerr != nil { return credentials.Credentials{}, gerr } cred, err := arnCredential.GetCredential() if err != nil { return credentials.Credentials{}, err } return credentials.Credentials{ AccessKeyID: *cred.AccessKeyId, AccessKeySecret: *cred.AccessKeySecret, SecurityToken: *cred.SecurityToken, }, nil }) // Load the default configurations and specify the credential provider and region cfg := oss.LoadDefaultConfig(). WithCredentialsProvider(provider). WithRegion(region) // Create an OSS client client := oss.NewClient(cfg) log.Printf("ossclient: %v", client) }
Use OIDCRoleARN
After setting the RAM role for worker nodes in Container Service for Kubernetes, applications within pods on these nodes can retrieve the STS token of the attached role via the metadata server, similar to applications on ECS. However, you may want to prevent untrusted applications, such as those submitted by customers who do not share their application code, from accessing the metadata server to retrieve the STS token of the RAM role attached to the worker node. To protect cloud resources, enable untrusted applications to securely obtain the necessary security token, and limit application-level permissions, you can utilize the RAM Roles for Service Account (RRSA) feature. This method relies on an STS token, where ACK generates and mounts OpenID Connect (OIDC) token files for different application pods and conveys relevant configuration details through environment variables. The Credentials tool retrieves this configuration from the environment variables and invokes the AssumeRoleWithOIDC operation of STS to retrieve the STS token for attached roles, thereby mitigating the risks associated with manually managing an AccessKey pair or an STS token. For more information, see Isolate pod permissions by configuring RAM permissions for ServiceAccount through RRSA.
-
Add the credentials dependency.
go get github.com/aliyun/credentials-go/credentials
-
Configure access credentials.
package main import ( "context" "log" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" openapicred "github.com/aliyun/credentials-go/credentials" ) func main() { // Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou region := "cn-hangzhou" config := new(openapicred.Config). // Set the credential type to oidc_role_arn SetType("oidc_role_arn"). // Specify the ARN of the OIDC IdP. The ARN is in the acs:ram::account-id:oidc-provider/provider-name format SetOIDCProviderArn("OIDCProviderArn"). // Specify the path of the file in which the OIDC token is stored SetOIDCTokenFilePath("OIDCTokenFilePath"). // Specify a custom session name for the role to distinguish different tokens SetRoleSessionName("RoleSessionName"). // By default, the canonical name of the RoleSessionName environment variable is ALIBABA_CLOUD_ROLE_SESSION_NAME // Optional. Specify the policy of the RAM role SetPolicy("Policy"). // Specify the ARN of the RAM role, which is the ID of the role to be assumed. Format: acs:ram::113511544585****:oidc-provider/TestOidcProvider SetRoleArn("RoleArn"). // Specify the validity period of the session SetSessionExpiration(3600) arnCredential, gerr := openapicred.NewCredential(config) provider := credentials.CredentialsProviderFunc(func(ctx context.Context) (credentials.Credentials, error) { if gerr != nil { return credentials.Credentials{}, gerr } cred, err := arnCredential.GetCredential() if err != nil { return credentials.Credentials{}, err } return credentials.Credentials{ AccessKeyID: *cred.AccessKeyId, AccessKeySecret: *cred.AccessKeySecret, SecurityToken: *cred.SecurityToken, }, nil }) // Load the default configurations and specify the credential provider and region cfg := oss.LoadDefaultConfig(). WithCredentialsProvider(provider). WithRegion(region) // Create an OSS client client := oss.NewClient(cfg) log.Printf("ossclient: %v", client) }
Use a custom credential provider
If the preceding credential configuration methods do not meet your requirements, you can specify the method that you want to use to obtain credentials. The following methods are supported:
-
Use the credentials.CredentialsProviderFunc method
package main import ( "context" "log" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" ) func main() { // Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou region := "cn-hangzhou" // Create a credential provider provider := credentials.CredentialsProviderFunc(func(ctx context.Context) (credentials.Credentials, error) { // Return long-term credentials return credentials.Credentials{AccessKeyID: "id", AccessKeySecret: "secret"}, nil // Return temporary credentials //return credentials.Credentials{AccessKeyID: "id", AccessKeySecret: "secret", SecurityToken: "token"}, nil }) // Load the default configurations and specify the credential provider and region cfg := oss.LoadDefaultConfig(). WithCredentialsProvider(provider). WithRegion(region) // Create an OSS client client := oss.NewClient(cfg) log.Printf("ossclient: %v", client) }
-
Use the credentials.CredentialsProvider method
package main import ( "context" "log" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss" "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials" ) type CustomerCredentialsProvider struct { // TODO } func NewCustomerCredentialsProvider() CustomerCredentialsProvider { return CustomerCredentialsProvider{} } func (s CustomerCredentialsProvider) GetCredentials(_ context.Context) (credentials.Credentials, error) { // Return long-term credentials return credentials.Credentials{AccessKeyID: "id", AccessKeySecret: "secret"}, nil // Return temporary credentials //return credentials.Credentials{AccessKeyID: "id", AccessKeySecret: "secret", SecurityToken: "token"}, nil } func main() { // Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou region := "cn-hangzhou" // Create a credential provider provider := NewCustomerCredentialsProvider() // Load the default configurations and specify the credential provider and region cfg := oss.LoadDefaultConfig(). WithCredentialsProvider(provider). WithRegion(region) // Create an OSS client client := oss.NewClient(cfg) log.Printf("ossclient: %v", client) }
Use the default credential chain
If you do not specify a method to initialize a Credentials client, the default credential provider chain is used. For more information about the logic for reading default credentials, see Default credential chain.
package main
import (
"context"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
osscred "github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
"github.com/aliyun/credentials-go/credentials"
)
func main() {
// Specify the ID of the region in which the bucket is located based on your business requirements. For example, if the bucket is located in the China (Hangzhou) region, set the region ID to cn-hangzhou
region := "cn-hangzhou"
// If you set the parameter to nil, the default credential provider chain is used and the credentials are automatically obtained
arnCredential, gerr := credentials.NewCredential(nil)
provider := osscred.CredentialsProviderFunc(func(ctx context.Context) (osscred.Credentials, error) {
if gerr != nil {
return osscred.Credentials{}, gerr
}
cred, err := arnCredential.GetCredential()
if err != nil {
return osscred.Credentials{}, err
}
return osscred.Credentials{
AccessKeyID: *cred.AccessKeyId,
AccessKeySecret: *cred.AccessKeySecret,
SecurityToken: *cred.SecurityToken,
}, nil
})
// Load the default configurations and specify the credential provider and region
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(provider).
WithRegion(region)
// Create an OSS client
client := oss.NewClient(cfg)
log.Printf("ossclient: %v", client)
}