Set expiration for policy statements

更新时间:
复制 MD 格式

Add an acs:CurrentTime condition to a bucket policy or RAM policy Statement to make it expire automatically. Use this approach for temporary bans, time-limited access, and automated cleanup of expired statements.

Use cases

Add a time condition to a statement to auto-expire it, eliminating the risk of forgetting to revoke permissions manually.

  • Temporary access denial: Deny all access until a specified date. Access is automatically restored after the date passes.

  • Time-limited authorization: Allow access to resources only within a specified time window. The permission automatically expires afterward.

Use the acs:CurrentTime condition key with date/time comparison operators in the Condition block to bind statement effectiveness to the system time.

Example bucket policy

This bucket policy grants (Allow) all users the oss:GetObject permission on objects in mytestbucket before 17:00:00 on August 12, 2026 (Beijing Time). After this time, the statement expires and access is denied.

{
    "Version": "1",
    "Statement": [
        {
            "Action": [
                "oss:GetObject"
            ],
            "Effect": "Allow",
            "Resource": [
                "acs:oss:*:*:mytestbucket/*"
            ],
            "Condition": {
                "DateLessThan": {
                    "acs:CurrentTime": [
                        "2026-08-12T17:00:00+08:00"
                    ]
                }
            }
        }
    ]
}

How it works:

  • Before expiration (current time < 2026-08-12 17:00): The DateLessThan condition is true, so the Allow statement takes effect and GetObject succeeds.

  • After expiration (current time ≥ 2026-08-12 17:00): The DateLessThan condition is false, the statement no longer applies, and access is denied.

Example RAM policy

This RAM policy grants a RAM user access to any object in mytestbucket only before 17:00:00 on August 12, 2026 (UTC+8).

{
  "Version": "1",
  "Statement": [
    {
      "Action": "oss:*",
      "Effect": "Allow",
      "Resource": [
        "acs:oss:*:*:mytestbucket/*"
      ],
      "Condition": {
        "DateLessThan": {
          "acs:CurrentTime": "2026-08-12T17:00:00+08:00"
        }
      }
    }
  ]
}

RAM policies support the same time conditions. Access Alibaba Cloud during a specified period of time.

Condition keys and operators

Bucket policies and RAM policies share the same condition keys and operators. The following are commonly used for statement expiration:

Condition key

Condition key

Description

acs:CurrentTime

The system time when the request reaches the OSS server, in ISO 8601 format.

Date operators

acs:CurrentTime supports the following six date operators:

Operator

Description

DateEquals

The current time is the same as the specified time.

DateNotEquals

The current time is not the same as the specified time.

DateLessThan

The current time is earlier than the specified time. This is useful for "Allow before expiration" or "Deny before expiration" scenarios.

DateLessThanEquals

The current time is earlier than or equal to the specified time.

DateGreaterThan

The current time is later than the specified time. This is useful for "Allow after a certain time" scenarios.

DateGreaterThanEquals

The current time is later than or equal to the specified time.

Condition lists all bucket policy elements and conditions.

Clean up expired statements

Expired time-based statements are not automatically removed from a bucket policy. Over time, they can cause the following issues:

  • Size limit: Bucket policies have a 16 KB size limit. Accumulated expired statements consume space and can block new additions.

  • Management: Redundant statements obscure permission boundaries and complicate troubleshooting.

  • Compliance: Regular cleanup of expired entries helps maintain the principle of least privilege.

Periodically clean up expired statements. Identify them by their Sid and delete them manually, or deploy an automation script to Function Compute (FC) with a time-based trigger (for example, weekly). Customize the cleanup process for your business requirements.

Cleanup procedure

  1. Call GetBucketPolicy to retrieve the complete Policy JSON text.

  2. Parse the policy JSON and iterate through each statement.

  3. Find DateLessThan or DateGreaterThan in Condition, and extract the time string for acs:CurrentTime.

  4. Parse the time string into a datetime object and compare it with the current system time.

  5. If a time condition will never be triggered again (for example, the specified time for DateLessThan is earlier than the current time), the Statement is marked as expired and removed from the list.

  6. Call PutBucketPolicy to resubmit the list of Statements after the expired entries are removed.

Identifying expired statements

To determine whether an expired statement can be safely deleted, consider both the Condition operator and Effect:

Condition combination

Description

Cleanup recommendation

DateLessThan + Deny

Denies access before a specified date. The restriction is automatically lifted after the date passes.

Safe to delete after the date passes. Removing the statement lifts the restriction, which matches the original intent.

DateLessThan + Allow

Grants temporary access before a specified date. The permission automatically expires after the date passes.

Safe to delete after the specified date passes.

DateGreaterThan + Allow

Allows access only after a specified date. Once the current time is later than the specified date, this condition is always true.

To make the permission permanent, remove the Condition section but keep the statement. Otherwise, use a DateLessThan condition to set an explicit end date.

Example Python automation script

This sample script uses the oss2 SDK to identify and remove expired statements with the DateLessThan condition. Adjust the rules for your business logic.

Important

This script modifies the bucket policy. Test it on a non-production bucket first. Install python-dateutil to parse ISO 8601 time strings with time zones.

import json
import alibabacloud_oss_v2 as oss
from datetime import datetime, timezone
import dateutil.parser  # We recommend installing the python-dateutil library to correctly parse ISO 8601 strings.

# Configurations
access_key = 'YOUR_ACCESS_KEY'
secret_key = 'YOUR_SECRET_KEY'
region = 'cn-hangzhou'
bucket_name = 'your-bucket-name'

cfg = oss.config.load_default()
cfg.credentials_provider = oss.credentials.StaticCredentialsProvider(access_key, secret_key)
cfg.region = region
client = oss.Client(cfg)

def clean_expired_policy():
    try:
        # 1. Get the current bucket policy.
        result = client.get_bucket_policy(oss.models.GetBucketPolicyRequest(bucket=bucket_name))
        policy_data = json.loads(result.body)

        statements = policy_data.get('Statement', [])
        now = datetime.now(timezone.utc)  # Use UTC for time comparison.

        new_statements = []
        removed_count = 0

        # 2. Iterate through and check each statement.
        for stmt in statements:
            is_expired = False

            # Check for time-based conditions (this example uses DateLessThan).
            condition = stmt.get('Condition', {})
            date_less_than = condition.get('DateLessThan', {}).get('acs:CurrentTime')

            if date_less_than:
                # Extract the time from the policy (for example, "2026-08-12T17:00:00+08:00").
                # dateutil.parser can automatically handle time zone information, such as +08:00.
                expiry_time = dateutil.parser.isoparse(date_less_than[0])

                # If the specified time is earlier than the current time, the Deny/Allow statement will never be triggered again.
                if expiry_time < now:
                    is_expired = True
                    print(f"Found expired statement [Sid: {stmt.get('Sid', 'N/A')}]: The set time {date_less_than[0]} has passed.")

            if not is_expired:
                new_statements.append(stmt)
            else:
                removed_count += 1

        # 3. Write the policy back to the bucket.
        if removed_count > 0:
            if not new_statements:
                # If all statements are expired, delete the entire policy.
                client.delete_bucket_policy(oss.models.DeleteBucketPolicyRequest(bucket=bucket_name))
                print("All statements have expired. The bucket policy has been cleared.")
            else:
                policy_data['Statement'] = new_statements
                client.put_bucket_policy(oss.models.PutBucketPolicyRequest(
                    bucket=bucket_name,
                    body=json.dumps(policy_data),
                ))
                print(f"Cleanup complete. Removed {removed_count} expired statement(s).")
        else:
            print("No expired statements found.")

    except oss.exceptions.OperationError as e:
        cause = e.unwrap() if hasattr(e, 'unwrap') else None
        if isinstance(cause, oss.exceptions.ServiceError) and cause.code == 'NoSuchBucketPolicy':
            print("This bucket does not have a policy configured.")
        else:
            print(f"An error occurred: {e}")
    except Exception as e:
        print(f"An error occurred: {e}")

if __name__ == "__main__":
    clean_expired_policy()

Usage notes

  • Time format: Use ISO 8601 format with an explicit time zone (for example, +08:00). Omitting the time zone may cause unexpected expiration behavior due to server-side parsing differences.

  • Operator matching: Choose times and operators that match your business logic.

  • Test first: Test your configuration and cleanup script on a non-production bucket before applying changes to production.