All Products
Search
Document Center

Object Storage Service:Retention policy (WORM)

Last Updated:Feb 19, 2025

The Write Once Read Many (WORM) feature of retention policies in Object Storage Service (OSS) prevents users from modifying or deleting data. If you want to ensure that no one, including resource owners, can modify or delete objects in a bucket for a certain period, configure a retention policy for that bucket. During the specified retention period, you can only upload or read objects from the bucket. Modifying or deleting objects is permitted only after the retention period has ended.

Prerequisites

  • Regions such as China (Hangzhou), China (Shanghai), and Hong Kong (China), among others, support the configuration of retention policies.

  • Ensure that versioning is disabled for the bucket you want to configure with a retention policy. For more information about versioning, see Introduction to versioning.

Scenarios

The WORM feature provided by OSS retention policies assists enterprises in meeting regulatory and compliance requirements from bodies such as the U.S. Securities and Exchange Commission (SEC) and the Financial Industry Regulatory Authority (FINRA). It is ideal for sectors including finance, insurance, healthcare, and securities, and for scenarios like Multi-Layer Protection Scheme (MLPS) audit of log data.

Note

OSS has been audited and certified by Cohasset Associates to meet compliance requirements such as SEC Rule 17a-4(f), FINRA 4511, and CFTC 1.31. For more information, see OSS Cohasset Assessment Report.

Notes

  • Currently, retention policies can only be configured at the bucket level.

  • We recommend that you do not enable OSS-HDFS and configure retention policies for a bucket at the same time.

    For example, OSS-HDFS is enabled for a bucket for which a retention policy is configured. When you use methods supported by OSS-HDFS to delete an object from the .dlsdata/ directory, you receive a message that indicates the object is deleted. However, OSS actually retains the object if the deletion occurs within the retention period and cannot recognize and delete the object after the retention period ends.

  • During the retention period, you can convert the storage class of objects in the bucket by configuring lifecycle rules to reduce storage costs while ensuring compliance.

Rules

  • Rules for modifications to take effect

    After a time-based retention policy is created, it defaults to the InProgress state and is valid for 24 hours, during which the bucket resources are protected.

    • Within 24 hours of creating the retention policy

      • If the retention policy is not locked within 24 hours, the bucket owner and authorized users can delete the policy.

      • If the retention policy is locked within 24 hours, you cannot delete the policy or shorten the retention period. You can only extend the retention period, and the data in the bucket is protected. Attempts to delete or modify the data will result in a 409 FileImmutable error message from OSS.

    • 24 hours after the retention policy is created

      If the retention policy is not locked after 24 hours, it becomes invalid, and you can delete the policy.

  • Rules for deletion

    • A time-based retention policy is a metadata attribute of a bucket. Deleting a bucket also deletes its retention policy.

    • If the retention policy is not locked within 24 hours after its creation, the bucket owner and authorized users can delete the policy.

    • If a bucket contains objects protected within the retention period, you cannot delete the bucket or the retention policy.

  • Examples

    Assume you create a 30-day retention policy for a bucket on June 01, 2022, and lock it after creation. You upload file1.txt, file2.txt, and file3.txt to the bucket at different times. The upload and expiration dates are as follows:

    Object name

    Upload date

    Expiration date

    file1.txt

    April 01, 2022

    April 30, 2022

    file2.txt

    June 01, 2022

    June 30, 2022

    file3.txt

    September 01, 2022

    September 30, 2022

Operations

Use the OSS console

  1. Create a retention policy.

    1. Log on to the OSS console.

    2. Click Buckets, and then click the name of the target bucket.

    3. In the left-side navigation pane, choose Content Security > Retention Policy.

    4. On the Retention Policy page, click Create Policy.

    5. In the Create Policy dialog box, specify the Retention Period.

      Note

      The retention period is measured in days. Valid values range from 1 to 25550.

    6. Click OK.

      Note

      The status of the retention policy is InProgress. It remains in this state for 24 hours, during which the bucket's resources are protected. If you decide not to retain the policy, you can delete it within this time frame.

  2. Lock the retention policy.

    1. Click Lock.

    2. In the dialog box that appears, click OK.

      Important

      Once the retention policy is locked, you cannot modify or delete it. You also cannot modify or delete data in the bucket during the retention period.

  3. (Optional) Modify the retention period.

    1. Click Edit.

    2. In the dialog box that appears, modify the retention period.

      Important

      You can only extend the retention period. Shortening it is not permitted.

Use Alibaba Cloud SDKs

The following sample code shows how to configure retention policies using OSS SDKs for commonly used programming languages. For details on configuring retention policies with other SDKs, see ```html SDK overview.

Java

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.common.auth.*;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.InitiateBucketWormRequest;
import com.aliyun.oss.model.InitiateBucketWormResult;

public class Demo {

    public static void main(String[] args) throws Exception {
        // In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
        String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
        // Obtain access credentials from 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. 
        EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
        // Specify the name of the bucket. Example: examplebucket. 
        String bucketName = "examplebucket";
        // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. 
        String region = "cn-hangzhou";

        // Create an OSSClient instance. 
        ClientBuilderConfiguration clientBuilderConfiguration = new ClientBuilderConfiguration();
        clientBuilderConfiguration.setSignatureVersion(SignVersion.V4);        
        OSS ossClient = OSSClientBuilder.create()
        .endpoint(endpoint)
        .credentialsProvider(credentialsProvider)
        .clientConfiguration(clientBuilderConfiguration)
        .region(region)               
        .build();

        try {
            // Create an InitiateBucketWormRequest object. 
            InitiateBucketWormRequest initiateBucketWormRequest = new InitiateBucketWormRequest(bucketName);
            // Set the retention period to 1 day. 
            initiateBucketWormRequest.setRetentionPeriodInDays(1);

            // Create a retention policy. 
            InitiateBucketWormResult initiateBucketWormResult = ossClient.initiateBucketWorm(initiateBucketWormRequest);

            // Display the ID of the retention policy. 
            String wormId = initiateBucketWormResult.getWormId();
            System.out.println(wormId);
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }
}

PHP

<?php
if (is_file(__DIR__ . '/../autoload.php')) {
    require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
    require_once __DIR__ . '/../vendor/autoload.php';
}

use OSS\Credentials\EnvironmentVariableCredentialsProvider;
use OSS\OssClient;
use OSS\CoreOssException;

// Obtain access credentials from 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 = new EnvironmentVariableCredentialsProvider();
// In this example, the endpoint of the China (Hangzhou) region is used. Specify your actual endpoint. 
$endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
$bucket= "<yourBucketName>";

$config = array(
        "provider" => $provider,
        "endpoint" => $endpoint,
        "signatureVersion" => OssClient::OSS_SIGNATURE_VERSION_V4,
        "region"=> "cn-hangzhou"
    );
    $ossClient = new OssClient($config);

try {
    // Create a retention policy and set the retention period to 30 days. 
    $wormId = $ossClient->initiateBucketWorm($bucket, 30);

    // Query the ID of the retention policy. 
    print($wormId);
} catch (OssException $e) {
    printf(__FUNCTION__ . ": FAILED\n");
    printf($e->getMessage() . "\n");
    return;
}

print(__FUNCTION__ . ": OK" . "\n"); 

Node.js

const OSS = require('ali-oss');

const client = new OSS({
  // Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to oss-cn-hangzhou. 
  region: 'yourregion',
  // Obtain access credentials from 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. 
  accessKeyId: process.env.OSS_ACCESS_KEY_ID,
  accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET,  
  authorizationV4: true,
  // Specify the name of your bucket.
  bucket: 'yourBucketName',
});
// Create a retention policy. 
async function initiateBucketWorm() {
 // Specify the name of the bucket. 
  const bucket = 'yourbucketname'
  // Specify the retention period of the retention policy. 
  const days = '<Retention Days>'
    const res = await client.initiateBucketWorm(bucket, days)
  console.log(res.wormId)
}

initiateBucketWorm()

Python

# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
# Obtain access credentials from 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. 
auth = oss2.ProviderAuthV4(EnvironmentVariableCredentialsProvider())

# Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. 
endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
# Specify the ID of the region that maps to the endpoint. Example: cn-hangzhou. This parameter is required if you use the signature algorithm V4.
region = "cn-hangzhou"

# Specify the name of your bucket.
bucket = oss2.Bucket(auth, endpoint, "yourBucketName", region=region)

# Create a retention policy and set the retention period to 1 day. 
result = bucket.init_bucket_worm(1)
# Query the ID of the retention policy. 
print(result.worm_id)

Go

package main

import (
	"log"

	"github.com/aliyun/aliyun-oss-go-sdk/oss"
)

func main() {
	// Obtain access credentials from 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, err := oss.NewEnvironmentVariableCredentialsProvider()
	if err != nil {
		log.Fatalf("Error creating credentials provider: %v", err)
	}

	// Create an OSSClient instance.
	// Set yourEndpoint to the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set yourEndpoint to https://oss-cn-hangzhou.aliyuncs.com. Specify your actual endpoint.
	// Specify the region in which the bucket is located. For example, if your bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. Specify your actual region.
	clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
	clientOptions = append(clientOptions, oss.Region("yourRegion"))
	// Specify the signature version.
	clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
	client, err := oss.New("yourEndpoint", "", "", clientOptions...)
	if err != nil {
		log.Fatalf("Error creating OSS client: %v", err)
	}

	// Specify the name of the bucket for which you want to create a retention policy.
	bucketName := "<yourBucketName>"

	// Set the retention period to 60 days.
	result, err := client.InitiateBucketWorm(bucketName, 60)
	if err != nil {
		log.Fatalf("Error initiating bucket WORM: %v", err)
	}

	log.Println("WORM policy initiated successfully:", result)
}

C++

#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;

int main(void)
{
    /* Initialize information about the account that is used to access OSS. */
            
    /* Specify the endpoint of the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the endpoint to https://oss-cn-hangzhou.aliyuncs.com. */
    std::string Endpoint = "yourEndpoint";
    /* Specify the region in which the bucket is located. For example, if the bucket is located in the China (Hangzhou) region, set the region to cn-hangzhou. */
    std::string Region = "yourRegion";
    /* Specify the name of the bucket. Example: examplebucket. */
    std::string BucketName = "examplebucket";

      /* Initialize resources, such as network resources. */
      InitializeSdk();

      ClientConfiguration conf;
      conf.signatureVersion = SignatureVersionType::V4;
      /* Obtain access credentials from 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. */
    auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
    OssClient client(Endpoint, credentialsProvider, conf);
    client.SetRegion(Region);
  
      /* Create a retention policy and set the retention period to 10 days. */
      auto outcome = client.InitiateBucketWorm(InitiateBucketWormRequest(BucketName, 10));

      if (outcome.isSuccess()) {      
            std::cout << " InitiateBucketWorm success " << std::endl;
            std::cout << "WormId:" << outcome.result().WormId() << std::endl;
      }
      else {
        /* Handle exceptions. */
        std::cout << "InitiateBucketWorm fail" <<
        ",code:" << outcome.error().Code() <<
        ",message:" << outcome.error().Message() <<
        ",requestId:" << outcome.error().RequestId() << std::endl;
        return -1;
      }

      /* Release resources, such as network resources. */
      ShutdownSdk();
      return 0;
}

Use the ossutil command line tool

The ossutil command line tool can be used to create a WORM policy. For instructions on installing ossutil, see Install ossutil.

The following command sets up a new WORM policy for the examplebucket bucket with a 365-day retention period.

ossutil api initiate-bucket-worm --bucket examplebucket --initiate-worm-configuration "{\"RetentionPeriodInDays\":\"365\"}"

For more details on the command, see initiate-bucket-worm.

Related API operations

For a high level of customization, you can directly call RESTful APIs. To do so, you must include signature calculation in your code. For more information, see InitiateBucketWorm.

FAQ

What are the benefits of retention policies?

Retention policies ensure compliant data storage by preventing data from being deleted or modified during the retention period. This is in contrast to data protected by RAM policies or bucket policies, which may still be modified or deleted.

When do I need to configure a retention policy?

A retention policy is recommended for buckets containing important data such as medical records, technical documents, and contracts, which must be stored for extended periods without allowing modifications or deletions.

Can I cancel a retention policy?

The ability to cancel a retention policy depends on its status:

  • Not locked: The bucket owner and authorized users can delete the policy.

  • Locked: The policy cannot be deleted by anyone.

Can I configure a retention policy for specific objects in a bucket?

Retention policies can only be applied to buckets as a whole. It is not possible to configure them for individual folders or objects within a bucket.

How do I calculate the retention period of an object?

The retention period for an object is determined by the object's last modified time and the duration of the retention policy. For instance, if a retention policy for Bucket A is set for 10 days and an object was last modified on February 15, 2022, the object's retention period will end on February 25, 2022.

How do I delete a bucket for which a retention policy is configured?

  • If the bucket is empty, you can delete it.

  • If the bucket contains non-protected objects, delete all objects before attempting to delete the bucket.

  • If the bucket contains objects under protection, the bucket cannot be deleted.

If my Alibaba Cloud account has overdue payments for OSS, are objects that are protected within the retention period of the retention policy retained?

In the event of overdue payments on your Alibaba Cloud account, Alibaba Cloud will enforce the data retention policy according to the terms of the contract.

Can an authorized RAM user configure a retention policy?

The retention policy API is accessible and supports RAM policies. Authorized RAM users can create or delete retention policies using the console, API, or SDKs.