对象级别保留策略(Object Worm)

更新时间:
复制为 MD 格式

对象级别保留策略(ObjectWorm)提供对象粒度的WORM(Write Once Read Many)合规保留能力。与 Bucket级别保留策略(BucketWorm)Bucket内所有Object统一保护不同,ObjectWorm支持为每个Object设置独立的保留模式和保留截止日期,满足金融、医疗等行业的精细化合规存储需求。

重要

该功能目前为邀测功能,如需使用,请联系技术支持申请开通。当前仅支持华东1(杭州)、西南1(成都)、华南1(深圳)、华南3(广州)、华北1(青岛)、华北2(北京)、华北5(呼和浩特)、华南2(河源)、中国香港、德国(法兰克福)、日本(东京)、韩国(首尔)、新加坡、马来西亚(吉隆坡)、印度尼西亚(雅加达)、菲律宾(马尼拉)、泰国(曼谷)、沙特(利雅得)、阿联酋(迪拜)地域。

功能概述

Object WormBucket级别开启后,支持为每个新上传的Object自动应用默认保留策略,也支持为单个已上传的Object设置独立的保留策略。Object级别的策略优先级高于Bucket默认策略。

当前仅支持合规模式(COMPLIANCE),即在保留期限内任何用户(包括根用户)都不能删除或覆盖写受保护的Object版本,保留截止日期只能延长不能缩短。

Bucket WormObject Worm

对比项

Bucket级别保留策略(BucketWorm)

对象级别保留策略(ObjectWorm)

保护范围

整个存储空间内所有对象

单个对象粒度

配置方式

Bucket级开关,对Bucket内所有文件(存量和增量)统一生效

Bucket级开关 + 可选默认策略。新上传文件继承默认策略,也可配置独立的保留策略(优先级更高)。存量文件需单独配置。

保留时间

相对保留天数(基于对象最后修改时间 + 保留天数)

绝对保留截止日期(RetainUntilDate),精确到秒

互斥关系

Bucket WormObject Worm不支持同时开启,二者互斥。

前提条件

  • Bucket已开启版本控制。Object Worm强依赖版本控制功能,未开启版本控制时无法开启Object Worm。开启Object Worm后,版本控制无法关闭。

  • Bucket未开启Bucket级别保留策略(BucketWorm)。Object WormBucket Worm互斥,不支持同时开启。

开启Object Worm并配置保留策略

Bucket上开启对象级别保留策略,以防止特定文件在一定时间内被删除或被覆盖写。功能开启后,可针对单个新上传的对象或者单个已上传的对象单独配置保留策略,使用更加灵活。

警告

此操作不可逆,开启后无法关闭Object Worm功能,且版本控制也无法关闭。请确认后再操作。

控制台

  1. 登录OSS管理控制台

  2. 在左侧导航栏,单击Bucket列表,然后单击目标Bucket名称。

  3. 在左侧导航栏,选择数据保护 > 对象级别保留策略

  4. 单击开启按钮。

  5. 在默认保留策略配置中,按需配置以下参数:

    • 暂不设置不设置默认保留策略,上传到 Bucket 中的对象不会自动附加默认保留规则。

    • 合规模式(Compliance Mode):合规模式下,保留期内任何用户(包括根用户)都无法删除或覆盖写对象。

      • 保留时间:输入保留时长数字,选择单位为

  6. 单击保存,在二次确认弹窗中输入确认信息完成开启。

ossutil

为存储空间examplebucket开启对象级别保留策略,并配置合规模式、默认保留天数为1天。

使用XML配置文件,object-worm-configuration.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<ObjectWormConfiguration>
  <ObjectWormEnabled>Enabled</ObjectWormEnabled>
  <Rule>
    <DefaultRetention>
      <Mode>COMPLIANCE</Mode>
      <Days>1</Days>
    </DefaultRetention>
  </Rule>
</ObjectWormConfiguration>

命令示例如下:

ossutil api put-bucket-object-worm-configuration --bucket examplebucket --object-worm-configuration file://object-worm-configuration.xml

SDK

以下代码示例演示如何通过SDK开启Object Worm并配置默认保留策略。

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 domain names that other services can use to access OSS')
parser.add_argument('--mode', help='Object-level retention strategy pattern. 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 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(&region, "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

调用PutBucketObjectWormConfiguration接口开启Object Worm,请求体示例如下。以下示例为Bucket开启ObjectWorm并设置默认保留策略为合规模式保留1天。

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>

Object配置保留策略

为指定Object版本配置独立的保留策略,包括保留模式和保留时间。Object级别的策略优先级高于Bucket默认保留策略。

控制台

支持在文件列表页或文件详情页为已上传的Object配置保留策略。

  1. 登录OSS管理控制台

  2. 在左侧导航栏,单击Bucket列表,然后单击目标Bucket名称。

  3. 在左侧导航栏,单击文件管理,找到目标文件。

  4. 单击目标文件右侧的更多 > 对象级别保留策略

  5. 在弹出的设置面板中,配置默认保留模式保留时间,然后单击确定

说明

合规模式下,已设置保留策略的Object仅支持延长保留时间,不支持缩短。

ossutil

为存储空间examplebucket中的对象exampleobject配置合规模式保留策略,保留截止日期为2026-12-31T00:00:00.000Z。

使用XML配置文件,retention.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<Retention>
  <Mode>COMPLIANCE</Mode>
  <RetainUntilDate>2026-12-31T00:00:00.000Z</RetainUntilDate>
</Retention>

命令示例如下:

ossutil api put-object-retention --bucket examplebucket --key exampleobject --retention file://retention.xml

SDK

以下代码示例演示如何通过SDKObject配置保留策略。

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 domain names that other services can use to access OSS')
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 retain until date (1 days 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(&region, "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

调用PutObjectRetention接口为Object配置保留策略,请求体示例如下。

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>

上传时配置保留策略

上传Object时可通过请求头直接配置保留策略,无需单独调用PutObjectRetention接口。支持PutObjectPutObjectInitiateMultipartUpload操作。

控制台

  1. 登录OSS管理控制台,进入目标Bucket文件管理页面。

  2. 单击上传文件

  3. 在上传面板中展开高级选项,找到默认保留策略设置项。

  4. 选择单独设置,配置保留模式保留时间,然后上传文件。

    说明

    若选择继承Bucket默认策略,则上传的文件将自动应用Bucket的默认保留策略。

ossutil

通过ossutil的 API级命令put-object上传文件时,使用--object-worm-mode--object-worm-retain-until-date参数指定保留策略。

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

以下代码示例演示如何在调用PutObject接口上传文件时配置保留策略。

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)

# 上传文件并设置保留策略:合规模式,保留至2026年10月11日
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 {
            // 上传文件并设置保留策略:合规模式,保留至2026年10月11日
            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)

    // 上传文件并设置保留策略:合规模式,保留至2026年10月11日
    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

调用PutObject接口上传文件时,通过请求头配置保留策略。

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]

注意事项

  • 不可关闭:一旦为Bucket开启Object Worm,将无法关闭该功能,除非注销阿里云账号。请在开启前充分评估业务需求。

  • 默认策略生效范围:默认保留策略仅对后续新上传的文件生效,存量文件不会自动生效。如需对存量Object设置保留策略,需通过PutObjectRetention接口单独设置。

  • Object策略优先级:如果Object设置了独立的保留策略,则以Object级别的策略为准,优先级高于Bucket默认保留策略。

  • 保留期限只能延长:在合规模式下,已设置的保留截止日期(RetainUntilDate)只能延长,不能缩短。

  • 删除文件:处于ObjectWorm保留期内的文件无法删除。

  • DeleteMarker:删除标记(DeleteMarker)不受Object Worm保护,可以正常创建和清理。但处于保留期内的Object版本不允许被删除。

  • 分片文件:分片上传产生的分片文件(Part)同样不受 Object Worm 保护。

  • 数据复制:数据复制不会自动复制源端的ObjectWorm保留策略设置。目的端Object遵循目的Bucket自身的ObjectWorm设置,需要单独配置。

  • 生命周期管理:开启ObjectWorm后,生命周期规则中的存储类型转换(Transition)操作不受影响,但处于保留期内的文件不会被生命周期规则自动删除(Expiration)。

  • 日志转存:不建议将日志文件投递到已开启ObjectWormBucket中,老旧日志文件可能因处于保留期内而无法自动删除,导致存储费用持续增长。

  • Append上传:配置了Bucket级别ObjectWorm默认保留策略后,不支持使用追加上传方式,且AppendObject不支持设置ObjectWorm。

  • Object ACL:处于ObjectWorm保留期内的文件无法设置Object ACL。