ObjectWorm provides object-level WORM (Write Once Read Many) compliance retention capabilities. Unlike BucketWorm (bucket-level retention policy), which applies a uniform protection policy to all objects in a bucket, ObjectWorm lets you set an independent retention mode and retain until date for each object. This meets the fine-grained compliance storage requirements of industries such as finance and healthcare.
This feature is currently available by invitation only. To request access, contact technical support. This feature is available only in the China (Hangzhou), China (Chengdu), China (Shenzhen), China (Guangzhou), China (Qingdao), China (Beijing), China (Hohhot), China (Heyuan), China (Hong Kong), Germany (Frankfurt), Japan (Tokyo), South Korea (Seoul), Singapore, Malaysia (Kuala Lumpur), Indonesia (Jakarta), Philippines (Manila), Thailand (Bangkok), Saudi Arabia (Riyadh), and UAE (Dubai) regions.
Overview
After you enable ObjectWorm on a bucket, you can automatically apply a default retention policy to newly uploaded objects. You can also configure an independent retention policy for individual existing objects. An object-level policy takes precedence over the bucket's default policy.
Currently, only compliance mode is supported. In compliance mode, no user, including the root user, can delete or overwrite a protected object version during its retention period. The retain until date can only be extended, not shortened.
BucketWorm vs. ObjectWorm
Item | BucketWorm | ObjectWorm |
Scope | All objects within a bucket | Individual object level |
Configuration method | A bucket-level switch that applies a uniform policy to all objects in the bucket, including both existing and new objects. | A bucket-level switch with an optional default policy. New objects inherit the default policy, but you can also configure an independent policy with a higher priority. You must configure policies for existing objects individually. |
Retention period | Relative retention period in days, calculated as the object's last modified time plus the number of retention days. | An absolute retain until date ( |
Mutual exclusion | BucketWorm and ObjectWorm are mutually exclusive. | |
Prerequisites
Versioning is enabled for the bucket. ObjectWorm requires versioning and cannot be enabled if versioning is disabled. After you enable ObjectWorm, you cannot disable versioning.
BucketWorm (bucket-level retention policy) is not enabled for the bucket. ObjectWorm and BucketWorm are mutually exclusive and cannot be enabled at the same time.
Enable ObjectWorm and configure a retention policy
Enable an object-level retention policy on a bucket to prevent specific objects from being deleted or overwritten for a certain period. After the feature is enabled, you can configure an independent retention policy for a new or an existing object, offering greater flexibility.
This operation cannot be reversed. Once ObjectWorm is enabled, you cannot disable ObjectWorm or versioning. Proceed with caution.
Console
Log on to the OSS console.
In the navigation pane on the left, click Bucket List and then click the name of the target bucket.
In the navigation pane on the left, choose .
Click Enable.
In the Default Retention Policy section, configure the following parameters as needed:
Do not set for now: No default retention policy is set. Objects uploaded to the bucket are not automatically protected by a default retention rule.
Compliance Mode: In compliance mode, no user, including the root user, can delete or overwrite an object during its retention period.
Retention Period: Enter a number for the retention duration and select the unit as Days or Years.
Click Save. In the confirmation dialog box, enter the confirmation message to complete the process.
ossutil
Enable an object-level retention policy for the bucket named examplebucket, set the retention mode to compliance mode, and specify a default retention period of 1 day.
Using an XML configuration file named object-worm-configuration.xml with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<ObjectWormConfiguration>
<ObjectWormEnabled>Enabled</ObjectWormEnabled>
<Rule>
<DefaultRetention>
<Mode>COMPLIANCE</Mode>
<Days>1</Days>
</DefaultRetention>
</Rule>
</ObjectWormConfiguration>Example command:
ossutil api put-bucket-object-worm-configuration --bucket examplebucket --object-worm-configuration file://object-worm-configuration.xmlSDK
The following code examples show how to use an SDK to enable ObjectWorm and configure a default retention policy.
Python
import argparse
import alibabacloud_oss_v2 as oss
parser = argparse.ArgumentParser(description="put bucket object worm configuration sample")
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The OSS endpoint. If not specified, the SDK determines the endpoint based on the region.')
parser.add_argument('--mode', help='The retention mode. Valid values: GOVERNANCE, COMPLIANCE', default='GOVERNANCE')
parser.add_argument('--days', help='Object-level retention policy days (max 36500)', type=int)
parser.add_argument('--years', help='Bucket object level retention policy years (max 100)', type=int)
def main():
args = parser.parse_args()
# Loading credentials from the environment variables
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# Using the SDK's default configuration
cfg = oss.config.load_default()
cfg.credentials_provider = credentials_provider
cfg.region = args.region
if args.endpoint is not None:
cfg.endpoint = args.endpoint
client = oss.Client(cfg)
# Create a default retention rule
default_retention = oss.ObjectWormConfigurationRuleDefaultRetention(
mode=args.mode,
days=args.days,
# Specify either days or years, but not both.
# years=args.years,
)
# Create the rule
rule = oss.ObjectWormConfigurationRule(
default_retention=default_retention,
)
# Create the WORM configuration
config = oss.ObjectWormConfiguration(
object_worm_enabled='Enabled',
rule=rule,
)
result = client.put_bucket_object_worm_configuration(oss.PutBucketObjectWormConfigurationRequest(
bucket=args.bucket,
object_worm_configuration=config,
))
print(f'status code: {result.status_code},'
f' request id: {result.request_id},'
)
if __name__ == "__main__":
main()Go
package main
import (
"context"
"flag"
"log"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
var (
region string
bucketName string
)
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
}
func main() {
flag.Parse()
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
client := oss.NewClient(cfg)
request := &oss.PutBucketObjectWormConfigurationRequest{
Bucket: oss.Ptr(bucketName),
ObjectWormConfiguration: &oss.ObjectWormConfiguration{
ObjectWormEnabled: oss.Ptr("Enabled"),
Rule: &oss.ObjectWormRule{
DefaultRetention: &oss.ObjectWormDefaultRetention{
Mode: oss.Ptr("COMPLIANCE"),
Days: oss.Ptr(int32(1)),
},
},
},
}
result, err := client.PutBucketObjectWormConfiguration(context.TODO(), request)
if err != nil {
log.Fatalf("failed to put bucket object worm configuration %v", err)
}
log.Printf("put bucket object worm configuration result:%#v\n", result)
}Java
import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.OSSClientBuilder;
import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.models.*;
public class PutBucketObjectWormConfigurationDemo {
public static void main(String[] args) {
CredentialsProvider provider = new EnvironmentVariableCredentialsProvider();
OSSClient client = OSSClient.newBuilder()
.credentialsProvider(provider)
.region("cn-hangzhou")
.build();
try {
ObjectWormConfigurationDefaultRetention defaultRetention = ObjectWormConfigurationDefaultRetention.newBuilder()
.mode("COMPLIANCE")
.days(1)
.build();
ObjectWormConfigurationRule rule = ObjectWormConfigurationRule.newBuilder()
.defaultRetention(defaultRetention)
.build();
ObjectWormConfiguration objectWormConfiguration = ObjectWormConfiguration.newBuilder()
.objectWormEnabled("Enabled")
.rule(rule)
.build();
PutBucketObjectWormConfigurationRequest request = PutBucketObjectWormConfigurationRequest.newBuilder()
.bucket("examplebucket")
.objectWormConfiguration(objectWormConfiguration)
.build();
PutBucketObjectWormConfigurationResult result = client.putBucketObjectWormConfiguration(request);
System.out.printf("Status code:%d, request id:%s%n",
result.statusCode(), result.requestId());
} catch (Exception e) {
System.out.printf("error: %s%n", e);
} finally {
client.close();
}
}
}API
Call the PutBucketObjectWormConfiguration operation to enable ObjectWorm. The following is a sample request body. This example enables ObjectWorm for a bucket and sets the default retention policy to compliance mode for 1 day.
PUT /?objectWorm HTTP/1.1
Date: Thu, 17 Mar 2026 11:18:32 GMT
Content-Length: 188
Content-Type: application/xml
Content-MD5: B2M2Y8AsgTpgAmY7PhC****
Host: examplebucket.oss-cn-hangzhou.aliyuncs.com
Authorization: OSS4-HMAC-SHA256 Credential=LTAI********************/20260317/cn-hangzhou/oss/aliyun_v4_request,AdditionalHeaders=content-length,Signature=a7c3554c729d****
<?xml version="1.0" encoding="UTF-8"?>
<ObjectWormConfiguration>
<ObjectWormEnabled>Enabled</ObjectWormEnabled>
<Rule>
<DefaultRetention>
<Mode>COMPLIANCE</Mode>
<Days>1</Days>
</DefaultRetention>
</Rule>
</ObjectWormConfiguration>Configure a retention policy for an object
Configure an independent retention policy for a specific object version, including the retention mode and retention period. An object-level policy takes precedence over the bucket's default retention policy.
Console
You can configure a retention policy for an uploaded object on the Files page or the object's details page.
Log on to the OSS console.
In the navigation pane on the left, click Bucket List and then click the name of the target bucket.
In the navigation pane on the left, click Files and find the target object.
In the row of the target object, choose .
In the panel that appears, configure the Retention Mode and Retention Period, and then click OK.
In compliance mode, you can extend but not shorten the retention period for an object that already has a retention policy.
ossutil
Configure a compliance mode retention policy for the object exampleobject in the bucket examplebucket. Set the retain until date to 2026-12-31T00:00:00.000Z.
Using an XML configuration file named retention.xml with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<Retention>
<Mode>COMPLIANCE</Mode>
<RetainUntilDate>2026-12-31T00:00:00.000Z</RetainUntilDate>
</Retention>Example command:
ossutil api put-object-retention --bucket examplebucket --key exampleobject --retention file://retention.xmlSDK
The following code examples show how to use an SDK to configure a retention policy for an object.
Python
import argparse
import alibabacloud_oss_v2 as oss
from datetime import datetime, timedelta, timezone
parser = argparse.ArgumentParser(description="put object retention sample")
parser.add_argument('--region', help='The region in which the bucket is located.', required=True)
parser.add_argument('--bucket', help='The name of the bucket.', required=True)
parser.add_argument('--endpoint', help='The OSS endpoint. If not specified, the SDK determines the endpoint based on the region.')
parser.add_argument('--key', help='The object key.', required=True)
def main():
args = parser.parse_args()
# Loading credentials from the environment variables
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
# Using the SDK's default configuration
cfg = oss.config.load_default()
cfg.credentials_provider = credentials_provider
cfg.region = args.region
if args.endpoint is not None:
cfg.endpoint = args.endpoint
client = oss.Client(cfg)
# Calculate retain until date (1 day from now) in ISO 8601 format
# Use UTC time (recommended for OSS)
retain_until_date = datetime.now(timezone.utc) + timedelta(days=1)
retain_until_iso = retain_until_date.strftime('%Y-%m-%dT%H:%M:%S.000Z')
# Create retention configuration
retention_config = oss.Retention(
mode=oss.ObjectRetentionModeType.COMPLIANCE,
retain_until_date=retain_until_iso,
)
# Set object retention
result = client.put_object_retention(oss.PutObjectRetentionRequest(
bucket=args.bucket,
key=args.key,
retention=retention_config,
))
print(f'status code: {result.status_code},'
f' request id: {result.request_id}')
if __name__ == "__main__":
main()Go
package main
import (
"context"
"flag"
"log"
"time"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
var (
region string
bucketName string
objectName string
)
func init() {
flag.StringVar(®ion, "region", "", "The region in which the bucket is located.")
flag.StringVar(&bucketName, "bucket", "", "The name of the bucket.")
flag.StringVar(&objectName, "object", "", "The name of the object.")
}
func main() {
flag.Parse()
if len(region) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, region required")
}
if len(bucketName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, bucket name required")
}
if len(objectName) == 0 {
flag.PrintDefaults()
log.Fatalf("invalid parameters, object name required")
}
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion(region)
client := oss.NewClient(cfg)
date := time.Now().UTC().Add(5 * time.Hour).Format("2006-01-02T15:04:05.000Z")
putRequest := &oss.PutObjectRetentionRequest{
Bucket: oss.Ptr(bucketName),
Key: oss.Ptr(objectName),
Retention: &oss.ObjectWormRetention{
Mode: oss.Ptr("COMPLIANCE"),
RetainUntilDate: oss.Ptr(date),
},
}
putResult, err := client.PutObjectRetention(context.TODO(), putRequest)
if err != nil {
log.Fatalf("failed to put object retention %v", err)
}
log.Printf("put object retention result:%#v\n", putResult)
}Java
import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.OSSClientBuilder;
import com.aliyun.sdk.service.oss2.credentials.CredentialsProvider;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.models.*;
public class PutObjectRetentionDemo {
public static void main(String[] args) {
CredentialsProvider provider = new EnvironmentVariableCredentialsProvider();
OSSClient client = OSSClient.newBuilder()
.credentialsProvider(provider)
.region("cn-hangzhou")
.build();
try {
Retention retention = Retention.newBuilder()
.mode("COMPLIANCE")
.retainUntilDate("2026-12-31T00:00:00.000Z")
.build();
PutObjectRetentionRequest request = PutObjectRetentionRequest.newBuilder()
.bucket("examplebucket")
.key("exampleobject")
.retention(retention)
.build();
PutObjectRetentionResult result = client.putObjectRetention(request);
System.out.printf("Status code:%d, request id:%s%n",
result.statusCode(), result.requestId());
} catch (Exception e) {
System.out.printf("error: %s%n", e);
} finally {
client.close();
}
}
}API
Call the PutObjectRetention operation to configure a retention policy for an object. The following is a sample request body.
PUT /exampleobject?retention&versionId=CAEQNhiBgMDJgZCA0BYiIDc4MGZj**** HTTP/1.1
Date: Thu, 17 Mar 2026 11:18:32 GMT
Content-MD5: B2M2Y8AsgTpgAmY7PhC****
Content-Type: application/xml
Content-Length: 162
Host: examplebucket.oss-cn-hangzhou.aliyuncs.com
Authorization: OSS4-HMAC-SHA256 Credential=LTAI********************/20260317/cn-hangzhou/oss/aliyun_v4_request,Signature=****
<Retention>
<Mode>COMPLIANCE</Mode>
<RetainUntilDate>2026-10-11T00:00:00.000Z</RetainUntilDate>
</Retention>Configure a retention policy during upload
When you upload an object, you can directly configure a retention policy in the request headers, eliminating the need to call the PutObjectRetention operation separately. This is supported for the PutObject, CopyObject, and InitiateMultipartUpload operations.
Console
Log on to the OSS console and navigate to the Files page of the target bucket.
Click Upload File.
In the upload panel, expand Advanced Options and find the Default Retention Policy setting.
Select Set Individually, configure the Retention Mode and Retention Period, and then upload the object.
NoteIf you select Inherit Bucket's Default Policy, the uploaded object automatically uses the bucket's default retention policy.
ossutil
When you use the API-level command of ossutil put-object to upload an object, use the --object-worm-mode and --object-worm-retain-until-date parameters to specify the retention policy.
ossutil api put-object --bucket examplebucket --key exampleobject --body file://localfile.txt --object-worm-mode COMPLIANCE --object-worm-retain-until-date 2026-10-11T00:00:00.000ZSDK
The following code examples show how to configure a retention policy when calling the PutObject operation to upload an object.
import alibabacloud_oss_v2 as oss
credentials_provider = oss.credentials.EnvironmentVariableCredentialsProvider()
cfg = oss.config.load_default()
cfg.credentials_provider = credentials_provider
cfg.region = 'cn-hangzhou'
client = oss.Client(cfg)
# Upload the object and set its retention policy: compliance mode, retain until October 11, 2026
result = client.put_object(oss.PutObjectRequest(
bucket='examplebucket',
key='exampleobject',
body='Hello OSS',
object_worm_mode='COMPLIANCE',
object_worm_retain_until_date='2026-10-11T00:00:00.000Z',
))
print(f'status code: {result.status_code}')import com.aliyun.sdk.service.oss2.OSSClient;
import com.aliyun.sdk.service.oss2.credentials.EnvironmentVariableCredentialsProvider;
import com.aliyun.sdk.service.oss2.models.*;
import com.aliyun.sdk.service.oss2.transport.BinaryData;
public class UploadWithRetention {
public static void main(String[] args) {
OSSClient client = OSSClient.newBuilder()
.credentialsProvider(new EnvironmentVariableCredentialsProvider())
.region("cn-hangzhou")
.build();
try {
// Upload the object and set its retention policy: compliance mode, retain until October 11, 2026
PutObjectResult result = client.putObject(PutObjectRequest.newBuilder()
.bucket("examplebucket")
.key("exampleobject")
.body(BinaryData.fromString("Hello OSS"))
.header("x-oss-object-worm-mode", "COMPLIANCE")
.header("x-oss-object-worm-retain-until-date", "2026-10-11T00:00:00.000Z")
.build());
System.out.printf("status code: %d%n", result.statusCode());
} finally {
client.close();
}
}
}package main
import (
"context"
"fmt"
"strings"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss"
"github.com/aliyun/alibabacloud-oss-go-sdk-v2/oss/credentials"
)
func main() {
cfg := oss.LoadDefaultConfig().
WithCredentialsProvider(credentials.NewEnvironmentVariableCredentialsProvider()).
WithRegion("cn-hangzhou")
client := oss.NewClient(cfg)
// Upload the object and set its retention policy: compliance mode, retain until October 11, 2026
request := &oss.PutObjectRequest{
Bucket: oss.Ptr("examplebucket"),
Key: oss.Ptr("exampleobject"),
Body: strings.NewReader("Hello OSS"),
ObjectWormMode: oss.Ptr("COMPLIANCE"),
ObjectWormRetainUntilDate: oss.Ptr("2026-10-11T00:00:00.000Z"),
}
_, err := client.PutObject(context.TODO(), request)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Object uploaded with retention successfully")
}API
Call the PutObject operation to upload an object and configure its retention policy in the request headers.
PUT /exampleobject HTTP/1.1
Host: examplebucket.oss-cn-hangzhou.aliyuncs.com
x-oss-object-worm-mode: COMPLIANCE
x-oss-object-worm-retain-until-date: 2026-10-11T00:00:00.000Z
Content-MD5: B2M2Y8AsgTpgAmY7PhC****
Authorization: SignatureValue
[Object Content]Usage notes
Cannot be disabled: Once ObjectWorm is enabled for a bucket, the feature cannot be disabled unless you close your Alibaba Cloud account. Fully assess your business needs before you enable this feature.
Default policy scope: The default retention policy applies only to new objects, not existing ones. To protect an existing object, you must call the PutObjectRetention operation to set its policy.
Object policy priority: If an object has an independent retention policy, that policy takes precedence over the bucket's default retention policy.
Retention period extension: In compliance mode, the specified retain until date (
RetainUntilDate) can only be extended, not shortened.Object deletion: You cannot delete an object that is within its ObjectWorm retention period.
Delete markers: Delete markers are not protected by ObjectWorm and can be created and cleared normally. However, an object version that is within its retention period cannot be deleted.
Parts: Parts from multipart uploads are not protected by ObjectWorm.
Data replication: An object's retention policy is not copied during replication; instead, the destination object inherits the ObjectWorm settings from the destination bucket.
Lifecycle management: After ObjectWorm is enabled, transition operations in lifecycle management rules are not affected. However, expiration rules will not delete objects that are within their retention period.
Log storage: We recommend that you do not store log files in a bucket with ObjectWorm enabled. Older log files may not be automatically deleted if they are within their retention period, which can increase storage costs.
Append uploads: If a default ObjectWorm retention policy is configured for a bucket, you cannot use the append upload method. The AppendObject operation does not support setting ObjectWorm policies.
Object ACLs: You cannot change the ACL of an object during its ObjectWorm retention period.