All Products
Search
Document Center

Tablestore:AccessKey pair security

Last Updated:Mar 14, 2025

Tablestore supports the V4 signature algorithm to enhance the security of AccessKey pairs. During identity authentication, a derived key created by the V4 signature algorithm is used instead of the actual AccessKey pair, mitigating the risks associated with key exposure. If a derived key is compromised, its impact is confined to resources within a specific region and product for that day, without affecting other products or regions. Moreover, the derived key automatically expires and becomes inactive the following day.

Background information

The V4 signature introduces a novel approach to identity authentication. It is a string that includes the AccessKey secret from an Alibaba Cloud account or RAM user, date, region, and product code, calculated in a specified manner.

With the adoption of the V4 signature, the exposure of a V4 signature does not compromise other regions or products associated with the account, and the validity of a stolen V4 signature is limited to no more than one day. Hence, the V4 signature significantly enhances the security of the AccessKey pair for the account.

Note

Beyond the V4 signature feature, it is crucial to safeguard AccessKey pairs in everyday operations. For instance, set the key as an environment variable in the code before its utilization.

Request flow

  1. The client calculates the AccessKey pair using the V4 signature algorithm to generate a derived key and then initiates a request with this key.

  2. Upon receiving the request, the server uses the derived key to authenticate the user.

  3. Once identity authentication is successful, the server processes the request and returns the result.

    Note

    If identity authentication fails, the server denies the client's access.

  4. The client receives the result processed by the server.

Sample code

Important

The Tablestore Java SDK supports the V4 signature feature starting from version 5.16.1. Ensure you are using an SDK version that supports this feature before implementing the V4 signature.

Initialize with AccessKey

This section demonstrates configuring access credentials using the AccessKey of an Alibaba Cloud account or RAM user as an example. For details on obtaining an AccessKey, see How to obtain an AccessKey.

Below is sample code on using a V4 signature to initialize a Tablestore client, query the list of data tables in an instance, and display them in the Tablestore console.

  • Example 1 requires only the AccessKey. The Tablestore SDK computes and generates the derived key, so manual maintenance of the derived key is unnecessary. The SDK automatically refreshes the key upon expiration.

  • Example 2 involves providing both the AccessKey and the derived key (v4SigningAccessKey). The derived key expires the next day, necessitating regular updates to maintain service access.

import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.core.ResourceManager;
import com.alicloud.openservices.tablestore.core.auth.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import static com.alicloud.openservices.tablestore.core.Constants.PRODUCT;
import static com.alicloud.openservices.tablestore.core.Constants.SIGNING_KEY_SIGN_METHOD;

public class InitClientV4 {
    public static void main(String[] args) {
        // yourRegion Specify the region in which your instance resides. Example: cn-hangzhou
        final String region = "yourRegion";
        // yourInstanceName Specify the name of the instance
        final String instanceName = "yourInstanceName";
        // yourEndpoint Specify the endpoint of the instance
        final String endpoint = "yourEndpoint";
        // Obtain the AccessKey ID and AccessKey secret from the system environment variables
        final String accessKeyId = System.getenv("TABLESTORE_ACCESS_KEY_ID");
        final String accessKeySecret = System.getenv("TABLESTORE_ACCESS_KEY_SECRET");

        {
            /**
             * Example 1: Use the original accessKeyId, accessKeySecret -> First construct {@link DefaultCredentials }, then generate {@link V4Credentials }
             */
            DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret);
            V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
            CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);

            /**
             * using {@link V4Credentials } initialize tableStore client
             */
            SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));

            // do something
            client.listTable().getTableNames().forEach(System.out::println);
            // shutdown tableStore client
            client.shutdown();
        }

        {
            /**
             * Example 2: Directly use accessKey and derived key -> Directly construct {@link V4Credentials }
             */
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
            String signDate = dateFormat.format(new Date()); // signDate format is like "20230527"
            String v4SigningAccessKey = CalculateV4SigningKeyUtil.finalSigningKeyString(accessKeySecret, signDate, region, PRODUCT, SIGNING_KEY_SIGN_METHOD); // derived key
            V4Credentials credentialsV4 = new V4Credentials(accessKeyId, v4SigningAccessKey, region, signDate);
            CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);

            /**
             * using {@link V4Credentials } initialize tableStore client
             */
            SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));

            // do something
            client.listTable().getTableNames().forEach(System.out::println);
            // shutdown tableStore client
            client.shutdown();
        }
    }
}

Use STS to initialize

For details on obtaining temporary STS access credentials, see Using Temporary STS Access Credentials to Access Tablestore.

The following sample code illustrates how to use a V4 signature to initialize a Tablestore client, query the list of data tables in an instance, and display them in the Tablestore console.

  • Example 1 requires only the temporary access credentials of STS. The Tablestore SDK computes and generates the derived key, eliminating the need for manual maintenance. The SDK refreshes the key when it expires.

  • Example 2 requires providing both the temporary access credentials of STS and the derived key (v4SigningAccessKey). Since the derived key expires the following day, you must regularly update it to continue accessing the service.

import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.core.ResourceManager;
import com.alicloud.openservices.tablestore.core.auth.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import static com.alicloud.openservices.tablestore.core.Constants.PRODUCT;
import static com.alicloud.openservices.tablestore.core.Constants.SIGNING_KEY_SIGN_METHOD;

public class InitClientV4 {
    public static void main(String[] args) {
        // yourRegion Specify the region in which your instance resides. Example: cn-hangzhou
        final String region = "yourRegion";
        // yourInstanceName Specify the name of the instance
        final String instanceName = "yourInstanceName";
        // yourEndpoint Specify the endpoint of the instance
        final String endpoint = "yourEndpoint";
        // Obtain the temporary AccessKey ID, temporary AccessKey secret, and security token from the environment variables
        final String accessKeyId = System.getenv("TABLESTORE_ACCESS_KEY_ID");
        final String accessKeySecret = System.getenv("TABLESTORE_ACCESS_KEY_SECRET");
        final String securityToken = System.getenv("TABLESTORE_SESSION_TOKEN");

        {
            /**
             *  Example 1: Use the original accessKeyId, accessKeySecret, securityToken -> First construct {@link DefaultCredentials }, then generate {@link V4Credentials }
             */
            DefaultCredentials credentials = new DefaultCredentials(accessKeyId, accessKeySecret, securityToken);
            V4Credentials credentialsV4 = V4Credentials.createByServiceCredentials(credentials, region);
            CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);

            /**
             * using {@link V4Credentials } initialize tableStore client
             */
            SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));

            // do something
            client.listTable().getTableNames().forEach(System.out::println);
            // shutdown tableStore client
            client.shutdown();
        }
        
        {
            /**
             * Example 2: Directly use accessKey and derived key -> Directly construct {@link V4Credentials }
             */
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
            String signDate = dateFormat.format(new Date());      // signDate format is like "20230527"
            String v4SigningAccessKey = CalculateV4SigningKeyUtil.finalSigningKeyString(accessKeySecret, signDate, region, PRODUCT, SIGNING_KEY_SIGN_METHOD);
            V4Credentials credentialsV4 = new V4Credentials(accessKeyId, v4SigningAccessKey, securityToken, region, signDate);
            CredentialsProvider provider = new DefaultCredentialProvider(credentialsV4);

            /**
             * using {@link V4Credentials } initialize tableStore client
             */
            SyncClient client = new SyncClient(endpoint, provider, instanceName, null, new ResourceManager(null, null));

            // do something
            client.listTable().getTableNames().forEach(System.out::println);
            // shutdown tableStore client
            client.shutdown();
        }
    }
}