tessl install tessl/golang-cloud-google-com-go-storage@1.59.0Google Cloud Storage client library for Go providing comprehensive APIs for bucket and object operations, access control, and advanced features
This document covers access control mechanisms including Access Control Lists (ACLs), IAM policies, signed URLs for time-limited access, and POST policies for browser-based uploads.
Manage fine-grained access control for buckets and objects.
/**
* ACLHandle provides operations on an access control list.
* Use BucketHandle.ACL() for bucket ACLs.
* Use BucketHandle.DefaultObjectACL() for default object ACLs.
* Use ObjectHandle.ACL() for object ACLs.
*/
type ACLHandle struct {
// contains filtered or unexported fields
}
/**
* Lists all ACL rules.
* @param ctx - Context for the operation
* @returns Slice of ACLRule and error
*/
func (a *ACLHandle) List(ctx context.Context) ([]ACLRule, error)
/**
* Sets the role for an entity.
* @param ctx - Context for the operation
* @param entity - ACL entity (user, group, domain, etc.)
* @param role - ACL role (OWNER, READER, WRITER)
* @returns Error if set fails
*/
func (a *ACLHandle) Set(ctx context.Context, entity ACLEntity, role ACLRole) error
/**
* Deletes the ACL entry for an entity.
* @param ctx - Context for the operation
* @param entity - ACL entity to delete
* @returns Error if delete fails
*/
func (a *ACLHandle) Delete(ctx context.Context, entity ACLEntity) errorTypes for defining access control rules.
/**
* ACLEntity refers to a user or group (grantee).
* Can be in the form of:
* - "user-<userId>" or "user-<email>"
* - "group-<groupId>" or "group-<email>"
* - "domain-<domain>"
* - "project-team-<projectId>"
* - Predefined: AllUsers, AllAuthenticatedUsers
*/
type ACLEntity string
/**
* ACLRole is the level of access to grant.
*/
type ACLRole string
// Predefined ACL entities
const (
// AllUsers grants access to anyone on the internet
AllUsers ACLEntity = "allUsers"
// AllAuthenticatedUsers grants access to any authenticated user
AllAuthenticatedUsers ACLEntity = "allAuthenticatedUsers"
)
// ACL roles
const (
// RoleOwner grants full control
RoleOwner ACLRole = "OWNER"
// RoleReader grants read access
RoleReader ACLRole = "READER"
// RoleWriter grants write access (buckets only)
RoleWriter ACLRole = "WRITER"
)
/**
* ACLRule represents a grant for a role to an entity.
*/
type ACLRule struct {
// Entity is the grantee (user, group, domain, etc.)
Entity ACLEntity
// EntityID is the ID for the entity (read-only)
EntityID string
// Role is the access level granted
Role ACLRole
// Domain is the domain for domain entities (read-only)
Domain string
// Email is the email for user/group entities (read-only)
Email string
// ProjectTeam is the project team info (read-only)
ProjectTeam *ProjectTeam
}
/**
* ProjectTeam is the project team associated with an entity.
*/
type ProjectTeam struct {
// ProjectNumber is the project number
ProjectNumber string
// Team is the team name (editors, owners, viewers)
Team string
}Usage Examples:
import (
"context"
"cloud.google.com/go/storage"
)
ctx := context.Background()
bucket := client.Bucket("my-bucket")
// List bucket ACL
rules, err := bucket.ACL().List(ctx)
if err != nil {
log.Fatal(err)
}
for _, rule := range rules {
fmt.Printf("Entity: %s, Role: %s\n", rule.Entity, rule.Role)
}
// Grant read access to a user
entity := storage.ACLEntity("user-alice@example.com")
err = bucket.ACL().Set(ctx, entity, storage.RoleReader)
if err != nil {
log.Fatal(err)
}
// Grant public read access
err = bucket.ACL().Set(ctx, storage.AllUsers, storage.RoleReader)
if err != nil {
log.Fatal(err)
}
// Revoke access
err = bucket.ACL().Delete(ctx, entity)
if err != nil {
log.Fatal(err)
}
// Set object ACL
obj := bucket.Object("my-object.txt")
err = obj.ACL().Set(ctx, storage.AllAuthenticatedUsers, storage.RoleReader)
// Set default object ACL (applied to new objects)
err = bucket.DefaultObjectACL().Set(ctx, storage.AllUsers, storage.RoleReader)Manage Identity and Access Management policies for buckets.
/**
* Returns an IAM handle for the bucket.
* IAM policies provide centralized access control.
* @returns iam.Handle for policy management
*/
func (b *BucketHandle) IAM() *iam.HandleNote: The IAM handle comes from cloud.google.com/go/iam package. Common IAM operations:
import (
"cloud.google.com/go/iam"
"cloud.google.com/go/iam/apiv1/iampb"
)
// Get IAM policy
handle := bucket.IAM()
policy, err := handle.Policy(ctx)
if err != nil {
log.Fatal(err)
}
// Add a member to a role
policy.Add("user:alice@example.com", "roles/storage.objectViewer")
// Set the updated policy
err = handle.SetPolicy(ctx, policy)
if err != nil {
log.Fatal(err)
}
// Test permissions
permissions := []string{
"storage.objects.get",
"storage.objects.list",
}
allowed, err := handle.TestPermissions(ctx, permissions)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Allowed permissions: %v\n", allowed)Generate time-limited URLs for restricted resource access without authentication.
/**
* Generates a signed URL for restricted resource access.
* Allows unauthenticated access for a limited time.
* @param bucket - Bucket name
* @param object - Object name
* @param opts - Signed URL options
* @returns Signed URL string and error
*/
func SignedURL(bucket, object string, opts *SignedURLOptions) (string, error)
/**
* Generates a signed URL via the bucket handle.
* Supports automatic credential detection.
* @param object - Object name
* @param opts - Signed URL options
* @returns Signed URL string and error
*/
func (b *BucketHandle) SignedURL(object string, opts *SignedURLOptions) (string, error)
/**
* SignedURLOptions configures signed URL generation.
*/
type SignedURLOptions struct {
// GoogleAccessID is the service account email address
// Required (unless auto-detected)
GoogleAccessID string
// PrivateKey is the service account private key (PEM format)
// Exactly one of PrivateKey or SignBytes must be provided
PrivateKey []byte
// SignBytes is a custom signing function
// Exactly one of PrivateKey or SignBytes must be provided
SignBytes func([]byte) ([]byte, error)
// Method is the HTTP method for the signed URL
// Valid values: GET, HEAD, PUT, POST, DELETE
// Required
Method string
// Expires is the expiration time
// Must be in the future
// For V4, maximum 7 days from now
// Required
Expires time.Time
// ContentType is the required Content-Type header
// Optional
ContentType string
// Headers are additional required headers
// Optional
Headers []string
// QueryParameters are additional query parameters
// Optional
QueryParameters url.Values
// MD5 is the required MD5 hash (base64-encoded)
// Optional
MD5 string
// Style configures the URL style
// Use URLStyle functions: PathStyle(), VirtualHostedStyle(), BucketBoundHostname()
// Optional
Style *URLStyle
// Insecure allows HTTP instead of HTTPS
// Not recommended for production
// Optional
Insecure bool
// Scheme is the signing scheme (V2 or V4)
// V4 is recommended
// Optional (defaults to V2 for compatibility)
Scheme SigningScheme
// Hostname is a custom hostname for the URL
// Optional (defaults to storage.googleapis.com)
Hostname string
}
/**
* SigningScheme determines the version of signed URL.
*/
type SigningScheme int
const (
// SigningSchemeV2 uses V2 signing (deprecated)
SigningSchemeV2 SigningScheme = iota
// SigningSchemeV4 uses V4 signing (recommended)
SigningSchemeV4
)
/**
* URLStyle configures the URL format.
*/
type URLStyle struct {
// contains filtered or unexported fields
}
/**
* Returns path-style URL configuration.
* Format: https://storage.googleapis.com/bucket/object
* @returns URLStyle for path-style URLs
*/
func PathStyle() *URLStyle
/**
* Returns virtual-hosted-style URL configuration.
* Format: https://bucket.storage.googleapis.com/object
* @returns URLStyle for virtual-hosted-style URLs
*/
func VirtualHostedStyle() *URLStyle
/**
* Returns custom hostname URL configuration.
* Format: https://custom.example.com/object
* @param hostname - Custom hostname
* @returns URLStyle for custom hostname URLs
*/
func BucketBoundHostname(hostname string) *URLStyleUsage Examples:
import (
"time"
"cloud.google.com/go/storage"
)
// Generate signed URL for download (GET)
opts := &storage.SignedURLOptions{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
PrivateKey: privateKeyBytes, // Load from key file
Method: "GET",
Expires: time.Now().Add(15 * time.Minute),
}
url, err := storage.SignedURL("my-bucket", "my-object.txt", opts)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Download URL: %s\n", url)
// Generate signed URL for upload (PUT)
opts = &storage.SignedURLOptions{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
PrivateKey: privateKeyBytes,
Method: "PUT",
Expires: time.Now().Add(1 * time.Hour),
ContentType: "image/jpeg",
}
url, err = storage.SignedURL("my-bucket", "upload.jpg", opts)
// Use V4 signing (recommended)
opts = &storage.SignedURLOptions{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
PrivateKey: privateKeyBytes,
Method: "GET",
Expires: time.Now().Add(24 * time.Hour),
Scheme: storage.SigningSchemeV4,
}
url, err = storage.SignedURL("my-bucket", "my-object.txt", opts)
// Use virtual-hosted-style URL
opts = &storage.SignedURLOptions{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
PrivateKey: privateKeyBytes,
Method: "GET",
Expires: time.Now().Add(1 * time.Hour),
Style: storage.VirtualHostedStyle(),
}
url, err = storage.SignedURL("my-bucket", "my-object.txt", opts)
// Use custom hostname
opts = &storage.SignedURLOptions{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
PrivateKey: privateKeyBytes,
Method: "GET",
Expires: time.Now().Add(1 * time.Hour),
Style: storage.BucketBoundHostname("cdn.example.com"),
}
url, err = storage.SignedURL("my-bucket", "my-object.txt", opts)
// Auto-detect credentials (using bucket handle)
bucket := client.Bucket("my-bucket")
opts = &storage.SignedURLOptions{
Method: "GET",
Expires: time.Now().Add(15 * time.Minute),
}
url, err = bucket.SignedURL("my-object.txt", opts)
// GoogleAccessID and PrivateKey are auto-detected from client credentials
// With custom signing function (e.g., for App Engine)
opts = &storage.SignedURLOptions{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
SignBytes: func(b []byte) ([]byte, error) {
// Custom signing logic (e.g., using KMS, HSM, etc.)
return signFunction(b)
},
Method: "GET",
Expires: time.Now().Add(1 * time.Hour),
}
url, err = storage.SignedURL("my-bucket", "my-object.txt", opts)Generate POST policies for browser-based file uploads.
/**
* Generates a PostPolicyV4 for browser-based uploads.
* Allows unauthenticated multipart form uploads.
* @param bucket - Bucket name
* @param object - Object name (empty string with prefix condition for variable names)
* @param opts - POST policy options
* @returns PostPolicyV4 and error
*/
func GenerateSignedPostPolicyV4(bucket, object string, opts *PostPolicyV4Options) (*PostPolicyV4, error)
/**
* Generates a PostPolicyV4 via the bucket handle.
* Supports automatic credential detection.
* @param object - Object name
* @param opts - POST policy options
* @returns PostPolicyV4 and error
*/
func (b *BucketHandle) GenerateSignedPostPolicyV4(object string, opts *PostPolicyV4Options) (*PostPolicyV4, error)
/**
* PostPolicyV4Options configures POST policy generation.
*/
type PostPolicyV4Options struct {
// GoogleAccessID is the service account email address
// Required (unless auto-detected)
GoogleAccessID string
// PrivateKey is the service account private key (PEM format)
// Exactly one of PrivateKey, SignBytes, or SignRawBytes must be provided
PrivateKey []byte
// SignBytes is a custom signing function
SignBytes func([]byte) ([]byte, error)
// SignRawBytes is a custom raw signing function
SignRawBytes func([]byte) ([]byte, error)
// Expires is the expiration time
// Must be in the future, maximum 7 days from now
// Required
Expires time.Time
// Fields are form fields to include in the policy
// Optional
Fields *PolicyV4Fields
// Conditions are policy conditions
// Optional
Conditions []PostPolicyV4Condition
// Hostname is a custom hostname
// Optional (defaults to storage.googleapis.com)
Hostname string
// Style configures the URL style
// Optional
Style *URLStyle
}
/**
* PolicyV4Fields contains form fields for the POST form.
*/
type PolicyV4Fields struct {
// ACL is the access control list
ACL string
// CacheControl is the Cache-Control header
CacheControl string
// ContentType is the Content-Type header
ContentType string
// ContentDisposition is the Content-Disposition header
ContentDisposition string
// ContentEncoding is the Content-Encoding header
ContentEncoding string
// Expires is the Expires header
Expires time.Time
// SuccessActionRedirect is the redirect URL after successful upload
SuccessActionRedirect string
// SuccessActionStatus is the HTTP status code to return after successful upload
SuccessActionStatus int
// Metadata is custom metadata
Metadata map[string]string
}
/**
* PostPolicyV4Condition represents a policy condition.
*/
type PostPolicyV4Condition interface {
// contains filtered or unexported methods
}
/**
* Creates a condition that a field starts with a prefix.
* @param key - Form field name
* @param prefix - Required prefix
* @returns PostPolicyV4Condition
*/
func ConditionStartsWith(key, prefix string) PostPolicyV4Condition
/**
* Creates a content-length range condition.
* @param start - Minimum length in bytes
* @param end - Maximum length in bytes
* @returns PostPolicyV4Condition
*/
func ConditionContentLengthRange(start, end uint64) PostPolicyV4Condition
/**
* PostPolicyV4 contains the generated POST policy.
*/
type PostPolicyV4 struct {
// URL is the form action URL
URL string
// Fields are the hidden form fields to include
Fields map[string]string
}Usage Examples:
import (
"time"
"cloud.google.com/go/storage"
)
// Generate POST policy for file upload
opts := &storage.PostPolicyV4Options{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
PrivateKey: privateKeyBytes,
Expires: time.Now().Add(30 * time.Minute),
}
policy, err := storage.GenerateSignedPostPolicyV4("my-bucket", "upload.jpg", opts)
if err != nil {
log.Fatal(err)
}
// Use in HTML form
html := fmt.Sprintf(`
<form action="%s" method="post" enctype="multipart/form-data">
<input type="hidden" name="key" value="%s">
<input type="hidden" name="x-goog-signature" value="%s">
<input type="hidden" name="x-goog-algorithm" value="%s">
<input type="hidden" name="x-goog-credential" value="%s">
<input type="hidden" name="x-goog-date" value="%s">
<input type="hidden" name="policy" value="%s">
<input type="file" name="file">
<input type="submit" value="Upload">
</form>
`, policy.URL, policy.Fields["key"], policy.Fields["x-goog-signature"],
policy.Fields["x-goog-algorithm"], policy.Fields["x-goog-credential"],
policy.Fields["x-goog-date"], policy.Fields["policy"])
// POST policy with metadata
opts = &storage.PostPolicyV4Options{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
PrivateKey: privateKeyBytes,
Expires: time.Now().Add(1 * time.Hour),
Fields: &storage.PolicyV4Fields{
ContentType: "image/jpeg",
Metadata: map[string]string{
"uploaded-by": "web-form",
},
},
}
policy, err = storage.GenerateSignedPostPolicyV4("my-bucket", "photo.jpg", opts)
// POST policy with conditions
opts = &storage.PostPolicyV4Options{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
PrivateKey: privateKeyBytes,
Expires: time.Now().Add(1 * time.Hour),
Conditions: []storage.PostPolicyV4Condition{
storage.ConditionContentLengthRange(0, 10*1024*1024), // Max 10MB
storage.ConditionStartsWith("$key", "uploads/"),
},
}
policy, err = storage.GenerateSignedPostPolicyV4("my-bucket", "", opts)
// POST policy with variable object name
opts = &storage.PostPolicyV4Options{
GoogleAccessID: "service-account@project.iam.gserviceaccount.com",
PrivateKey: privateKeyBytes,
Expires: time.Now().Add(1 * time.Hour),
Conditions: []storage.PostPolicyV4Condition{
storage.ConditionStartsWith("$key", "user-uploads/"),
},
}
// Empty object name allows any name matching conditions
policy, err = storage.GenerateSignedPostPolicyV4("my-bucket", "", opts)
// Auto-detect credentials (using bucket handle)
bucket := client.Bucket("my-bucket")
opts = &storage.PostPolicyV4Options{
Expires: time.Now().Add(30 * time.Minute),
Fields: &storage.PolicyV4Fields{
ContentType: "text/plain",
},
}
policy, err = bucket.GenerateSignedPostPolicyV4("upload.txt", opts)HMAC keys for S3-compatible authentication.
/**
* Creates a new HMAC key for the service account.
* @param ctx - Context for the operation
* @param projectID - Google Cloud project ID
* @param serviceAccountEmail - Service account email
* @param opts - Optional HMAC key options
* @returns HMACKey and error
*/
func (c *Client) CreateHMACKey(ctx context.Context, projectID, serviceAccountEmail string, opts ...HMACKeyOption) (*HMACKey, error)
/**
* Returns a handle to an HMAC key.
* @param projectID - Google Cloud project ID
* @param accessID - HMAC key access ID
* @returns HMACKeyHandle
*/
func (c *Client) HMACKeyHandle(projectID, accessID string) *HMACKeyHandle
/**
* Returns an iterator over HMAC keys.
* @param ctx - Context for the operation
* @param projectID - Google Cloud project ID
* @param opts - Optional filter options
* @returns HMACKeysIterator
*/
func (c *Client) ListHMACKeys(ctx context.Context, projectID string, opts ...HMACKeyOption) *HMACKeysIterator
/**
* HMACKey contains HMAC key information.
*/
type HMACKey struct {
// Secret is the secret key (only returned on creation)
Secret string
// AccessID is the access ID (public)
AccessID string
// Etag is the entity tag (read-only)
Etag string
// ID is the HMAC key identifier
ID string
// ProjectID is the project ID
ProjectID string
// ServiceAccountEmail is the service account email
ServiceAccountEmail string
// CreatedTime is the creation time (read-only)
CreatedTime time.Time
// UpdatedTime is the last update time (read-only)
UpdatedTime time.Time
// State is the key state (Active, Inactive, Deleted)
State HMACState
}
/**
* HMACKeyHandle provides operations on an HMAC key.
*/
type HMACKeyHandle struct {
// contains filtered or unexported fields
}
/**
* Retrieves the HMAC key metadata.
* @param ctx - Context for the operation
* @param opts - Optional HMAC key options
* @returns HMACKey and error
*/
func (h *HMACKeyHandle) Get(ctx context.Context, opts ...HMACKeyOption) (*HMACKey, error)
/**
* Updates the HMAC key.
* @param ctx - Context for the operation
* @param attrs - Attributes to update
* @param opts - Optional HMAC key options
* @returns Updated HMACKey and error
*/
func (h *HMACKeyHandle) Update(ctx context.Context, attrs HMACKeyAttrsToUpdate, opts ...HMACKeyOption) (*HMACKey, error)
/**
* Deletes the HMAC key.
* Key must be inactive before deletion.
* @param ctx - Context for the operation
* @param opts - Optional HMAC key options
* @returns Error if deletion fails
*/
func (h *HMACKeyHandle) Delete(ctx context.Context, opts ...HMACKeyOption) error
/**
* HMACKeyAttrsToUpdate specifies HMAC key attributes to update.
*/
type HMACKeyAttrsToUpdate struct {
// State is the key state to set
// Valid values: Active, Inactive
State HMACState
// Etag is the entity tag for concurrency control
Etag string
}
/**
* HMACState represents the state of an HMAC key.
*/
type HMACState string
const (
// Active key state
Active HMACState = "ACTIVE"
// Inactive key state
Inactive HMACState = "INACTIVE"
// Deleted key state (read-only)
Deleted HMACState = "DELETED"
)
/**
* HMACKeysIterator is an iterator over HMAC keys.
*/
type HMACKeysIterator struct {
// contains filtered or unexported fields
}
/**
* Returns the next HMAC key. Returns iterator.Done when complete.
* @returns HMACKey and error
*/
func (it *HMACKeysIterator) Next() (*HMACKey, error)
/**
* Returns pagination information.
* @returns iterator.PageInfo
*/
func (it *HMACKeysIterator) PageInfo() *iterator.PageInfo
/**
* HMACKeyOption configures HMAC key operations.
*/
type HMACKeyOption interface {
// contains filtered or unexported methods
}
/**
* Filters HMAC keys by service account.
* @param email - Service account email
* @returns HMACKeyOption
*/
func ForHMACKeyServiceAccountEmail(email string) HMACKeyOption
/**
* Includes deleted keys in listing.
* @returns HMACKeyOption
*/
func ShowDeletedHMACKeys() HMACKeyOption
/**
* Bills HMAC key requests against the specified user project.
* @param userProjectID - Project ID to bill
* @returns HMACKeyOption
*/
func UserProjectForHMACKeys(userProjectID string) HMACKeyOptionUsage Examples:
import (
"cloud.google.com/go/storage"
"google.golang.org/api/iterator"
)
ctx := context.Background()
// Create HMAC key
key, err := client.CreateHMACKey(ctx, "my-project", "service-account@my-project.iam.gserviceaccount.com")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Access ID: %s\n", key.AccessID)
fmt.Printf("Secret: %s\n", key.Secret) // Only available on creation
fmt.Printf("State: %s\n", key.State)
// List HMAC keys
it := client.ListHMACKeys(ctx, "my-project")
for {
key, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
log.Fatal(err)
}
fmt.Printf("Key: %s, State: %s\n", key.AccessID, key.State)
}
// List keys for specific service account
it = client.ListHMACKeys(ctx, "my-project",
storage.ForHMACKeyServiceAccountEmail("service-account@my-project.iam.gserviceaccount.com"))
// Get HMAC key
handle := client.HMACKeyHandle("my-project", "access-id")
key, err = handle.Get(ctx)
if err != nil {
log.Fatal(err)
}
// Deactivate HMAC key
update := storage.HMACKeyAttrsToUpdate{
State: storage.Inactive,
}
key, err = handle.Update(ctx, update)
if err != nil {
log.Fatal(err)
}
// Delete HMAC key (must be inactive first)
err = handle.Delete(ctx)
if err != nil {
log.Fatal(err)
}
// List including deleted keys
it = client.ListHMACKeys(ctx, "my-project", storage.ShowDeletedHMACKeys())