This is an automated email from the ASF dual-hosted git repository.

xuanwo pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 77e74d059 feat(services/s3): Add a way to specify a default object ACL 
(#7186)
77e74d059 is described below

commit 77e74d05973b344a7c5fb67125124aee5d25b279
Author: Antoine D <[email protected]>
AuthorDate: Mon Mar 9 12:58:20 2026 +0100

    feat(services/s3): Add a way to specify a default object ACL (#7186)
    
    feat(services/s3): Add a way to specify a default ACL
    
    This default ACL is used when creating an object.
    
    https://github.com/apache/opendal/issues/5358
    
    Note: I did not use a fixed list for the ACL but a String since I'm not an 
expert on this, and I don't really know if, for all supported services, we can 
restrict it the list of [canned 
ACL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html#canned-acl).
---
 core/services/s3/src/backend.rs |  7 +++++++
 core/services/s3/src/config.rs  |  4 ++++
 core/services/s3/src/core.rs    |  8 ++++++++
 core/services/s3/src/docs.md    | 31 +++++++++++++++++++++++++++++++
 4 files changed, 50 insertions(+)

diff --git a/core/services/s3/src/backend.rs b/core/services/s3/src/backend.rs
index d3ae6aa76..3c71d75e8 100644
--- a/core/services/s3/src/backend.rs
+++ b/core/services/s3/src/backend.rs
@@ -682,6 +682,12 @@ impl S3Builder {
 
         None
     }
+
+    /// Set default ACL for new objects.
+    pub fn default_acl(mut self, acl: &str) -> Self {
+        self.config.default_acl = Some(acl.to_string());
+        self
+    }
 }
 
 impl Builder for S3Builder {
@@ -960,6 +966,7 @@ impl Builder for S3Builder {
                 enable_request_payer: config.enable_request_payer,
                 signer,
                 checksum_algorithm,
+                default_acl: config.default_acl,
             }),
         })
     }
diff --git a/core/services/s3/src/config.rs b/core/services/s3/src/config.rs
index 8e4a3c15d..8c219de6c 100644
--- a/core/services/s3/src/config.rs
+++ b/core/services/s3/src/config.rs
@@ -221,6 +221,10 @@ pub struct S3Config {
     /// Indicates whether the client agrees to pay for the requests made to 
the S3 bucket.
     #[serde(alias = "aws_request_payer", alias = "request_payer")]
     pub enable_request_payer: bool,
+
+    /// Default ACL for new objects.
+    /// Note that some s3 services like minio do not support this option.
+    pub default_acl: Option<String>,
 }
 
 impl Debug for S3Config {
diff --git a/core/services/s3/src/core.rs b/core/services/s3/src/core.rs
index 03e14483a..bdb1ec470 100644
--- a/core/services/s3/src/core.rs
+++ b/core/services/s3/src/core.rs
@@ -75,6 +75,8 @@ pub mod constants {
     pub const X_AMZ_VERSION_ID: &str = "x-amz-version-id";
     pub const X_AMZ_OBJECT_SIZE: &str = "x-amz-object-size";
 
+    pub const X_AMZ_ACL: &str = "x-amz-acl";
+
     pub const RESPONSE_CONTENT_DISPOSITION: &str = 
"response-content-disposition";
     pub const RESPONSE_CONTENT_TYPE: &str = "response-content-type";
     pub const RESPONSE_CACHE_CONTROL: &str = "response-cache-control";
@@ -97,6 +99,7 @@ pub struct S3Core {
     pub allow_anonymous: bool,
     pub disable_list_objects_v2: bool,
     pub enable_request_payer: bool,
+    pub default_acl: Option<String>,
 
     pub signer: Signer<Credential>,
     pub checksum_algorithm: Option<ChecksumAlgorithm>,
@@ -330,6 +333,11 @@ impl S3Core {
                 req = req.header(format!("{X_AMZ_META_PREFIX}{key}"), value)
             }
         }
+
+        // Set ACL header.
+        if let Some(acl) = &self.default_acl {
+            req = req.header(constants::X_AMZ_ACL, acl);
+        }
         req
     }
 
diff --git a/core/services/s3/src/docs.md b/core/services/s3/src/docs.md
index 04cc80009..df279f35b 100644
--- a/core/services/s3/src/docs.md
+++ b/core/services/s3/src/docs.md
@@ -31,6 +31,7 @@ This service can be used to:
 - `enable_virtual_host_style`: Enable virtual host style.
 - `disable_write_with_if_match`: Disable write with if match.
 - `enable_request_payer`: Enable the request payer for backend.
+- `default_acl`: Define the default access control list (ACL) when creating a 
new object. Note that some s3 services like minio do not support this option.
 
 Refer to [`S3Builder`]'s public API docs for more information.
 
@@ -237,3 +238,33 @@ async fn main() -> Result<()> {
     Ok(())
 }
 ```
+
+### S3 with default ACL
+
+```rust,no_run
+use log::info;
+use opendal_core::Operator;
+use opendal_core::Result;
+use opendal_service_s3::S3;
+
+#[tokio::main]
+async fn main() -> Result<()> {
+    let mut builder = S3::default()
+      // Setup builders
+      .root("/path/to/dir")
+      .bucket("test")
+      .region("us-east-1")
+      .endpoint("https://s3.amazonaws.com";)
+      .access_key_id("access_key_id")
+      .secret_access_key("secret_access_key")
+      // Enable public-read ACL
+      .default_acl("public-read");
+
+    let op = Operator::new(builder)?.finish();
+    info!("operator: {:?}", op);
+
+    // New objects will be created with public-read ACL
+
+    Ok(())
+}
+```

Reply via email to