Skip to content

HDDS-15945. [OEP] Support S3 WORM (Object Lock) - #11053

Draft
chungen0126 wants to merge 7 commits into
apache:masterfrom
chungen0126:HDDS-15945-design-doc
Draft

HDDS-15945. [OEP] Support S3 WORM (Object Lock)#11053
chungen0126 wants to merge 7 commits into
apache:masterfrom
chungen0126:HDDS-15945-design-doc

Conversation

@chungen0126

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

This is the OEP doc for S3 WORM (Object Lock) feature.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-15945

How was this patch tested?

No tests.

@devmadhuu devmadhuu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @chungen0126 for putting up the design. Curiously had a look and compared against AWS S3 specs. Got few doubts and points.


> _**Note**:
> AWS S3 supports enabling Object Lock and configuring RetentionConfig directly during bucket creation.
> In Apache Ozone's current design, these settings must be configured via dedicated API calls after the bucket has been created.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In contrast to AWS S3, how do we present this to compliance auditors? Or should there be a "one-way" flag that, once set, cannot be cleared?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing that out.

  • Enabling at Creation: We can definitely support enabling Object Lock directly at bucket creation time (e.g., via the S3 CreateBucket header/parameters) to eliminate any compliance window. I updated the doc.
  • One-way Flag: Exactly, objectLockEnabled is designed as a one-way flag—once enabled on a bucket, it cannot be cleared or disabled.


- Definition: Configures a fixed retention duration (specified in days or years) for an object and applies a specific retention mode.
- Retention Modes:
- Compliance Mode: The strictest protection tier. Once applied, no user (including root/admin) can remove the lock, shorten the duration, or overwrite the object before the retention period expires.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really true for Ozone. In AWS S3, it is being made sure to be immutable at all levels or atleast audited or blocked including admin/operators users, but in Ozone, this may not be true, currently design talks about a happy path using validateAndUpdateCache when hit on normal S3/ozone APIs. In Ozone there are other ways where someone can directly edit rocksDb or delete a key meta for a locked key. Another way, where ozone repair command also allows to restore OM's DB directory from a ratis snapshot taken before the lock was applied.

Probably the design should talk about behavior when such actions can happen in Ozone , that what is trusted boundary and upto what extent the data is protected because otherwise this design may not suffice the complete compliance audit implementation.

Can think of below:

  • Whether ozone repair subcommands should refuse to operate on Raft indexes that carry lock state changes without an explicit unsafe flag.
  • Whether locked keys should be detected on OM startup via cross-check between RocksDB state and a tamper-evident external audit log — so that a manual DB-copy recovery that silently removes a lock can at least be detected on the next start.
  • an operator can run skip-ratis-transaction at the Raft index of a SetRetention(compliance) entry across all 3 OMs while stopped, then restart, and the audit trail of the lock is gone (though RocksDB may still hold applied state

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out!

I've added a Trusted Boundary section to clarify that any operations requiring root access bypass the application-level API and are outside the trusted boundary.


message RetentionConfig {
optional RetentionMode retentionMode = 23;
optional uint64 retainUntilDate = 24;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to move the OM leader's clock forward: The WORM check in validateAndUpdateCache will compare retainUntilDate (stored) against "now". "Now" is whatever the OM leader believes the time is.


#### Bucket Table

Two new fields: objectLockEnabled & defaultRetention.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this object Locking is from S3, what interface via s3 api will be used to configure or manage? or its directly via ozone cli?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Object locking can be configured and managed via both the Ozone API and the S3 API.

  • Ozone API: It uses OzoneBucket#setRetentionConfig. If no default retention is set, the rule field within retention will simply be null.
  • S3 API: It is managed through PutBucketObjectLockConfiguration, which basically follows the standard S3 specifications. You can refer to the official AWS S3 documentation for more details.


### Ranger Access Control

- Legal Hold: Introduces three new Access Types—GET_LEGAL_HOLD, PUT_LEGAL_HOLD, and CLEAR_LEGAL_HOLD—and adds them to accessTypeRestrictions for Keys.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we introduce this feature in Ozone for validation via above api, Having same at ranger do have any specific advantage ?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how ranger and ozone role will combine in validation?


#### Impact on Delete Object Flow

All delete operations must perform WORM validation during the `validateAndUpdateCache` phase to preserve linearizability and prevent accidental deletion of protected data.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do impact for bucket removal or volume removal or directory removal where as per soft delete, it moves to deleted directory table, but generally validation is not done to deep child ?


## Security

Centralized access control via Ranger ensures all Object Lock operations (such as Retention Policy configuration and Legal Hold management) are enforced under strict access permissions. Dedicated Access Types (BYPASS_GOVERNANCE, PUT_LEGAL_HOLD, etc.) enforce the Principle of Least Privilege, preventing unauthorized tampering or removal of locks and enhancing data immutability.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like ranger can clear / update policy, and super admin role to update / delete bucket or file policy ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for pointing this out!

I've added a Trusted Boundary section to clarify that any operations requiring root access bypass the application-level API and are outside the trusted boundary.

message BucketInfo {
// ... existing fields
required bool objectLockEnabled = 24 [default = false];
optional RetentionConfig defaultRetention = 25;

@ChenSammi ChenSammi Sep 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @chungen0126 for working on this design.

It looks like bucket level retention configuration is different than object level. It support days and years, not the retainUntilDate.

https://docs.aws.amazon.com/cli/latest/reference/s3api/put-object-lock-configuration.html


* **`GET_LEGAL_HOLD`**: Allows querying the current Legal Hold status of an object (maps to the `GetObjectLegalHold` API).
* **`PUT_LEGAL_HOLD`**: Grants permission to apply a Legal Hold to an object (maps to `PutObjectLegalHold` with status ON). Once applied, the object is locked indefinitely, blocking all overwrite and delete operations.
* **`CLEAR_LEGAL_HOLD`**: Grants permission to remove a Legal Hold from an object (maps to `PutObjectLegalHold` with status OFF). Because this clears immutability protection, it is treated as a high-privilege action restricted only to authorized users.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLEAR_LEGAL_HOLD can be covered by PUT_LEGAL_HOLD, since AWS S3 doesn't have CLEAR_LEGAL_HOLD permission too, so let's avoid introduce a new extra permission.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi all - you won't need to create new access types for this. From the STS project, the concept of actions are created in Ranger, which map exactly to the AWS actions without the s3: prefix. From the AWS documentation (https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lock.html), there are 6 new actions:

s3:BypassGovernanceRetention
s3:GetBucketObjectLockConfiguration
s3:GetObjectLegalHold
s3:GetObjectRetention
s3:PutBucketObjectLockConfiguration
s3:PutObjectLegalHold
s3:PutObjectRetention

so in Ranger these would be:

BypassGovernanceRetention
GetBucketObjectLockConfiguration
GetObjectLegalHold
GetObjectRetention
PutBucketObjectLockConfiguration
PutObjectLegalHold
PutObjectRetention

For example, if you want the role to have access PutObjectLegalHold, you would grant PutObjectLegalHold action and write permission (i.e. access type) in Ranger. Or you could grant Put* and all permission and get access to all the Put actions.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mappings in Ranger for actions to permissions/access types are found here: https://github.com/apache/ranger/blob/master/security-admin/src/main/webapp/react-webapp/src/utils/actionRequirements/ozone.json.

Also, please note that when STS is merged to master, the IamSessionPolicyResolver would need to get updated with the new actions as well as S3GActionIamMapper.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, like @ChenSammi says, I believe you need to separate the authorization from the value being set. For example, the same PutObjectLegalHold authorization can be used with values ON or OFF in the API (see https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObjectLegalHold.html)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, to use the actions in Ranger, ensure to set the Ranger feature flag to true: https://ozone.apache.org/docs/next/administrator-guide/operations/s3/sts#ranger-feature-flag-action-matches-policy-condition

> * **Object Lock Immutability & Future Versioning Binding**:
> - **Current State (No Versioning)**: Once Object Lock is enabled on a bucket (`objectLockEnabled = true`), it cannot be disabled.
> - **Future Evolution (With Versioning)**: When S3 Versioning is supported, Object Lock and Versioning will be tightly coupled following AWS S3 semantics: once Object Lock is enabled, Versioning cannot be suspended or disabled.
> * **Bucket Creation Semantics**:

@ChenSammi ChenSammi Sep 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one more S3 behavior, versioning is enabled automatically when Object Lock is enabled.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Standard data mutating APIs will intercept the Object Lock state and return the `403 Access Denied` (or specifically `WORMProtectionException`) if a modification is attempted on a locked object:
* `PutObject` / `CopyObject` (Overwrites will be rejected)
* `DeleteObject` / `DeleteObjects` (Deletions will be rejected)
* `CreateMultipartUpload` / `CompleteMultipartUpload` / `UploadPart` (Uploads will be rejected if the object is locked)

@ChenSammi ChenSammi Sep 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reject upload in CreateMultipartUpload is good enough for the MPU, CompleteMultipartUpload and UploadPart can be untouched.


## Compatibility

Because this design alters the schemas of Bucket Table and Key Table, OM (Ozone Manager) version leveling will be introduced to maintain forward and backward compatibility across rolling upgrades.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the major reason is we have added new OM APIs for the feature, so we need a new OM version to tell client whether these APIs can be called or not. And table wise, since all new fields are optional fields, they are naturally backward compatible.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated


### Ranger Access Control

Ozone Object Lock enforces a dual-gate mechanism combining **Ranger authorization checks** and **underlying WORM state validation**:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have an JIRA open in Ranger project to track all the changes required for this feature?

@ChenSammi ChenSammi Sep 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fmorg-git , would you mind sharing some knowledge with @chungen0126 about how to expose new permissions for Ranger, and what are the major tasks needed for Ranger integration, including UI changes?

@fmorg-git fmorg-git Sep 9, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added comments

* **Compliance Mode**: Serves as the strictest compliance tier. Until the retention period expires, **no role or Ranger permission can bypass or overwrite the lock**, including cluster administrators.
* **Governance Mode and `BYPASS_GOVERNANCE`**:
* **Mechanism**: Governance Mode allows authorized users to overwrite, delete, or alter the retention duration of a locked object before its expiration date.
* **Authorization Binding**: Introduces the **`BYPASS_GOVERNANCE`** Access Type, configured under `accessTypeRestrictions` at the **Volume level**.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why BYPASS_GOVERNANCE is configured at volume level?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe BypassGovernanceRetention should be checked at the key level.

@chungen0126 chungen0126 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @ChenSammi, @devmadhuu @sumitagrawl, and @fmorg-git for the review! I’ve updated the design doc based on your feedback—please take another look.

Regarding the Ranger integration part, I'm still relatively new to it and actively catching up, so I would really appreciate it if @fmorg-git could help take a look. I'll continue refining the Ranger-related details in upcoming updates.

@devmadhuu

Copy link
Copy Markdown
Contributor

@chungen0126 , just want to highlight to be in compliance with AWS S3 WORM, that AWS has recently added variable retention with event holds to S3 Object Lock, so may be we can think about adding EVENT_TRIGGERED_RETENTION in our existing enum for extended support. Enterprise S3 semantics are increasingly about governance workflows, not just object durability. Reference : AWS S3 doc

object created
      |
event hold
      |
business event occurs
      |
hold released
      |
retention timer starts
      |
WORM until timer expires

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants