An object-level retention policy (ObjectWorm) provides WORM (Write Once, Read Many) compliance retention at the object level. Unlike a bucket-level retention policy (BucketWorm) that uniformly protects all objects in a bucket, ObjectWorm lets you set a unique retention mode and retain until date per object, meeting granular compliance requirements in finance, healthcare, and similar industries.
This feature is currently available by invitation only. To request access, contact technical support.
Overview
After you enable ObjectWorm for a bucket, new objects automatically inherit a default retention policy, and you can set a separate policy for individual existing objects. An object-level policy takes precedence over the bucket default.
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 |
|
Protection scope |
All objects in the bucket. |
Individual objects. |
|
Configuration method |
A bucket-level switch applied uniformly to all objects (both existing and new) in the bucket. |
New objects inherit the default policy. You can set a higher-priority policy for individual objects. |
|
Retention time |
Relative period in days from the object's last modification time. |
Absolute retain until date, accurate to the second. |
|
Mutual exclusion |
BucketWorm and ObjectWorm are mutually exclusive. |
|
Prerequisites
-
Versioning must be enabled on the bucket. After ObjectWorm is enabled, versioning cannot be disabled.
-
The bucket-level retention policy (BucketWorm) must not be enabled on the bucket. ObjectWorm and BucketWorm are mutually exclusive.
Enable ObjectWorm and configure a retention policy
Enable ObjectWorm on a bucket to prevent objects from being deleted or overwritten for a specified period. You can then configure a separate retention policy for each new or existing object.
This action is irreversible. Once enabled, ObjectWorm and versioning cannot be disabled for the bucket.
Console
-
Log on to the OSS console.
-
In the navigation pane on the left, click the Buckets, and then click the name of the target bucket.
-
In the navigation pane on the left, choose Data Protection > Object-Level Retention Policy.
-
Click Enable.
-
Configure the default retention policy:
-
Not Set: No default retention policy is applied. Uploaded objects are not automatically protected.
-
Compliance Mode: No user, including the root user, can delete or overwrite a protected object during the retention period.
-
Retention Period: Set the retention duration and select Days or Year as the unit.
-
-
-
Click Save and confirm by entering the required text in the dialog box.
ossutil
Enable ObjectWorm for the bucket examplebucket and set a default compliance retention policy with a 1-day period.
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 examples enable ObjectWorm and configure a default retention policy by using an SDK.
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 access endpoint.')
parser.add_argument('--mode', help='The retention mode. Valid values: GOVERNANCE, COMPLIANCE.', default='GOVERNANCE')
parser.add_argument('--days', help='The retention period in days (max: 36,500).', type=int)
parser.add_argument('--years', help='The retention period in years (max: 100).', type=int)
def main():
args = parser.parse_args()
# Loading credentials values 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 default retention settings
default_retention = oss.ObjectWormConfigurationRuleDefaultRetention(
mode=args.mode,
days=args.days,
# days and years can only appear once
# years=args.years,
)
# Create rule container
rule = oss.ObjectWormConfigurationRule(
default_retention=default_retention,
)
# Create 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 PutBucketObjectWormConfiguration to enable ObjectWorm. The following example enables ObjectWorm for a bucket with a default compliance retention policy of 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 an object retention policy
Set a retention mode and retain until date for a specific object version. An object-level policy takes precedence over the bucket default.
Console
Configure a retention policy for an existing object from the file list or the file details page.
-
Log on to the OSS console.
-
In the navigation pane on the left, click the Buckets, and then click the name of the target bucket.
-
In the navigation pane on the left, click Object Management, and find the target object.
-
To the right of the target object, choose .
-
In the settings panel, configure the Default Retention Pattern and Retention Period, and then click OK.
In compliance mode, you can only extend an existing retention period, not shorten it.
ossutil
Set a compliance retention policy for exampleobject in examplebucket, with a retain until date of 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 examples configure a retention policy for an object by using an SDK.
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 access endpoint.')
parser.add_argument('--key', help='The name of the object.', required=True)
def main():
args = parser.parse_args()
# Loading credentials values 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 the 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 PutObjectRetention to set a retention policy for an object. Sample request:
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 retention during upload
You can set a retention policy in the request headers when uploading an object, eliminating a separate PutObjectRetention call. This is supported for PutObject, CopyObject, and InitiateMultipartUpload.
Console
-
Log on to the OSS console and navigate to the Object Management page of the target bucket.
-
Click Upload Object.
-
In the Upload panel, expand Advanced Settings and find the Default Retention Policy setting.
-
Select {policyType}, configure the Retention Pattern and Retention Period, and then upload the file.
NoteIf you select {policyType}, the uploaded object automatically inherits the bucket's default retention policy.
ossutil
Use the put-object command with --object-worm-mode and --object-worm-retain-until-date to set a retention policy during upload.
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.000Z
SDK
The following example sets a retention policy when calling PutObject 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 a 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 a 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 a 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"),
RequestCommon: oss.RequestCommon{
Headers: map[string]string{
"x-oss-object-worm-mode": "COMPLIANCE",
"x-oss-object-worm-retain-until-date": "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 PutObject to upload an object and set 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
-
Header restrictions: When ObjectWorm is not enabled, API requests must not include these headers:
x-oss-bypass-governance-retentionorx-amz-bypass-governance-retention. -
Irreversible feature: Once enabled, ObjectWorm cannot be disabled. Evaluate your business needs before enabling this feature.
-
Scope of the default policy: A default retention policy applies only to new objects, not existing ones. Use the PutObjectRetention operation to set retention for existing objects individually.
-
Object policy precedence: An object's own retention policy takes precedence over the bucket default.
-
Retention period extension: In compliance mode, an existing retain until date can only be extended, not shortened.
-
Object deletion: Protected objects cannot be deleted during their retention period.
-
Delete markers: ObjectWorm does not protect delete markers — they can be created and cleared as usual. However, you cannot delete an object version within its retention period.
-
Parts: ObjectWorm does not protect parts generated from multipart uploads.
-
Data replication: Replication does not copy ObjectWorm settings. The destination object follows the destination bucket's ObjectWorm configuration, which must be set separately.
-
Lifecycle management: Lifecycle rules can still transition objects to other storage classes. However, objects within their retention period are not deleted by expiration rules.
-
Log shipping: Avoid shipping log files to an ObjectWorm-enabled bucket. Locked log files cannot be automatically deleted, increasing storage costs.
-
Append Object: The Append Object operation is not supported on buckets with a default object-level retention policy.
-
Object ACL: Object ACLs cannot be set for objects within their ObjectWorm retention period.