diff --git a/amazons3.admin.inc b/amazons3.admin.inc
index 910051a7e..07c333792 100644
--- a/amazons3.admin.inc
+++ b/amazons3.admin.inc
@@ -52,6 +52,19 @@ function amazons3_admin() {
     ),
   );
 
+  $form['amazons3_upload_acl'] = array(
+    '#type' => 'select',
+    '#title' => t('File upload access mode (ACL)'),
+    '#default_value' => variable_get('amazons3_upload_acl', 'public-read'),
+    '#options' => [
+      'public-read' => 'Public read',
+      'public-read-write' => 'Public read & write',
+      'authenticated-read' => 'Authenticated read',
+      'private' => 'Private',
+    ],
+    '#description' => t('The access mode to give new files that are added to the bucket. For files uploaded in fields that use Amazon S3 as their upload destination.'),
+  );
+
   $form['amazons3_cname'] = array(
     '#type' => 'checkbox',
     '#title' => t('Enable CNAME'),
@@ -133,6 +146,12 @@ function amazons3_admin() {
 function amazons3_admin_validate($form, &$form_state) {
   $bucket = $form_state['values']['amazons3_bucket'];
   $cloudfront = $form_state['values']['amazons3_cloudfront'];
+  $presignedUrls = $form_state['values']['amazons3_presigned_urls'];
+  $uploadMode = $form_state['values']['amazons3_upload_acl'];
+
+  if ($uploadMode === 'private' && empty($presignedUrls)) {
+    drupal_set_message(t('You selected private access mode for file uploads but did not specify any presigned url paths, none of the files uploaded into the bucket will be accessible until you do so. You can set it for any paths by adding 60|/* to the presigned url config.'), 'warning');
+  }
 
   if ($cloudfront) {
     $keypair = variable_get('amazons3_cloudfront_keypair_id', FALSE);
diff --git a/src/StreamWrapper.php b/src/StreamWrapper.php
index daf593fc6..4d23923b2 100644
--- a/src/StreamWrapper.php
+++ b/src/StreamWrapper.php
@@ -371,7 +371,7 @@ class StreamWrapper extends \Aws\S3\StreamWrapper implements \DrupalStreamWrappe
     }
 
     $options = parent::getOptions();
-    $options['ACL'] = 'public-read';
+    $options['ACL'] = $this->getUploadACL();
 
     if ($this->useRrs()) {
       $options['StorageClass'] = 'REDUCED_REDUNDANCY';
@@ -429,6 +429,25 @@ class StreamWrapper extends \Aws\S3\StreamWrapper implements \DrupalStreamWrappe
     return 'attachment; filename="' . mb_encode_mimeheader($this->getBasename()) . '"';
   }
 
+  /**
+   * Get the ACL to use for new uploads.
+   *
+   * @return string
+   *   A string representing the permissions
+   */
+  protected function getUploadACL() {
+    $acl = variable_get('amazons3_upload_acl');
+    switch ($acl) {
+      case 'public-read':
+      case 'public-read-write':
+      case 'authenticated-read':
+      case 'private':
+        return $acl;
+      default:
+        return 'public-read';
+    }
+  }
+
   /**
    * Find if this URI should force a download.
    *
