objectgate

A sign-in in front of a bucket you already own

Connect an S3 bucket, say who may open it, and each share gets its own address. A viewer signs in, picks an object, and downloads it from your bucket over a URL that expires in minutes. The bytes go from the browser to your storage, so nothing is copied to us and there is no second egress bill.

VIEWER SIGN-IN OBJECTGATE YOUR BUCKET THE REQUEST SIGNS ONE GET THE OBJECT, DIRECT FROM YOUR BUCKET READ-ONLY, ONE PREFIX
FIG. 1 GENERAL ARRANGEMENT SCALE: NONE SHEET 1 OF 6

Start with one bucket Read what it asks for

how it works

  1. Connect the bucket

    Give objectgate a read-only access key, or on AWS a cross-account role it assumes with an external id. Either way the grant is scoped to one bucket and one prefix, and you can revoke it in your own console.

    The connect check runs while you watch: it lists the prefix and reads one object. When that fails you get the S3 answer translated into the thing to change, whether it is a missing permission, the wrong region, or a KMS key policy that does not mention the role yet.

  2. Choose who may open it

    An address list, an email domain, a link that is itself the credential, or your own identity provider over OIDC. Sign-in happens before a request reaches the share, so a viewer needs no account with objectgate and no identity in your cloud.

  3. Send the address

    A share is a host: rushes.acme.objectgate.dev, or a domain of yours pointed at it. Signed-in viewers see the objects under the prefix you picked. A key that resolves outside that prefix answers 404, which tells a prober nothing about what exists.

inside one download

Five hops, and only the last one moves bytes. Rest on a hop to find it on the drawing.

1 2 3 4 5 ARRIVE RESOLVE SIGN 302 FETCH THE ONLY LEG THAT MOVES BYTES
FIG. 2 PATH OF ONE DOWNLOAD SCALE: NONE SHEET 2 OF 6
  1. GET /f/2026-08/master.mov arrives at the share carrying the viewer's session.
  2. resolve against the prefix the key is normalised and re-checked; a .. segment or a different prefix ends here.
  3. sign a GET for that one object, valid for the share's window, five minutes unless you set another.
  4. 302, Cache-Control: no-store with a content-disposition taken from the key, so the file keeps its name on the way into the downloads folder.
  5. browser → your bucket S3 answers the object. Range and If-None-Match work because the storage is answering them, not a proxy of ours.

Proxy delivery, on the paid plans, is the other setting: the share fetches the object and streams it to the viewer itself. No presigned URL ever reaches the browser — the address a viewer copies is the gated one, so it stops working the moment the share does — and the download comes from the share's own domain, not from your storage provider's. Either way the grant lands in the event log with the viewer, the key and the time.

your bucket, unchanged

The callouts number the parts people expect to have to touch. Rest on a row to find its balloon.

POLICY NO CDN 1 2 3 4 5
FIG. 3 DETAIL B, THE BUCKET SCALE: NONE SHEET 3 OF 6
Block Public Access
On, all four switches. objectgate reads with credentials; no object becomes public.
The bucket policy
Unedited. The permission lives in a role or a key that you create and can delete.
CloudFront
Not involved. No distribution, no origin access control, no signed cookies.
CORS
Untouched for downloads. Following a redirect to an object is a navigation, not a cross-origin fetch.
The objects
Left in place. The policy objectgate asks for grants no write anywhere.

who it is for

storage it reads

Amazon S3, Cloudflare R2, Backblaze B2, Wasabi, DigitalOcean Spaces, Scaleway Object Storage, and MinIO on a public hostname. Anything else that speaks S3 with signature version 4 connects as other, path-style. The connect guide lists the endpoint, region and addressing each one wants.

what it will not do

Reach a private network. The runtime refuses to open a connection to a private or link-local address, so a MinIO on a LAN or a host that only answers over a VPN cannot be connected at all. This is checked at connect time rather than discovered on a viewer's first download.

Thaw an archive. An object in Glacier or Deep Archive has to be restored in your account first. objectgate reports the storage class instead of stalling on it.

Decrypt without the key. A bucket encrypted with a customer-managed KMS key needs kms:Decrypt in the policy and a grant for the role in the key policy. One without the other still denies the read.

Span buckets. One share reads one bucket under one prefix. A second prefix is a second share, and the plans count them.