or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

bucket-access-control.mdbucket-features.mdbucket-operations.mdclient-config.mdindex.mdlist-operations.mdmultipart-upload.mdobject-operations.mdpaginators-waiters.mdpresigned-urls.mdtypes.md
tile.json

bucket-access-control.mddocs/

S3 Bucket Access Control Operations

This document covers AWS SDK for Go v2 S3 bucket access control operations including ACLs, bucket policies, public access blocks, ownership controls, and ABAC (Attribute-Based Access Control).

Package Information

  • Package: github.com/aws/aws-sdk-go-v2/service/s3
  • Types Package: github.com/aws/aws-sdk-go-v2/service/s3/types

Bucket ACL Operations

GetBucketAcl

Retrieves the access control list (ACL) of a bucket.

Note: Not supported for directory buckets. Beginning November 21, 2025, Amazon S3 will stop returning DisplayName. Use canonical IDs, AWS account IDs, or IAM ARNs instead.

Method Signature { .api }

func (c *Client) GetBucketAcl(
    ctx context.Context,
    params *GetBucketAclInput,
    optFns ...func(*Options),
) (*GetBucketAclOutput, error)

GetBucketAclInput { .api }

type GetBucketAclInput struct {
    // Specifies the S3 bucket whose ACL is being requested.
    // When using with an access point, provide the alias of the access point.
    // When using with an Object Lambda access point, provide the alias of the
    // Object Lambda access point.
    // Required: Yes
    Bucket *string

    // The account ID of the expected bucket owner. If the account ID that you
    // provide does not match the actual owner of the bucket, the request fails
    // with the HTTP status code 403 Forbidden (access denied).
    // Required: No
    ExpectedBucketOwner *string
}

GetBucketAclOutput { .api }

type GetBucketAclOutput struct {
    // A list of grants.
    Grants []types.Grant

    // Container for the bucket owner's display name and ID.
    Owner *types.Owner

    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Supporting Types

Grant { .api }

type Grant struct {
    // The person being granted permissions.
    Grantee *Grantee

    // Specifies the permission given to the grantee.
    // Values: READ | WRITE | READ_ACP | WRITE_ACP | FULL_CONTROL
    Permission Permission
}

Grantee { .api }

type Grantee struct {
    // Type of grantee
    // Required: Yes
    // Values: CanonicalUser | AmazonCustomerByEmail | Group
    Type Type

    // Screen name of the grantee (deprecated in some regions).
    DisplayName *string

    // Email address of the grantee (only supported in specific regions).
    EmailAddress *string

    // The canonical user ID of the grantee.
    ID *string

    // URI of the grantee group.
    URI *string
}

Owner { .api }

type Owner struct {
    // Container for the display name of the owner (supported in specific regions only).
    DisplayName *string

    // Container for the ID of the owner.
    ID *string
}

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    output, err := client.GetBucketAcl(context.TODO(), &s3.GetBucketAclInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Owner: %s\n", *output.Owner.ID)
    for _, grant := range output.Grants {
        fmt.Printf("Grantee: %s, Permission: %s\n",
            *grant.Grantee.ID, grant.Permission)
    }
}

PutBucketAcl

Sets the permissions on an existing bucket using access control lists (ACL).

Note: Not supported for directory buckets. Email grantee support discontinued after October 1, 2025. If your bucket uses bucket owner enforced setting, ACLs are disabled and no longer affect permissions.

Method Signature { .api }

func (c *Client) PutBucketAcl(
    ctx context.Context,
    params *PutBucketAclInput,
    optFns ...func(*Options),
) (*PutBucketAclOutput, error)

PutBucketAclInput { .api }

type PutBucketAclInput struct {
    // The bucket to which to apply the ACL.
    // Required: Yes
    Bucket *string

    // The canned ACL to apply to the bucket.
    // Values: private | public-read | public-read-write | authenticated-read
    // Required: No
    ACL types.BucketCannedACL

    // Contains the elements that set the ACL permissions for an object per grantee.
    // Required: No
    AccessControlPolicy *types.AccessControlPolicy

    // Indicates the algorithm used to create the checksum for the request when
    // you use the SDK. Values: CRC32 | CRC32C | SHA1 | SHA256
    // Required: No
    ChecksumAlgorithm types.ChecksumAlgorithm

    // The Base64 encoded 128-bit MD5 digest of the data.
    // Required: No
    ContentMD5 *string

    // The account ID of the expected bucket owner.
    // Required: No
    ExpectedBucketOwner *string

    // Allows grantee the read, write, read ACP, and write ACP permissions on the bucket.
    // Format: id="canonical-user-id"
    // Required: No
    GrantFullControl *string

    // Allows grantee to list the objects in the bucket.
    // Format: id="canonical-user-id" or uri="http://acs.amazonaws.com/groups/..."
    // Required: No
    GrantRead *string

    // Allows grantee to read the bucket ACL.
    // Format: id="canonical-user-id"
    // Required: No
    GrantReadACP *string

    // Allows grantee to create new objects in the bucket.
    // Format: id="canonical-user-id"
    // Required: No
    GrantWrite *string

    // Allows grantee to write the ACL for the applicable bucket.
    // Format: id="canonical-user-id"
    // Required: No
    GrantWriteACP *string
}

AccessControlPolicy { .api }

type AccessControlPolicy struct {
    // A list of grants.
    Grants []Grant

    // Container for the bucket owner's display name and ID.
    Owner *Owner
}

PutBucketAclOutput { .api }

type PutBucketAclOutput struct {
    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Usage Example

package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/service/s3/types"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    // Example 1: Using canned ACL
    _, err = client.PutBucketAcl(context.TODO(), &s3.PutBucketAclInput{
        Bucket: aws.String("my-bucket"),
        ACL:    types.BucketCannedACLPrivate,
    })
    if err != nil {
        log.Fatal(err)
    }

    // Example 2: Using grant headers
    _, err = client.PutBucketAcl(context.TODO(), &s3.PutBucketAclInput{
        Bucket:       aws.String("my-bucket"),
        GrantRead:    aws.String("id=canonical-user-id"),
        GrantReadACP: aws.String("id=canonical-user-id"),
    })
    if err != nil {
        log.Fatal(err)
    }

    // Example 3: Using AccessControlPolicy
    _, err = client.PutBucketAcl(context.TODO(), &s3.PutBucketAclInput{
        Bucket: aws.String("my-bucket"),
        AccessControlPolicy: &types.AccessControlPolicy{
            Owner: &types.Owner{
                ID: aws.String("owner-canonical-user-id"),
            },
            Grants: []types.Grant{
                {
                    Grantee: &types.Grantee{
                        Type: types.TypeCanonicalUser,
                        ID:   aws.String("grantee-canonical-user-id"),
                    },
                    Permission: types.PermissionRead,
                },
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }
}

Bucket Policy Operations

GetBucketPolicy

Returns the policy of a specified bucket.

Note: For directory buckets, you must use path-style requests to the Regional endpoint and the s3express:GetBucketPolicy permission.

Method Signature { .api }

func (c *Client) GetBucketPolicy(
    ctx context.Context,
    params *GetBucketPolicyInput,
    optFns ...func(*Options),
) (*GetBucketPolicyOutput, error)

GetBucketPolicyInput { .api }

type GetBucketPolicyInput struct {
    // The bucket name to get the bucket policy for.
    // For directory buckets, use path-style requests.
    // Required: Yes
    Bucket *string

    // The account ID of the expected bucket owner.
    // Not supported for directory buckets.
    // Required: No
    ExpectedBucketOwner *string
}

GetBucketPolicyOutput { .api }

type GetBucketPolicyOutput struct {
    // The bucket policy as a JSON document.
    Policy *string

    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    output, err := client.GetBucketPolicy(context.TODO(), &s3.GetBucketPolicyInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        log.Fatal(err)
    }

    fmt.Printf("Bucket Policy:\n%s\n", *output.Policy)
}

PutBucketPolicy

Applies an Amazon S3 bucket policy to an Amazon S3 bucket.

Note: For directory buckets, only the s3express:CreateSession IAM action is supported in the bucket policy.

Method Signature { .api }

func (c *Client) PutBucketPolicy(
    ctx context.Context,
    params *PutBucketPolicyInput,
    optFns ...func(*Options),
) (*PutBucketPolicyOutput, error)

PutBucketPolicyInput { .api }

type PutBucketPolicyInput struct {
    // The name of the bucket.
    // For directory buckets, use path-style requests.
    // Required: Yes
    Bucket *string

    // The bucket policy as a JSON document.
    // For directory buckets, only s3express:CreateSession is supported.
    // Required: Yes
    Policy *string

    // Indicates the algorithm used to create the checksum.
    // Values: CRC32 | CRC32C | CRC64NVME | SHA1 | SHA256
    // Required: No
    ChecksumAlgorithm types.ChecksumAlgorithm

    // Set to true to confirm that you want to remove your permissions to change
    // this bucket policy in the future.
    // Not supported for directory buckets.
    // Required: No
    ConfirmRemoveSelfBucketAccess *bool

    // The MD5 hash of the request body.
    // Not supported for directory buckets.
    // Required: No
    ContentMD5 *string

    // The account ID of the expected bucket owner.
    // Not supported for directory buckets.
    // Required: No
    ExpectedBucketOwner *string
}

PutBucketPolicyOutput { .api }

type PutBucketPolicyOutput struct {
    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Usage Example

package main

import (
    "context"
    "encoding/json"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    // Example 1: Public read policy
    publicReadPolicy := map[string]interface{}{
        "Version": "2012-10-17",
        "Statement": []map[string]interface{}{
            {
                "Sid":       "PublicReadGetObject",
                "Effect":    "Allow",
                "Principal": "*",
                "Action":    "s3:GetObject",
                "Resource":  "arn:aws:s3:::my-bucket/*",
            },
        },
    }

    policyJSON, err := json.Marshal(publicReadPolicy)
    if err != nil {
        log.Fatal(err)
    }

    _, err = client.PutBucketPolicy(context.TODO(), &s3.PutBucketPolicyInput{
        Bucket: aws.String("my-bucket"),
        Policy: aws.String(string(policyJSON)),
    })
    if err != nil {
        log.Fatal(err)
    }

    // Example 2: Restrict access to specific VPC
    vpcPolicy := map[string]interface{}{
        "Version": "2012-10-17",
        "Statement": []map[string]interface{}{
            {
                "Sid":    "Access-to-specific-VPC-only",
                "Effect": "Deny",
                "Principal": "*",
                "Action":    "s3:*",
                "Resource": []string{
                    "arn:aws:s3:::my-bucket",
                    "arn:aws:s3:::my-bucket/*",
                },
                "Condition": map[string]interface{}{
                    "StringNotEquals": map[string]string{
                        "aws:SourceVpc": "vpc-111bbb22",
                    },
                },
            },
        },
    }

    vpcPolicyJSON, err := json.Marshal(vpcPolicy)
    if err != nil {
        log.Fatal(err)
    }

    _, err = client.PutBucketPolicy(context.TODO(), &s3.PutBucketPolicyInput{
        Bucket: aws.String("my-bucket"),
        Policy: aws.String(string(vpcPolicyJSON)),
    })
    if err != nil {
        log.Fatal(err)
    }

    // Example 3: Require MFA for delete operations
    mfaPolicy := map[string]interface{}{
        "Version": "2012-10-17",
        "Statement": []map[string]interface{}{
            {
                "Sid":    "RequireMFAForDelete",
                "Effect": "Deny",
                "Principal": "*",
                "Action": []string{
                    "s3:DeleteObject",
                    "s3:DeleteObjectVersion",
                },
                "Resource": "arn:aws:s3:::my-bucket/*",
                "Condition": map[string]interface{}{
                    "BoolIfExists": map[string]string{
                        "aws:MultiFactorAuthPresent": "false",
                    },
                },
            },
        },
    }

    mfaPolicyJSON, err := json.Marshal(mfaPolicy)
    if err != nil {
        log.Fatal(err)
    }

    _, err = client.PutBucketPolicy(context.TODO(), &s3.PutBucketPolicyInput{
        Bucket: aws.String("my-bucket"),
        Policy: aws.String(string(mfaPolicyJSON)),
    })
    if err != nil {
        log.Fatal(err)
    }

    // Example 4: Bucket owner full control for cross-account access
    crossAccountPolicy := map[string]interface{}{
        "Version": "2012-10-17",
        "Statement": []map[string]interface{}{
            {
                "Sid":    "DelegateS3Access",
                "Effect": "Allow",
                "Principal": map[string]string{
                    "AWS": "arn:aws:iam::123456789012:root",
                },
                "Action": []string{
                    "s3:ListBucket",
                    "s3:GetObject",
                },
                "Resource": []string{
                    "arn:aws:s3:::my-bucket",
                    "arn:aws:s3:::my-bucket/*",
                },
            },
        },
    }

    crossAccountPolicyJSON, err := json.Marshal(crossAccountPolicy)
    if err != nil {
        log.Fatal(err)
    }

    _, err = client.PutBucketPolicy(context.TODO(), &s3.PutBucketPolicyInput{
        Bucket: aws.String("my-bucket"),
        Policy: aws.String(string(crossAccountPolicyJSON)),
    })
    if err != nil {
        log.Fatal(err)
    }
}

DeleteBucketPolicy

Deletes the policy of a specified bucket.

Method Signature { .api }

func (c *Client) DeleteBucketPolicy(
    ctx context.Context,
    params *DeleteBucketPolicyInput,
    optFns ...func(*Options),
) (*DeleteBucketPolicyOutput, error)

DeleteBucketPolicyInput { .api }

type DeleteBucketPolicyInput struct {
    // The bucket name.
    // For directory buckets, use path-style requests.
    // Required: Yes
    Bucket *string

    // The account ID of the expected bucket owner.
    // Not supported for directory buckets.
    // Required: No
    ExpectedBucketOwner *string
}

DeleteBucketPolicyOutput { .api }

type DeleteBucketPolicyOutput struct {
    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Usage Example

package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    _, err = client.DeleteBucketPolicy(context.TODO(), &s3.DeleteBucketPolicyInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("Bucket policy deleted successfully")
}

GetBucketPolicyStatus

Retrieves the policy status for an Amazon S3 bucket, indicating whether the bucket is public.

Note: Not supported for directory buckets.

Method Signature { .api }

func (c *Client) GetBucketPolicyStatus(
    ctx context.Context,
    params *GetBucketPolicyStatusInput,
    optFns ...func(*Options),
) (*GetBucketPolicyStatusOutput, error)

GetBucketPolicyStatusInput { .api }

type GetBucketPolicyStatusInput struct {
    // The name of the Amazon S3 bucket whose policy status you want to retrieve.
    // Required: Yes
    Bucket *string

    // The account ID of the expected bucket owner.
    // Required: No
    ExpectedBucketOwner *string
}

GetBucketPolicyStatusOutput { .api }

type GetBucketPolicyStatusOutput struct {
    // The policy status for the specified bucket.
    PolicyStatus *types.PolicyStatus

    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

PolicyStatus { .api }

type PolicyStatus struct {
    // The policy status for this bucket. TRUE indicates that this bucket is public.
    // FALSE indicates that the bucket is not public.
    IsPublic *bool
}

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    output, err := client.GetBucketPolicyStatus(context.TODO(), &s3.GetBucketPolicyStatusInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        log.Fatal(err)
    }

    if output.PolicyStatus != nil && output.PolicyStatus.IsPublic != nil {
        if *output.PolicyStatus.IsPublic {
            fmt.Println("Bucket is PUBLIC")
        } else {
            fmt.Println("Bucket is NOT public")
        }
    }
}

ABAC (Attribute-Based Access Control) Operations

GetBucketAbac

Returns the attribute-based access control (ABAC) property of the general purpose bucket.

Note: Only for general purpose buckets. Whether ABAC is enabled or disabled, you can use tags for cost tracking.

Method Signature { .api }

func (c *Client) GetBucketAbac(
    ctx context.Context,
    params *GetBucketAbacInput,
    optFns ...func(*Options),
) (*GetBucketAbacOutput, error)

GetBucketAbacInput { .api }

type GetBucketAbacInput struct {
    // The name of the general purpose bucket.
    // Required: Yes
    Bucket *string

    // The Amazon Web Services account ID of the general purpose bucket's owner.
    // Required: No
    ExpectedBucketOwner *string
}

GetBucketAbacOutput { .api }

type GetBucketAbacOutput struct {
    // The ABAC status of the general purpose bucket.
    AbacStatus *types.AbacStatus

    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

AbacStatus { .api }

type AbacStatus struct {
    // The ABAC status of the general purpose bucket.
    // Values: Enabled | Disabled
    Status types.BucketAbacStatus
}

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    output, err := client.GetBucketAbac(context.TODO(), &s3.GetBucketAbacInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        log.Fatal(err)
    }

    if output.AbacStatus != nil {
        fmt.Printf("ABAC Status: %s\n", output.AbacStatus.Status)
    }
}

PutBucketAbac

Sets the attribute-based access control (ABAC) property of the general purpose bucket.

Note: When ABAC is enabled, you must use TagResource, UntagResource, and ListTagsForResource actions to manage bucket tags. PutBucketTagging and DeleteBucketTagging are no longer available.

Method Signature { .api }

func (c *Client) PutBucketAbac(
    ctx context.Context,
    params *PutBucketAbacInput,
    optFns ...func(*Options),
) (*PutBucketAbacOutput, error)

PutBucketAbacInput { .api }

type PutBucketAbacInput struct {
    // The ABAC status of the general purpose bucket.
    // Required: Yes
    AbacStatus *types.AbacStatus

    // The name of the general purpose bucket.
    // Required: Yes
    Bucket *string

    // Indicates the algorithm to create the checksum.
    // Values: CRC32 | CRC32C | SHA1 | SHA256
    // Required: No
    ChecksumAlgorithm types.ChecksumAlgorithm

    // The MD5 hash of the PutBucketAbac request body.
    // Required: No
    ContentMD5 *string

    // The Amazon Web Services account ID of the general purpose bucket's owner.
    // Required: No
    ExpectedBucketOwner *string
}

PutBucketAbacOutput { .api }

type PutBucketAbacOutput struct {
    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Usage Example

package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/service/s3/types"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    // Enable ABAC for the bucket
    _, err = client.PutBucketAbac(context.TODO(), &s3.PutBucketAbacInput{
        Bucket: aws.String("my-bucket"),
        AbacStatus: &types.AbacStatus{
            Status: types.BucketAbacStatusEnabled,
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("ABAC enabled for bucket")

    // Disable ABAC for the bucket
    _, err = client.PutBucketAbac(context.TODO(), &s3.PutBucketAbacInput{
        Bucket: aws.String("my-bucket"),
        AbacStatus: &types.AbacStatus{
            Status: types.BucketAbacStatusDisabled,
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("ABAC disabled for bucket")
}

Public Access Block Operations

GetPublicAccessBlock

Retrieves the PublicAccessBlock configuration for an Amazon S3 bucket.

Note: Not supported for directory buckets. Amazon S3 evaluates the most restrictive combination of bucket-level and account-level settings.

Method Signature { .api }

func (c *Client) GetPublicAccessBlock(
    ctx context.Context,
    params *GetPublicAccessBlockInput,
    optFns ...func(*Options),
) (*GetPublicAccessBlockOutput, error)

GetPublicAccessBlockInput { .api }

type GetPublicAccessBlockInput struct {
    // The name of the Amazon S3 bucket whose PublicAccessBlock configuration you
    // want to retrieve.
    // Required: Yes
    Bucket *string

    // The account ID of the expected bucket owner.
    // Required: No
    ExpectedBucketOwner *string
}

GetPublicAccessBlockOutput { .api }

type GetPublicAccessBlockOutput struct {
    // The PublicAccessBlock configuration currently in effect for this Amazon S3 bucket.
    PublicAccessBlockConfiguration *types.PublicAccessBlockConfiguration

    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

PublicAccessBlockConfiguration { .api }

type PublicAccessBlockConfiguration struct {
    // Specifies whether Amazon S3 should block public access control lists (ACLs)
    // for this bucket and objects in this bucket.
    // Setting to TRUE causes PUT Bucket ACL and PUT Object ACL calls with public
    // ACLs to fail.
    BlockPublicAcls *bool

    // Specifies whether Amazon S3 should block public bucket policies for this bucket.
    // Setting to TRUE causes Amazon S3 to reject calls to PUT Bucket policy if the
    // specified bucket policy allows public access.
    BlockPublicPolicy *bool

    // Specifies whether Amazon S3 should ignore public ACLs for this bucket and
    // objects in this bucket.
    // Setting to TRUE causes Amazon S3 to ignore all public ACLs on this bucket
    // and objects in this bucket.
    IgnorePublicAcls *bool

    // Specifies whether Amazon S3 should restrict public bucket policies for this bucket.
    // Setting to TRUE restricts access to this bucket to only AWS service principals
    // and authorized users within this account if the bucket has a public policy.
    RestrictPublicBuckets *bool
}

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    output, err := client.GetPublicAccessBlock(context.TODO(), &s3.GetPublicAccessBlockInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        log.Fatal(err)
    }

    if output.PublicAccessBlockConfiguration != nil {
        config := output.PublicAccessBlockConfiguration
        fmt.Printf("BlockPublicAcls: %v\n", aws.ToBool(config.BlockPublicAcls))
        fmt.Printf("BlockPublicPolicy: %v\n", aws.ToBool(config.BlockPublicPolicy))
        fmt.Printf("IgnorePublicAcls: %v\n", aws.ToBool(config.IgnorePublicAcls))
        fmt.Printf("RestrictPublicBuckets: %v\n", aws.ToBool(config.RestrictPublicBuckets))
    }
}

PutPublicAccessBlock

Creates or modifies the PublicAccessBlock configuration for an Amazon S3 bucket.

Note: Not supported for directory buckets.

Method Signature { .api }

func (c *Client) PutPublicAccessBlock(
    ctx context.Context,
    params *PutPublicAccessBlockInput,
    optFns ...func(*Options),
) (*PutPublicAccessBlockOutput, error)

PutPublicAccessBlockInput { .api }

type PutPublicAccessBlockInput struct {
    // The name of the Amazon S3 bucket whose PublicAccessBlock configuration you
    // want to set.
    // Required: Yes
    Bucket *string

    // The PublicAccessBlock configuration to apply.
    // Required: Yes
    PublicAccessBlockConfiguration *types.PublicAccessBlockConfiguration

    // Indicates the algorithm used to create the checksum.
    // Values: CRC32 | CRC32C | SHA1 | SHA256
    // Required: No
    ChecksumAlgorithm types.ChecksumAlgorithm

    // The MD5 hash of the PutPublicAccessBlock request body.
    // Required: No
    ContentMD5 *string

    // The account ID of the expected bucket owner.
    // Required: No
    ExpectedBucketOwner *string
}

PutPublicAccessBlockOutput { .api }

type PutPublicAccessBlockOutput struct {
    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Usage Example

package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/service/s3/types"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    // Example 1: Block all public access
    _, err = client.PutPublicAccessBlock(context.TODO(), &s3.PutPublicAccessBlockInput{
        Bucket: aws.String("my-bucket"),
        PublicAccessBlockConfiguration: &types.PublicAccessBlockConfiguration{
            BlockPublicAcls:       aws.Bool(true),
            BlockPublicPolicy:     aws.Bool(true),
            IgnorePublicAcls:      aws.Bool(true),
            RestrictPublicBuckets: aws.Bool(true),
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("All public access blocked")

    // Example 2: Block only public ACLs
    _, err = client.PutPublicAccessBlock(context.TODO(), &s3.PutPublicAccessBlockInput{
        Bucket: aws.String("my-bucket"),
        PublicAccessBlockConfiguration: &types.PublicAccessBlockConfiguration{
            BlockPublicAcls:       aws.Bool(true),
            BlockPublicPolicy:     aws.Bool(false),
            IgnorePublicAcls:      aws.Bool(true),
            RestrictPublicBuckets: aws.Bool(false),
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("Public ACLs blocked")

    // Example 3: Allow public access (not recommended for production)
    _, err = client.PutPublicAccessBlock(context.TODO(), &s3.PutPublicAccessBlockInput{
        Bucket: aws.String("my-bucket"),
        PublicAccessBlockConfiguration: &types.PublicAccessBlockConfiguration{
            BlockPublicAcls:       aws.Bool(false),
            BlockPublicPolicy:     aws.Bool(false),
            IgnorePublicAcls:      aws.Bool(false),
            RestrictPublicBuckets: aws.Bool(false),
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("Public access allowed")
}

DeletePublicAccessBlock

Removes the PublicAccessBlock configuration for an Amazon S3 bucket.

Note: Not supported for directory buckets.

Method Signature { .api }

func (c *Client) DeletePublicAccessBlock(
    ctx context.Context,
    params *DeletePublicAccessBlockInput,
    optFns ...func(*Options),
) (*DeletePublicAccessBlockOutput, error)

DeletePublicAccessBlockInput { .api }

type DeletePublicAccessBlockInput struct {
    // The Amazon S3 bucket whose PublicAccessBlock configuration you want to delete.
    // Required: Yes
    Bucket *string

    // The account ID of the expected bucket owner.
    // Required: No
    ExpectedBucketOwner *string
}

DeletePublicAccessBlockOutput { .api }

type DeletePublicAccessBlockOutput struct {
    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Usage Example

package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    _, err = client.DeletePublicAccessBlock(context.TODO(), &s3.DeletePublicAccessBlockInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("Public access block configuration deleted")
}

Bucket Ownership Controls Operations

GetBucketOwnershipControls

Retrieves OwnershipControls for an Amazon S3 bucket.

Note: Not supported for directory buckets. Buckets created before the BucketOwnerEnforced setting was introduced may not have OwnershipControls.

Method Signature { .api }

func (c *Client) GetBucketOwnershipControls(
    ctx context.Context,
    params *GetBucketOwnershipControlsInput,
    optFns ...func(*Options),
) (*GetBucketOwnershipControlsOutput, error)

GetBucketOwnershipControlsInput { .api }

type GetBucketOwnershipControlsInput struct {
    // The name of the Amazon S3 bucket whose OwnershipControls you want to retrieve.
    // Required: Yes
    Bucket *string

    // The account ID of the expected bucket owner.
    // Required: No
    ExpectedBucketOwner *string
}

GetBucketOwnershipControlsOutput { .api }

type GetBucketOwnershipControlsOutput struct {
    // The OwnershipControls (BucketOwnerEnforced, BucketOwnerPreferred, or
    // ObjectWriter) currently in effect for this Amazon S3 bucket.
    OwnershipControls *types.OwnershipControls

    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

OwnershipControls { .api }

type OwnershipControls struct {
    // The container element for an ownership control rule.
    // Required: Yes
    Rules []OwnershipControlsRule
}

OwnershipControlsRule { .api }

type OwnershipControlsRule struct {
    // The container element for object ownership.
    //
    // Values:
    // - BucketOwnerPreferred: Objects uploaded with bucket-owner-full-control
    //   canned ACL change ownership to the bucket owner.
    // - ObjectWriter: The uploading account owns the object when uploaded with
    //   bucket-owner-full-control canned ACL.
    // - BucketOwnerEnforced: ACLs are disabled. The bucket owner automatically
    //   owns and has full control over every object. The bucket only accepts
    //   PUT requests that don't specify an ACL or specify bucket owner full
    //   control ACLs.
    //
    // Required: Yes
    ObjectOwnership types.ObjectOwnership
}

Usage Example

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    output, err := client.GetBucketOwnershipControls(context.TODO(), &s3.GetBucketOwnershipControlsInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        log.Fatal(err)
    }

    if output.OwnershipControls != nil {
        for _, rule := range output.OwnershipControls.Rules {
            fmt.Printf("Object Ownership: %s\n", rule.ObjectOwnership)
        }
    }
}

PutBucketOwnershipControls

Creates or modifies OwnershipControls for an Amazon S3 bucket.

Note: Not supported for directory buckets.

Method Signature { .api }

func (c *Client) PutBucketOwnershipControls(
    ctx context.Context,
    params *PutBucketOwnershipControlsInput,
    optFns ...func(*Options),
) (*PutBucketOwnershipControlsOutput, error)

PutBucketOwnershipControlsInput { .api }

type PutBucketOwnershipControlsInput struct {
    // The name of the Amazon S3 bucket whose OwnershipControls you want to set.
    // Required: Yes
    Bucket *string

    // The OwnershipControls to apply to this Amazon S3 bucket.
    // Required: Yes
    OwnershipControls *types.OwnershipControls

    // Indicates the algorithm used to create the checksum.
    // Values: CRC32 | CRC32C | SHA1 | SHA256
    // Required: No
    ChecksumAlgorithm types.ChecksumAlgorithm

    // The MD5 hash of the OwnershipControls request body.
    // Required: No
    ContentMD5 *string

    // The account ID of the expected bucket owner.
    // Required: No
    ExpectedBucketOwner *string
}

PutBucketOwnershipControlsOutput { .api }

type PutBucketOwnershipControlsOutput struct {
    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Usage Example

package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/service/s3/types"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    // Example 1: Set BucketOwnerEnforced (disables ACLs)
    _, err = client.PutBucketOwnershipControls(context.TODO(), &s3.PutBucketOwnershipControlsInput{
        Bucket: aws.String("my-bucket"),
        OwnershipControls: &types.OwnershipControls{
            Rules: []types.OwnershipControlsRule{
                {
                    ObjectOwnership: types.ObjectOwnershipBucketOwnerEnforced,
                },
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("BucketOwnerEnforced ownership controls set (ACLs disabled)")

    // Example 2: Set BucketOwnerPreferred
    _, err = client.PutBucketOwnershipControls(context.TODO(), &s3.PutBucketOwnershipControlsInput{
        Bucket: aws.String("my-bucket"),
        OwnershipControls: &types.OwnershipControls{
            Rules: []types.OwnershipControlsRule{
                {
                    ObjectOwnership: types.ObjectOwnershipBucketOwnerPreferred,
                },
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("BucketOwnerPreferred ownership controls set")

    // Example 3: Set ObjectWriter
    _, err = client.PutBucketOwnershipControls(context.TODO(), &s3.PutBucketOwnershipControlsInput{
        Bucket: aws.String("my-bucket"),
        OwnershipControls: &types.OwnershipControls{
            Rules: []types.OwnershipControlsRule{
                {
                    ObjectOwnership: types.ObjectOwnershipObjectWriter,
                },
            },
        },
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("ObjectWriter ownership controls set")
}

DeleteBucketOwnershipControls

Removes OwnershipControls for an Amazon S3 bucket.

Note: Not supported for directory buckets.

Method Signature { .api }

func (c *Client) DeleteBucketOwnershipControls(
    ctx context.Context,
    params *DeleteBucketOwnershipControlsInput,
    optFns ...func(*Options),
) (*DeleteBucketOwnershipControlsOutput, error)

DeleteBucketOwnershipControlsInput { .api }

type DeleteBucketOwnershipControlsInput struct {
    // The Amazon S3 bucket whose OwnershipControls you want to delete.
    // Required: Yes
    Bucket *string

    // The account ID of the expected bucket owner.
    // Required: No
    ExpectedBucketOwner *string
}

DeleteBucketOwnershipControlsOutput { .api }

type DeleteBucketOwnershipControlsOutput struct {
    // Metadata pertaining to the operation's result.
    ResultMetadata middleware.Metadata
}

Usage Example

package main

import (
    "context"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    _, err = client.DeleteBucketOwnershipControls(context.TODO(), &s3.DeleteBucketOwnershipControlsInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("Bucket ownership controls deleted")
}

Comprehensive Policy Examples

Cross-Account Access with Conditions

package main

import (
    "context"
    "encoding/json"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    // Complex policy with multiple conditions
    complexPolicy := map[string]interface{}{
        "Version": "2012-10-17",
        "Statement": []map[string]interface{}{
            {
                "Sid":    "AllowCrossAccountReadWithIPRestriction",
                "Effect": "Allow",
                "Principal": map[string]string{
                    "AWS": "arn:aws:iam::123456789012:root",
                },
                "Action": []string{
                    "s3:GetObject",
                    "s3:ListBucket",
                },
                "Resource": []string{
                    "arn:aws:s3:::my-bucket",
                    "arn:aws:s3:::my-bucket/*",
                },
                "Condition": map[string]interface{}{
                    "IpAddress": map[string][]string{
                        "aws:SourceIp": {
                            "203.0.113.0/24",
                            "198.51.100.0/24",
                        },
                    },
                    "StringLike": map[string]string{
                        "s3:prefix": "public/*",
                    },
                },
            },
            {
                "Sid":    "RequireSSLForUploads",
                "Effect": "Deny",
                "Principal": "*",
                "Action":    "s3:*",
                "Resource": []string{
                    "arn:aws:s3:::my-bucket/*",
                },
                "Condition": map[string]interface{}{
                    "Bool": map[string]string{
                        "aws:SecureTransport": "false",
                    },
                },
            },
        },
    }

    policyJSON, err := json.Marshal(complexPolicy)
    if err != nil {
        log.Fatal(err)
    }

    _, err = client.PutBucketPolicy(context.TODO(), &s3.PutBucketPolicyInput{
        Bucket: aws.String("my-bucket"),
        Policy: aws.String(string(policyJSON)),
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("Complex policy applied successfully")
}

Tag-Based Access Control Policy

package main

import (
    "context"
    "encoding/json"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    // Tag-based access control policy
    tagBasedPolicy := map[string]interface{}{
        "Version": "2012-10-17",
        "Statement": []map[string]interface{}{
            {
                "Sid":    "AllowAccessBasedOnObjectTags",
                "Effect": "Allow",
                "Principal": map[string]string{
                    "AWS": "arn:aws:iam::123456789012:role/DevelopmentRole",
                },
                "Action": []string{
                    "s3:GetObject",
                    "s3:PutObject",
                },
                "Resource": "arn:aws:s3:::my-bucket/*",
                "Condition": map[string]interface{}{
                    "StringEquals": map[string]string{
                        "s3:ExistingObjectTag/Environment": "Development",
                    },
                },
            },
            {
                "Sid":    "AllowAccessBasedOnRequestTags",
                "Effect": "Allow",
                "Principal": map[string]string{
                    "AWS": "arn:aws:iam::123456789012:role/ProductionRole",
                },
                "Action": "s3:PutObject",
                "Resource": "arn:aws:s3:::my-bucket/*",
                "Condition": map[string]interface{}{
                    "StringEquals": map[string]string{
                        "s3:RequestObjectTag/Environment": "Production",
                    },
                },
            },
        },
    }

    policyJSON, err := json.Marshal(tagBasedPolicy)
    if err != nil {
        log.Fatal(err)
    }

    _, err = client.PutBucketPolicy(context.TODO(), &s3.PutBucketPolicyInput{
        Bucket: aws.String("my-bucket"),
        Policy: aws.String(string(policyJSON)),
    })
    if err != nil {
        log.Fatal(err)
    }

    log.Println("Tag-based policy applied successfully")
}

Related Operations

  • GetBucketTagging - Retrieve bucket tags (used with ABAC)
  • PutBucketTagging - Set bucket tags (disabled when ABAC is enabled)
  • GetObjectAcl - Retrieve object ACL
  • PutObjectAcl - Set object ACL
  • CreateBucket - Create a new bucket with access control settings
  • GetBucketLocation - Retrieve bucket region

Error Handling

Common errors when working with bucket access control operations:

  • NoSuchBucket - The specified bucket does not exist
  • AccessDenied - Insufficient permissions to perform the operation
  • InvalidBucketName - The bucket name is invalid
  • BucketAlreadyOwnedByYou - Bucket already exists and is owned by you
  • NoSuchConfiguration - The configuration does not exist
  • NotImplemented - Operation not supported for directory buckets

Error Handling Example

package main

import (
    "context"
    "errors"
    "log"

    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/s3"
    "github.com/aws/aws-sdk-go-v2/service/s3/types"
    "github.com/aws/aws-sdk-go-v2/aws"
)

func main() {
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Fatal(err)
    }

    client := s3.NewFromConfig(cfg)

    _, err = client.GetBucketPolicy(context.TODO(), &s3.GetBucketPolicyInput{
        Bucket: aws.String("my-bucket"),
    })
    if err != nil {
        var noSuchBucket *types.NoSuchBucket
        var noSuchConfig *types.NoSuchConfiguration

        if errors.As(err, &noSuchBucket) {
            log.Println("Bucket does not exist")
        } else if errors.As(err, &noSuchConfig) {
            log.Println("No bucket policy configured")
        } else {
            log.Fatal(err)
        }
    }
}

Best Practices

  1. Use Bucket Owner Enforced: For new buckets, set ObjectOwnership to BucketOwnerEnforced to disable ACLs and rely on bucket policies and IAM policies.

  2. Block Public Access: Enable all public access block settings by default unless you specifically need public access.

  3. Principle of Least Privilege: Grant only the minimum permissions required for users and applications.

  4. Use Bucket Policies Over ACLs: Bucket policies provide more granular control and are easier to manage than ACLs.

  5. Enable ABAC for Fine-Grained Control: Use ABAC with tags to implement attribute-based access control for more flexible permission management.

  6. Use ExpectedBucketOwner: Always include the ExpectedBucketOwner parameter to prevent accidental operations on wrong buckets.

  7. Require SSL/TLS: Include a policy statement that denies all requests not made over HTTPS.

  8. Regular Audits: Use GetBucketPolicyStatus regularly to check if your buckets are public.

  9. MFA Delete: For critical buckets, require MFA for delete operations using bucket policies.

  10. Version Control Policies: Store bucket policies in version control and treat them as infrastructure as code.

See Also

  • S3 Bucket Configuration Operations
  • S3 Object Operations
  • S3 Client Configuration
  • AWS IAM Best Practices
  • S3 Security Best Practices