Public vs private files: buckets, temporary links and share links

A public file opens for anyone who has the URL. A private file opens only through an authorized link, such as a presigned URL or a revocable share link.

Updated 6 min read

Learning objectives

After reading this article you will be able to:

  • Decide which files should be public and which private
  • Test with curl that a file is really protected
  • Choose between a presigned URL and a share link to open a private file
On this page

Every file you put in object storage carries a decision: who can open it. Logos, product images and your site's JavaScript must be visible to everyone. Contracts, invoices and photos of ID documents must not.

The expensive mistake is making public something that should be private. The file leaks without a single error, because serving public files is exactly what the storage was set up to do. So decide the visibility before you upload, and check it afterwards with a simple test.

Is the file the samefor everyone?yesnoPublicanyone withthe URL gets it;CDN cachingPrivateno authorizationmeans 403One-offpresigned URL,expires on its ownRevocableshare link
Same for everyone? Public, behind a CDN. If not, private, opened by a presigned URL or a revocable share link.

What is the difference between a public and a private file?#

Public: anyone with the URL downloads the file, with no login, no signature and no expiry. The URL is permanent and can be cached by a CDN, which makes delivery fast and cheap.

Private: a request without authorization gets an error (usually 403). Access needs the owner's credentials or a link the owner generated, with an expiry and, sometimes, a way to cancel it.

Visibility is not a property a file has "by nature". It is a setting on the bucket, the folder or the object, and you can change it. What you cannot change is what already left: a public URL someone copied keeps working for as long as the file stays public.

Which files should be public and which private?#

A simple rule: if the content can appear on an open page with no login, it can be public. If it appears only after authentication, it is private.

File type Visibility Why
Site images, CSS, JS, fonts Public Everyone sees them, CDN caching helps
Avatars and product images Public Already shown on open pages
Invoices, contracts, tax documents Private One person's data
ID photos, medical exams Private Sensitive personal data
Exports and reports Private Contain internal data
Subscriber-only media Private Access is part of the product

When in doubt, start private. Opening a file later is a one-line change; closing it later does not recall what was already copied.

How do I test that a file is really protected?#

Request the direct URL with no credentials, the way a stranger would. Use a terminal or a private browser window:

bash
curl -I "https://my-bucket.s3.amazonaws.com/invoices/2026-10.pdf"

A private file answers something like:

HTTP/1.1 403 Forbidden

A public file answers HTTP/1.1 200 OK. If your "private" file returns 200, it is not private, however impossible the URL looks to guess. Repeat the test after any change to policies or permissions.

On Amazon S3 (see what S3-compatible storage is), the official documentation says new buckets, access points and objects don't allow public access by default. Block Public Access has four settings (BlockPublicAcls, IgnorePublicAcls, BlockPublicPolicy and RestrictPublicBuckets) that override policies and ACLs, and AWS recommends turning on all four. Other providers have similar controls under different names: look up the equivalent in your provider's documentation.

How do I give someone access to a private file?#

Two mechanisms are common. The choice depends on how long the link needs to last and whether you might need to cancel it early.

Presigned URL (temporary link). Your backend signs a URL with a short expiry. Whoever opens it downloads the file, with no account and no credentials. You cannot cancel one specific link before it expires. Details in what a presigned URL is.

Share link. A longer-lived link, recorded in the storage, that the owner can revoke. It suits a file you distribute for days and may want to pull back.

A Python example with boto3 (pip install boto3), with credentials in environment variables:

python
import os

import boto3
from botocore.config import Config

s3 = boto3.client(
    "s3",
    region_name="us-east-1",
    endpoint_url=os.environ.get("S3_ENDPOINT"),  # omit on AWS S3
    aws_access_key_id=os.environ["S3_ACCESS_KEY"],
    aws_secret_access_key=os.environ["S3_SECRET_KEY"],
    config=Config(signature_version="s3v4"),
)

url = s3.generate_presigned_url(
    ClientMethod="get_object",
    Params={"Bucket": "my-bucket", "Key": "invoices/2026-10.pdf"},
    ExpiresIn=600,  # 10 minutes
)
print(url)

Run curl -o invoice.pdf "<url>" (with quotes) and the file downloads. The same URL without the signature parameters still returns 403. On Amazon S3 the maximum expiry is 12 hours from the console and 7 days from an SDK or the CLI with IAM user credentials; with temporary credentials, the URL dies when they do.

Does sharing a public file protect it?#

No, and this is the most common mistake. Creating a share link for a file that is already public restricts nothing: the public URL stays open for anyone who has it. Adding a password to the share link does not help either, because the direct path never asks for one.

For a share link (or its password, where the storage offers one) to mean anything, the file has to be private. Only then is the authorized link the sole way in. The right order is to close the file first and only then generate the link.

What mistakes should I avoid?#

  • Trusting a long random URL. It leaks through logs, history and forwarded messages. Access control is a check, not a secret in the URL.
  • Storing the presigned URL in your database. It expires. Generate a new one on each request from an authenticated user.
  • Mixing public and private in the same folder. Separate them by folder or bucket and apply different rules to each. A private file dropped in the public folder is the classic leak.
  • Forgetting the cache. A public file may stay cached on a CDN after you close it. After changing visibility, test again and purge the cache if needed.
  • Granting more than needed. A link should reach one file, for as long as the task takes.

How to do this on Square Cloud#

On Square Cloud Blob Storage, the decision from the table above becomes the bucket you write to: each account has the fixed buckets public, served by a global CDN at the edge, and private. Logos and product images go in the first; invoices, contracts and exports go in the second. Visibility can also be set per folder, together with expiration, cache, maximum size and allowed extensions, which helps you avoid the classic leak of a private file forgotten in the public folder.

A private file opens three ways, with the differences you just read about: the SigV4 presigned URL your code generates, valid for up to 7 days; the dashboard's temporary link, valid for up to 24 hours and not revocable; and the share link, valid for up to 30 days and revocable, with password and metadata on the Pro and Enterprise plans. Since a link and its password only protect private files, write to private first and create the link afterwards.

The boto3 code above runs against Blob with S3_ENDPOINT=https://s3-blob.squarecloud.app, the auto region in place of us-east-1, the private bucket in place of my-bucket and the S3 keys from the "S3 access" tab of the dashboard, derived from an API key. After your first upload, repeat this article's test: with the signature the file downloads, without it the file must not open. There are no egress or ingress fees, and the included quota ranges from 5 GB to 250 GB depending on the plan. Explore Blob Storage and compare quotas on Pricing.

Blob Storage

S3-compatible object storage with no egress fees

Learn more

FAQs

Does sharing a public file protect it?

No. A share link is just one more way in. The file's public URL keeps working for anyone who has it. To control access, the file has to be private.

Is a hard-to-guess URL enough to protect a file?

No. Security through obscurity fails as soon as the URL leaks into a log, a browser history or a forwarded message. Anyone with the URL of a public file gets it, with no check at all.

How do I know if a file is public?

Request the direct URL with no credentials, for example with curl -I. A 200 means anyone can open it. A private file answers 403 (or 401, depending on the storage).

Are new S3 buckets private by default?

Yes. According to the AWS documentation, new buckets, access points and objects don't allow public access by default, and Block Public Access stops policies or ACLs from opening them by mistake.

Next articleEgress fees: the hidden cost of cloud storageEgress fees are charges per GB that leave your cloud storage for the internet. See how the math works, a worked example, and how to avoid bill surprises.

More in Storage

See all 15 articles