10.2 Cloud Storage Security & Access Controls
Key Takeaways
Uniform Bucket-Level Access (UBLA) disables legacy object-level ACLs, unifying all access management exclusively through Cloud IAM.
Public Access Prevention (PAP) enforces organization- or bucket-level blocks against granting permissions to allUsers or allAuthenticatedUsers, preventing public internet data leaks.
Signed URLs provide time-limited, cryptographically delegated read or write access to specific objects for external users without requiring Google accounts.
Signed Policy Documents allow secure, direct browser-to-bucket uploads with strict constraints on file size, content type, and key prefixes.
Cross-Origin Resource Sharing (CORS) must be configured on buckets to allow client-side web applications running in external browser domains to fetch or upload objects.
Cloud Storage Security & Access Controls
Core Focus: Cloud Storage serves as the primary landing zone and data lake repository for Google Cloud analytical architectures. Protecting stored objects against accidental public exposure, unauthorized internal access, and data tampering requires a thorough understanding of bucket access control models. The Google Cloud Associate Data Practitioner examination heavily tests Uniform Bucket-Level Access (UBLA), Public Access Prevention (PAP), time-limited delegated access via Signed URLs, and Cross-Origin Resource Sharing (CORS).
In enterprise data platforms, Cloud Storage stores raw ingestion drops, transactional database backups, uncompressed event archives, and intermediate machine learning artifacts. Securing this foundational storage layer requires balancing strict governance with operational usability—enabling automated ingestion jobs and external partner sharing without exposing sensitive data to the public internet or creating administrative overhead.
Access Control Models: Uniform Bucket-Level Access vs. Fine-Grained Access
Google Cloud Storage supports two distinct access control models for buckets: Uniform Bucket-Level Access (UBLA) and Fine-Grained Access.
+-----------------------------------------------------------------------------------+
| Cloud Storage Access Control Models |
| |
| [ Uniform Bucket-Level Access (UBLA) ] [ Fine-Grained Access (Legacy) ] |
| - Disables object-level ACLs - Combines Cloud IAM + Object ACLs |
| - All permissions managed via Cloud IAM - Grants per-object permissions |
| - Required for IAM Conditions & Org Policy - Creates auditing blind spots |
| - Recommended Google Cloud Best Practice - High administrative complexity |
+-----------------------------------------------------------------------------------+
1. Uniform Bucket-Level Access (UBLA)
Uniform Bucket-Level Access unifies and simplifies access management by disabling object-level Access Control Lists (ACLs) across the entire bucket.
- Exclusively IAM-Driven: All authorization decisions are evaluated strictly through Google Cloud IAM policies at the bucket, project, folder, or organization level.
- Consistent Security Posture: Individual objects inside the bucket cannot have custom or divergent permissions. If a user has
roles/storage.objectVieweron the bucket, they can read every object in that bucket. - Support for Advanced IAM Features: UBLA is required to use modern IAM security controls, such as IAM Conditions (e.g., granting read access only to objects starting with prefix
financial_reports/2026/, or restricting access to specific business hours). - Lock-in Period: Once UBLA has been enabled continuously on a bucket for 90 days, it becomes permanently locked and cannot be disabled. This ensures compliance teams that legacy ACLs cannot be reintroduced.
Google Cloud Recommendation: Always enable Uniform Bucket-Level Access on all new buckets. It represents the enterprise standard for data governance, simplifying security auditing and eliminating unintended permission drift caused by object-level ACLs.
2. Fine-Grained Access (Legacy Model)
Fine-Grained Access is the legacy Cloud Storage access model where permissions can be specified using both Cloud IAM and object-level Access Control Lists (ACLs).
- Object-Level ACLs: An ACL is a list of permission entries attached directly to an individual object, specifying an identity (a user, group, or domain) and an access level (
READER,WRITER, orOWNER). - When It Is Used: Fine-Grained access is only appropriate in legacy systems where individual objects within the same bucket require completely different access rules that cannot be organized into separate buckets or handled via IAM Conditions.
- Operational Pitfalls: Fine-Grained access introduces significant security risks. Auditing permissions requires scanning metadata on millions of individual objects rather than inspecting a single bucket IAM policy. Furthermore, when users upload objects using different service accounts, object ownership can become fragmented, preventing project administrators from accessing objects uploaded by external accounts unless bucket-owner-full-control flags are applied.
Public Access Prevention (PAP)
One of the most dangerous misconfigurations in cloud storage is accidentally granting read access to the general public. In Google Cloud, public access occurs when a bucket or object grants permissions to either of two special identifiers:
allUsers: Anyone on the public internet, whether authenticated or anonymous.allAuthenticatedUsers: Any entity authenticated with a valid Google account (including personal@gmail.comaccounts worldwide).
+-------------------------------------------------------------------------+
| Public Access Prevention (PAP) |
| |
| Bucket IAM Request: Grant roles/storage.objectViewer to 'allUsers' |
| | |
| v |
| [ PAP Enforcement Check ] |
| | |
| +----------------------+----------------------+ |
| | (PAP Enforced) | (Inherited) |
| v v |
| [ BLOCKED ] [ ALLOWED ] |
| Request rejected with Public access permitted |
| security policy error (High security risk) |
+-------------------------------------------------------------------------+
Operational Mechanics of PAP
Public Access Prevention (PAP) provides a fail-safe security mechanism to ensure data cannot be inadvertently exposed to the public internet:
- Enforcement Levels: PAP can be enforced at the individual bucket level or enforced hierarchically across an entire organization or folder using the Organization Policy constraint
storage.publicAccessPrevention. - Action on Violation: When PAP is
enforcedon a bucket:- Any existing IAM bindings or ACLs granting permissions to
allUsersorallAuthenticatedUsersare immediately neutralized and ignored. - Any new API request attempting to grant permissions to
allUsersorallAuthenticatedUsersfails with an authorization error.
- Any existing IAM bindings or ACLs granting permissions to
- Preserving Authorized Access: Enforcing PAP does not block legitimate authorized access. Internal users, service accounts, and third parties authenticated via IAM or cryptographic Signed URLs continue to access the bucket normally.
Temporary & Delegated Access: Signed URLs & Policy Documents
Data pipelines frequently need to share objects with external clients, partners, or web applications who do not have Google Cloud identities or service accounts. Opening the bucket to the public is unacceptable. Cloud Storage resolves this through Signed URLs and Signed Policy Documents.
+-----------------------------------------------------------------------------------------+
| Signed URL Flow |
| |
| [ Application Server ] ---> Generates Signed URL using Service Account Private Key |
| | (Sets: Bucket, Object, HTTP Method, Expiration Window) |
| v |
| [ External Client / Partner ] (No Google Account Required) |
| | |
| v |
| HTTP GET/PUT with Cryptographic Signature ---> [ Cloud Storage ] |
| (Validates Signature & Expiration) |
+-----------------------------------------------------------------------------------------+
1. Signed URLs
A Signed URL is a time-limited URL that carries authentication information in its query parameters, signed with the cryptographic private key of a Google Cloud Service Account.
Key Characteristics of Signed URLs
- No Google Account Needed: Anyone who possesses the signed URL can execute the specified HTTP action (
GETto download,PUTto upload,DELETEto remove) on the specific object. - Time-Bound Validity: The URL is configured with an explicit expiration window. With modern V4 signing, the maximum duration can be up to 7 days (168 hours). Best practice recommends setting the expiration to minutes or hours (e.g., 15 minutes for a download link).
- Delegated Authority: The signed URL carries only the authority of the signing service account. If the signing service account lacks
roles/storage.objectVieweron the bucket, a signedGETURL will return anHTTP 403 Forbiddenerror when invoked. - Bypassing Public Access Prevention: Signed URLs function seamlessly on buckets where Public Access Prevention is enforced. This is because the request is authenticated via the cryptographic signature of the service account, not anonymous
allUsersaccess.
2. Signed Policy Documents (Browser POST Uploads)
When a web or mobile application needs to allow users to upload files directly into Cloud Storage without streaming massive files through backend application servers, data architects leverage Signed Policy Documents.
- Mechanism: The backend server generates an HTML form policy document encoded in Base64 and signed by a service account.
- Client Execution: The user's web browser uploads the file directly to Cloud Storage via an
HTTP POSTrequest containing the signed policy document. - Enforced Constraints: Unlike a simple PUT signed URL, a policy document enforces strict upload conditions:
content-length-range: Enforces minimum and maximum allowable file sizes (preventing malicious users from exhausting storage quotas).aclandsuccess_action_redirect: Dictates resulting permissions and redirect endpoints.starts-with: Restricts upload destinations to a specific directory prefix (e.g.,uploads/user_123/).
Cross-Origin Resource Sharing (CORS)
By default, web browsers enforce the Same-Origin Policy, which blocks web pages hosted on one origin (e.g., https://dashboard.example.com) from making direct XMLHttpRequest or Fetch API requests to a different origin (such as https://storage.googleapis.com).
+-------------------------------------------------------------------------+
| Cross-Origin Resource Sharing (CORS) |
| |
| Browser (https://analytics.example.com) |
| | |
| | 1. HTTP OPTIONS Preflight Request |
| v |
| Cloud Storage Bucket |
| | |
| | 2. Checks CORS Configuration: |
| | - Allowed Origin: https://analytics.example.com |
| | - Allowed Method: GET, PUT |
| | - Max-Age: 3600 seconds |
| v |
| Browser executes direct upload / download |
+-------------------------------------------------------------------------+
Configuring CORS on Cloud Storage
When web dashboards or analytical portals need to display images, download CSV reports, or upload datasets directly to a bucket from the client browser, a CORS configuration must be applied to the bucket.
A CORS configuration is a JSON file applied via the gcloud storage buckets update command:
[
{
"origin": ["https://analytics.example.com"],
"method": ["GET", "PUT", "OPTIONS"],
"responseHeader": ["Content-Type", "x-goog-meta-*"],
"maxAgeSeconds": 3600
}
]
origin: The list of external domains permitted to make cross-origin requests. Never use wildcard*in production environments handling sensitive data.method: The allowed HTTP verbs (e.g.,GET,PUT,POST,OPTIONS).responseHeader: Custom headers the browser is permitted to read in Cloud Storage responses.maxAgeSeconds: The duration the browser can cache the preflightOPTIONSresponse, reducing request latency.
Common Exam Traps & Real-World Scenarios
Trap 1: Attempting to Modify Object ACLs on a UBLA Bucket
- The Scenario: An administrator runs
gcloud storage objects update gs://my-bucket/file.csv --add-acl-grant=...on a bucket that has Uniform Bucket-Level Access enabled. - The Trap: Expecting the ACL to apply successfully.
- The Reality: Cloud Storage immediately rejects the request with an error:
Cannot use ACLs when uniform bucket-level access is enabled. Under UBLA, all permissions must be granted via IAM at the bucket level or higher.
Trap 2: Believing Public Access Prevention Blocks Signed URLs
- The Scenario: A company enforces Public Access Prevention on all buckets to prevent data leaks. A partner needs temporary access to download a 5 GB export file.
- The Trap: Recommending that the administrator temporarily disable Public Access Prevention to allow the partner to download the file.
- The Reality: Disabling PAP is completely unnecessary and introduces severe security vulnerabilities. Signed URLs function perfectly while PAP is enforced because access is authorized via the service account's cryptographic signature, not anonymous public access.
Trap 3: Confusing allAuthenticatedUsers with Internal Corporate Employees
- The Scenario: A junior engineer wants all company employees to have read access to a shared raw data bucket, so they grant
roles/storage.objectViewertoallAuthenticatedUsers. - The Trap: Assuming
allAuthenticatedUsersrefers to authenticated members of the corporate Google Workspace domain. - The Reality:
allAuthenticatedUsersincludes anyone in the world authenticated with any Google account (including personal consumer Gmail accounts). To restrict access to corporate employees, permissions must be granted to the corporate Google Group (e.g.,data-team@company.com) or the Google Workspace domain (domain:company.com).
An external financial auditing firm needs to inspect a 20 GB transactional audit log stored in a private Cloud Storage bucket in the 'finance-analytics' project. The auditors do not have Google Cloud identities or corporate Google accounts. The compliance policy strictly requires that the bucket remain completely protected against public internet exposure and that the auditors' access automatically terminates after 6 hours. Which approach fulfills these requirements?
Generate a time-limited Signed URL valid for 6 hours using a service account that holds roles/storage.objectViewer permissions on the bucket, and provide the URL to the auditors.
Switch the bucket from Uniform Bucket-Level Access to Fine-Grained access and attach an object ACL granting READER permissions to the auditing firm's public IP address.
Disable Public Access Prevention on the bucket and grant roles/storage.objectViewer to allUsers with an IAM condition expiring in 6 hours.
Grant the auditing firm temporary roles/viewer access to the parent Google Cloud project, and configure a Cloud Scheduler job to remove the binding after 6 hours.
An enterprise organization policy mandates that all cloud storage assets must have legacy object-level Access Control Lists (ACLs) permanently disabled to ensure centralized access control and auditability strictly through Google Cloud IAM. Which feature must be configured on all storage buckets?
Customer-Managed Encryption Keys (CMEK)
Cross-Origin Resource Sharing (CORS)
Uniform Bucket-Level Access (UBLA)
Public Access Prevention (PAP)
A data analytics single-page web application hosted at 'https://bi.example.com' allows internal users to download generated CSV reports directly from a private Cloud Storage bucket. Although users authenticate successfully to the web application, their browser download requests fail with a client-side JavaScript preflight network error. What configuration must be applied to the Cloud Storage bucket to resolve this issue?
Switch the bucket access control model from Uniform Bucket-Level Access to Fine-Grained access.
Disable Public Access Prevention on the bucket so browsers can download the reports.
Grant roles/storage.objectAdmin to allAuthenticatedUsers on the target bucket.
Add a CORS configuration allowing origin 'https://bi.example.com' with the GET method.
Sections you finish are checked off in the contents.