diff --git a/docs/storage-drivers/s3.md b/docs/storage-drivers/s3.md
index 97cfbfc1..32f199fc 100644
--- a/docs/storage-drivers/s3.md
+++ b/docs/storage-drivers/s3.md
@@ -160,6 +160,17 @@ An implementation of the `storagedriver.StorageDriver` interface which uses Amaz
The S3 storage class applied to each registry file. The default value is STANDARD.
+
+
+ objectacl
+ |
+
+ no
+ |
+
+ The S3 Canned ACL for objects. The default value is "private".
+ |
+
@@ -189,6 +200,8 @@ An implementation of the `storagedriver.StorageDriver` interface which uses Amaz
`storageclass`: (optional) The storage class applied to each registry file. Defaults to STANDARD. Valid options are STANDARD and REDUCED_REDUNDANCY.
+`objectacl`: (optional) The canned object ACL to be applied to each registry object. Defaults to `private`. If you are using a bucket owned by another AWS account, it is recommended that you set this to `bucket-owner-full-control` so that the bucket owner can access your objects. Other valid options are available in the [AWS S3 documentation](http://docs.aws.amazon.com/AmazonS3/latest/dev/acl-overview.html#canned-acl).
+
## S3 permission scopes
The following IAM permissions are required by the registry for push and pull. See [the S3 policy documentation](http://docs.aws.amazon.com/AmazonS3/latest/dev/mpuAndPermissions.html) for more details.
diff --git a/registry/storage/driver/s3-aws/s3.go b/registry/storage/driver/s3-aws/s3.go
index 6fa28d4d..6c1c3370 100644
--- a/registry/storage/driver/s3-aws/s3.go
+++ b/registry/storage/driver/s3-aws/s3.go
@@ -53,6 +53,9 @@ const listMax = 1000
// validRegions maps known s3 region identifiers to region descriptors
var validRegions = map[string]struct{}{}
+// validObjectAcls contains known s3 object Acls
+var validObjectAcls = map[string]struct{}{}
+
//DriverParameters A struct that encapsulates all of the driver parameters after all values have been set
type DriverParameters struct {
AccessKey string
@@ -67,6 +70,7 @@ type DriverParameters struct {
RootDirectory string
StorageClass string
UserAgent string
+ ObjectAcl string
}
func init() {
@@ -87,6 +91,18 @@ func init() {
validRegions[region] = struct{}{}
}
+ for _, objectAcl := range []string{
+ s3.ObjectCannedACLPrivate,
+ s3.ObjectCannedACLPublicRead,
+ s3.ObjectCannedACLPublicReadWrite,
+ s3.ObjectCannedACLAuthenticatedRead,
+ s3.ObjectCannedACLAwsExecRead,
+ s3.ObjectCannedACLBucketOwnerRead,
+ s3.ObjectCannedACLBucketOwnerFullControl,
+ } {
+ validObjectAcls[objectAcl] = struct{}{}
+ }
+
// Register this as the default s3 driver in addition to s3aws
factory.Register("s3", &s3DriverFactory{})
factory.Register(driverName, &s3DriverFactory{})
@@ -107,6 +123,7 @@ type driver struct {
KeyID string
RootDirectory string
StorageClass string
+ ObjectAcl string
}
type baseEmbed struct {
@@ -248,6 +265,20 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
userAgent = ""
}
+ objectAcl := s3.ObjectCannedACLPrivate
+ objectAclParam := parameters["objectacl"]
+ if objectAclParam != nil {
+ objectAclString, ok := objectAclParam.(string)
+ if !ok {
+ return nil, fmt.Errorf("Invalid value for objectacl parameter: %v", objectAclParam)
+ }
+
+ if _, ok = validObjectAcls[objectAclString]; !ok {
+ return nil, fmt.Errorf("Invalid value for objectacl parameter: %v", objectAclParam)
+ }
+ objectAcl = objectAclString
+ }
+
params := DriverParameters{
fmt.Sprint(accessKey),
fmt.Sprint(secretKey),
@@ -261,6 +292,7 @@ func FromParameters(parameters map[string]interface{}) (*Driver, error) {
fmt.Sprint(rootDirectory),
storageClass,
fmt.Sprint(userAgent),
+ objectAcl,
}
return New(params)
@@ -321,6 +353,7 @@ func New(params DriverParameters) (*Driver, error) {
KeyID: params.KeyID,
RootDirectory: params.RootDirectory,
StorageClass: params.StorageClass,
+ ObjectAcl: params.ObjectAcl,
}
return &Driver{
@@ -688,7 +721,7 @@ func (d *driver) getContentType() *string {
}
func (d *driver) getACL() *string {
- return aws.String("private")
+ return aws.String(d.ObjectAcl)
}
func (d *driver) getStorageClass() *string {
diff --git a/registry/storage/driver/s3-aws/s3_test.go b/registry/storage/driver/s3-aws/s3_test.go
index 70358763..e1df500f 100644
--- a/registry/storage/driver/s3-aws/s3_test.go
+++ b/registry/storage/driver/s3-aws/s3_test.go
@@ -30,6 +30,7 @@ func init() {
keyID := os.Getenv("S3_KEY_ID")
secure := os.Getenv("S3_SECURE")
region := os.Getenv("AWS_REGION")
+ objectAcl := os.Getenv("S3_OBJECT_ACL")
root, err := ioutil.TempDir("", "driver-")
regionEndpoint := os.Getenv("REGION_ENDPOINT")
if err != nil {
@@ -67,6 +68,7 @@ func init() {
rootDirectory,
storageClass,
driverName + "-test",
+ objectAcl,
}
return New(parameters)