FileHutch

Use cases

Four file jobs, and the policy that does each

Every one of these is the same three steps: name a policy, quote it on upload, store the ID. What changes is the policy.

User-generated images

Avatars, logos and cover images

Public, small, and resized to a handful of sizes you will change your mind about twice. The crop belongs in a transform, not in your templates.

  • Types and size are capped by the policy, so the browser cannot send a 40 MB TIFF
  • Uploads go straight to the bucket — your server issues the policy and never sees the bytes
  • Rename or resize the transform later and every app picks it up without a deploy

app/models/user.rb

class User < ApplicationRecord
  has_hutch :avatar, policy: "avatars"
end

# users.avatar_file_id => "file_3p7wn4c2"
image_tag user.avatar_transform_url("avatar")

Private documents

Invoices, contracts and exports

The files where getting access control wrong is the whole problem. Private by policy, delivered through a link that expires, and every download recorded.

  • Links are issued per request and expire on the policy's TTL, not on a global setting
  • Content-Disposition is set on the signed URL, so a PDF downloads instead of opening
  • The audit log answers who downloaded the contract, and when, without a database query

app/controllers/invoices_controller.rb

# Private stays private: this URL is dead in an hour.
def download
  authorize! :read, @invoice

  redirect_to @invoice.file.signed_url(
    expires_in: 1.hour,
    disposition: "attachment"
  ), allow_other_host: true
end

And the rest

Same three steps, different policy

Client projects, one per customer
An agency runs a project per client, each pointed at that client's own bucket. When the engagement ends you hand over the bucket and delete the project — the files were never in your account.
CSV imports and generated exports
Upload a spreadsheet, process it, write the result back as a private file with a short TTL. The export link in the email expires before the email does.
Agent-built applications
An MCP server and scoped agent keys mean a coding agent can create policies and transforms itself. Every action it takes is attributed to its key in the audit log, never to you.
Marketplace and seller uploads
Sellers upload product images against a public policy with a hard size cap; verification documents go to a private one. Two policies, one bucket, no ambiguity about which is which.

Where it is a bad fit

Said here rather than discovered in month three.

A video product
Files are stored and delivered, never transcoded. If you need adaptive bitrate or a player, use Mux or Cloudflare Stream.
A marketing asset library
No collections, approvals or brand portals. That is a DAM, and there are good ones.
Petabyte archives
Plans top out at 750 GB. Past that you want a storage contract, not a control plane.
Heavy on-the-fly image manipulation
Named transforms cover resize, crop and format. Overlays, face detection and generative fill are Cloudinary's job.

Whichever shape yours is, it starts with one policy.

Create a project, name a policy, store the ID. The free plan is enough to find out.