Private Cloud Storage downloads for Bubble: signed URLs, proxy downloads, or Google sign-in?

A client portal requests one private document through an authorization gate before a temporary path opens to cloud storage.

The short answer

A private file needs a private delivery decision every time it is requested. Do not store a permanent public object URL in Bubble and assume that hiding the field is enough. First authorize the current user against the current organization and file record. Then choose a delivery method that matches the audience and the amount of control the application needs.

For most customer portals, the realistic choices are a short-lived Cloud Storage signed URL or an application-controlled proxy download. Google-authenticated browser downloads can work for an internal workforce whose Google identities already have Cloud Storage permissions, but they are usually a poor fit for customers who sign into the Bubble application rather than Google Cloud.

This download question is separate from upload architecture. An upload can be correct while the later read path is too broad, too long-lived, or difficult to revoke.

Start with application authorization

Bubble knows the application user, the organization they belong to, and the record they are trying to open. Cloud Storage knows buckets, objects, and Google principals. A useful download boundary connects those two worlds without trusting a browser-supplied tenant ID or object name.

A request should begin with a stable application file ID, not a raw bucket path. A server-side component can then:

  1. authenticate the Bubble request;

  2. load the file record and its owning organization;

  3. verify that the current user may read that record;

  4. resolve the approved bucket and object name from trusted data;

  5. check file state, such as active, quarantined, retained, or deleted;

  6. issue or stream the download using the selected delivery method;

  7. record a bounded access event without logging the download credential.

This ordering matters. A signed URL is not an authorization check. It is the result of one. Google documents signed URLs as time-limited access to a specific Cloud Storage resource and notes that anyone who possesses the URL can use it while it remains active. Treat the URL as a temporary bearer credential, keep its lifetime short, and avoid placing it in logs or analytics payloads.

Option 1: issue a short-lived signed URL

With this pattern, the application authorizes the request and returns a signed GET URL for one object. The browser downloads directly from Cloud Storage, so the application does not carry the file bytes.

This is often a good fit when files are large, downloads are frequent, or the application does not need to inspect every byte. The URL can be limited to one object, one HTTP method, and an expiration time. Google’s signed URL documentation explains that signed URLs work through Cloud Storage XML API endpoints and can be used by anyone who has the URL until it expires.

The trade-off is limited revocation. If the user’s organization access changes one second after a ten-minute URL is issued, that URL can still work for its remaining lifetime. A shorter lifetime narrows that window, but it may create poor behavior for slow downloads or users who open a link after a delay.

Choose a duration from the actual workflow. A preview link may need less time than a multi-gigabyte export. Do not automatically use the longest supported duration. Do not store signed URLs as durable file fields in Bubble; store the application file ID and generate a new delivery credential after each authorization decision.

Signed URLs also affect browser behavior. Set the expected content type and download disposition at upload time or when generating the response. Test names with spaces, Unicode characters, and repeated downloads. Confirm that expired links fail safely and that an application page can request a fresh one.

Option 2: proxy the download through an application service

In a proxy pattern, the browser requests the file from an application endpoint. The service performs the authorization check, reads the object using its own workload identity, and streams the bytes to the browser.

This gives the application more control. It can recheck access throughout a request, apply rate limits, produce consistent error messages, add response headers, or terminate the stream when policy changes. It can also hide bucket and object names from the browser.

The cost is operational. The service now handles file bandwidth, timeouts, partial downloads, range requests, memory pressure, and client disconnects. A naive implementation may buffer the entire object in memory. A safer implementation streams data, supports the browser behaviors the product needs, and keeps authorization separate from the byte-transfer code.

The proxy can also become a bottleneck. Cloud Run and Cloud Storage charges depend on location, network path, request volume, and data transfer. Place the service and bucket deliberately, then measure the actual workload before making performance or cost claims.

Use this pattern when policy requires a server-controlled response, not merely because it feels more private. If a short-lived signed URL satisfies the authorization and revocation window, direct delivery is usually simpler.

Option 3: use Google-authenticated browser downloads

Cloud Storage also supports browser downloads that ask the visitor to authenticate with a Google account. The account must have permission to read the object. Google documents the storage.cloud.google.com endpoint and the required Cloud Storage permission in its request endpoint guide.

This can be reasonable for an internal tool where every user has a managed Google identity and bucket access is administered through IAM. It is less attractive for a customer portal. The customer may not have a Google account, may sign into the wrong one, or may receive a confusing Google authorization error that the Bubble application cannot explain.

Avoid granting broad bucket viewer roles to large groups simply to make downloads convenient. IAM answers whether a Google principal can access a Google Cloud resource. It does not automatically reproduce the row-level organization rules in a Bubble application.

Make the file record durable

Whichever delivery method you choose, the Bubble-side record needs enough trusted metadata to resolve and govern the object. A useful record can include:

  • an application file ID;

  • owning organization ID;

  • bucket reference and opaque object name;

  • object generation when version-specific reads matter;

  • original display name and safe content type;

  • lifecycle state;

  • upload completion and validation timestamps;

  • retention or deletion state;

  • last successful reconciliation result.

Cloud Storage gives each object generation a unique generation number. Google’s object metadata documentation explains how generation and metageneration identify object and metadata versions. Binding a sensitive download to the expected generation can prevent a later replacement at the same object name from being mistaken for the file that was originally authorized.

Do not use a readable path such as customer-name/contracts/file.pdf as proof of ownership. Names are useful for organization, but authorization should come from trusted application records and policy.

Test access changes and awkward failures

A download design is incomplete until it handles negative cases. Use synthetic users and files to test:

  • a user in the correct organization;

  • a user in another organization who knows the file ID;

  • a user removed from the organization after a link is issued;

  • an expired or altered signed URL;

  • an object that exists but is quarantined or pending deletion;

  • a Bubble record whose object is missing;

  • an object whose generation no longer matches the record;

  • a proxy request interrupted halfway through;

  • filenames containing spaces and non-ASCII characters;

  • repeated download requests and rate limits.

The expected result is not only a 403. The Bubble interface should distinguish “you do not have access,” “the link expired,” and “the file is temporarily unavailable” without revealing whether another tenant’s object exists.

A simple decision rule

Use a short-lived signed URL when the application can make one strong authorization decision and direct object delivery is acceptable. Use a proxy when the application must control the response, hide storage details, or enforce policy that a bearer URL cannot express. Use Google-authenticated browser downloads for a managed internal audience that already uses Google identities and IAM.

Bubble’s own private-file model is also a valid alternative. Bubble’s file documentation explains that private files must be attached to a thing and governed by privacy rules. If that model meets the workflow, moving the file to Cloud Storage may add complexity without enough benefit.

Where Bubble2X fits

Bubble2X is building toward controlled Bubble-to-Google-Cloud file workflows. A planned delivery path could connect Bubble authorization, stable file records, scoped Cloud Storage access, and observable results. That is product direction, not a statement that a managed download workflow is available today.

If you are designing a client portal, bring one real download workflow: who requests the file, which organization owns it, how quickly access must be revoked, typical file sizes, and what the user should see after a failure. Those details determine whether a signed URL, proxy, or Bubble-native file is the better fit.

References

Primary CTA: Discuss your private file-delivery workflow.

Decision flow comparing a short-lived signed URL, an application proxy, and a Google-authenticated browser download.

Help shape the cloud layer for Bubble apps

Help shape the cloud layer for Bubble apps

Help shape the cloud layer for Bubble apps

Bubble2X is building a Bubble-to-Google-Cloud integration for controlled customer-file workflows.

Newsletter

Get tips, product updates, and insights about building with Bubble2X.

Subscribe to Bubble2X updates. See our Privacy Notice.

© 2026 Bubble2X. Product in development.

Bubble2X is building a Bubble-to-Google-Cloud integration for controlled customer-file workflows.

Newsletter

Get tips, product updates, and insights about building with Bubble2X.

Subscribe to Bubble2X updates. See our Privacy Notice.

© 2026 Bubble2X. Product in development.

Bubble2X is building a Bubble-to-Google-Cloud integration for controlled customer-file workflows.

Newsletter

Get tips, product updates, and insights about building with Bubble2X.

Subscribe to Bubble2X updates. See our Privacy Notice.

© 2026 Bubble2X. Product in development.