A time-based retention policy (WORM) prevents objects in an OSS bucket from being modified or deleted during a defined retention period. Retention periods range from 1 day to 70 years.
How it works
A retention policy has two states:
InProgress: The policy is created but not yet locked. It can be cancelled.
Locked: The policy is permanent. The retention period can only be extended, never shortened, and the policy cannot be cancelled.
After locking, objects in the bucket are protected for the duration of the retention period. Any attempt to delete or overwrite a protected object fails with an error.
Prerequisites
Before you begin, ensure that you have:
Versioning disabled on the target bucket (a bucket cannot have both versioning and a retention policy enabled at the same time)
The OSS_ACCESS_KEY_ID and OSS_ACCESS_KEY_SECRET environment variables set with your access credentials
The permissions required to manage bucket WORM configurations
Usage notes
All examples share the same client initialization pattern:
Credentials are read from environment variables (OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET).
Set yourEndpoint to the endpoint for your bucket's region. For example, for the China (Hangzhou) region, use https://oss-cn-hangzhou.aliyuncs.com. For same-region access from other Alibaba Cloud services, use the internal endpoint. For more information, see Regions and endpoints.
Set yourRegion to the region ID for your bucket, such as cn-hangzhou.
To create an OSSClient instance using a custom domain name or Security Token Service (STS), see Configure OSSClient instances.
Create a retention policy
Important Versioning and retention policies are mutually exclusive. Disable versioning on the bucket before creating a retention policy.
The following example creates a policy with a retention period of 60 days. After calling InitiateBucketWorm, the policy is in the InProgress state.
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
// Read credentials from environment variables.
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Error creating credentials provider: %v", err)
}
// Initialize the OSSClient.
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Error creating OSS client: %v", err)
}
bucketName := "<yourBucketName>"
// Create a retention policy with a 60-day retention period.
result, err := client.InitiateBucketWorm(bucketName, 60)
if err != nil {
log.Fatalf("Error initiating bucket WORM: %v", err)
}
log.Println("Retention policy created:", result)
}
Cancel an unlocked retention policy
An InProgress policy can be cancelled before it is locked. Once locked, a policy cannot be cancelled.
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Error creating credentials provider: %v", err)
}
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Error creating OSS client: %v", err)
}
bucketName := "<yourBucketName>"
// Cancel the unlocked retention policy.
err = client.AbortBucketWorm(bucketName)
if err != nil {
log.Fatalf("Error aborting bucket WORM: %v", err)
}
log.Println("Retention policy cancelled.")
}
Lock a retention policy
Locking a policy is irreversible. After locking, the retention period can only be extended, and the policy cannot be deleted.
The following example retrieves the current policy to get its WormId, then locks it using CompleteBucketWorm.
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Error creating credentials provider: %v", err)
}
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Error creating OSS client: %v", err)
}
bucketName := "<yourBucketName>"
// Get the current policy configuration to retrieve the WormId.
wormConfig, err := client.GetBucketWorm(bucketName)
if err != nil {
log.Fatalf("Error getting bucket WORM configuration: %v", err)
}
// Lock the retention policy. This action is irreversible.
err = client.CompleteBucketWorm(bucketName, wormConfig.WormId)
if err != nil {
log.Fatalf("Error locking bucket WORM: %v", err)
}
log.Println("Retention policy locked.")
}
Query a retention policy
Use GetBucketWorm to retrieve the current policy configuration, including its state, creation date, and retention period.
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Error creating credentials provider: %v", err)
}
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Error creating OSS client: %v", err)
}
bucketName := "<yourBucketName>"
wormConfig, err := client.GetBucketWorm(bucketName)
if err != nil {
log.Fatalf("Error getting bucket WORM configuration: %v", err)
}
// Policy ID
log.Printf("WORM Policy ID: %d", wormConfig.WormId)
// Creation time of the policy
log.Printf("CreationDate: %s", wormConfig.CreationDate)
// "InProgress" (unlocked) or "Locked"
log.Printf("State: %s", wormConfig.State)
// Retention period in days
log.Printf("RetentionPeriodInDays: %d", wormConfig.RetentionPeriodInDays)
}
Extend the retention period
After a policy is locked, the retention period can only be extended — never shortened. The following example extends the period to 30 days.
package main
import (
"log"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
log.Fatalf("Error creating credentials provider: %v", err)
}
clientOptions := []oss.ClientOption{oss.SetCredentialsProvider(&provider)}
clientOptions = append(clientOptions, oss.Region("yourRegion"))
clientOptions = append(clientOptions, oss.AuthVersion(oss.AuthV4))
client, err := oss.New("yourEndpoint", "", "", clientOptions...)
if err != nil {
log.Fatalf("Error creating OSS client: %v", err)
}
bucketName := "<yourBucketName>"
// Get the current policy to retrieve the WormId.
wormConfig, err := client.GetBucketWorm(bucketName)
if err != nil {
log.Fatalf("Error getting bucket WORM configuration: %v", err)
}
// Extend the retention period for objects in the locked retention policy to 30 days.
err = client.ExtendBucketWorm(bucketName, 30, wormConfig.WormId)
if err != nil {
log.Fatalf("Error extending bucket WORM: %v", err)
}
log.Println("Retention period extended.")
}
API reference
| Operation | Method | Description |
|---|
| Create a retention policy | InitiateBucketWorm | Creates a policy in the InProgress state |
| Cancel an unlocked policy | AbortBucketWorm | Cancels a policy in the InProgress state |
| Lock a retention policy | CompleteBucketWorm | Permanently locks the policy |
| Query a retention policy | GetBucketWorm | Returns the current policy configuration |
| Extend the retention period | ExtendBucketWorm | Extends the period on a locked policy |
For complete sample code, see the GitHub examples.