file_gate
File Gate
Gate access to private files. Deny anonymous access to private:// files and deliver them only to visitors who have passed a gate — a lead form, a login, a token, a purchase — through short-lived signed URLs that work with any front end.
The problem it solves
Out of the box, Drupal grants a private file download to anyone who can view the entity that references it. Because anonymous users can view published content, a private file attached to published media is effectively public to anyone who has the link — private:// only means "not guessable", not "gated". File Gate closes that gap.
Features
- Pluggable gate methods. A clean plugin type (
GateMethod) decides how a request proves it passed the gate. Ships with Signed URL (HMAC, short-lived) and Authenticated access; add your own — token, email capture, form submission — in a few lines. - 100% front-end agnostic, headless-first. A trusted back end mints a signed URL over a server-to-server API and the browser redeems it. Nothing about React, Next.js, Vue, or a coupled Twig theme is assumed — decoupled, coupled, and hybrid sites all work.
- Per-field configuration. Mark any file or image field "gated" right where you choose its storage. Enabling gating forces the private file system and locks it, so a gated field can never silently store public, world-readable files.
- Media-optional. Gate a Media source field, a plain file field, or any other private file field. The only hard dependency is core File.
- Short-lived, self-expiring URLs. Signed links carry a configurable TTL (default 120 seconds) and bind the exact file, so a link minted for one file cannot fetch another and stops working the instant it expires. No long-lived public URL is ever exposed.
- Fails closed. With no signing secret configured, minting returns
503and every gated file is denied — security never depends on remembering to switch something on. - Constant-time verification. Grants are HMAC-SHA256 and compared with
hash_equals(). The secret lives in the environment, never in exported configuration. - Editors keep working. A "Bypass file gate" permission lets trusted staff download gated files normally through the admin UI.
- Admin dashboard. One settings page reports the secret status, sets global defaults (TTL, content disposition, rate limiting), lists the available gate methods, and shows every gated field with a link straight to its settings.
- Abuse-resistant. The mint endpoint is flood-limited per client IP.
How it works
- Mark a private file or image field as gated and pick a method.
- Your back end runs its own gate (lead form, login, purchase, …), then calls
POST /api/file-gate/mintwith a file or media UUID and the shared secret. - File Gate returns a relative, short-lived signed path.
- The visitor's browser redeems it at
GET /api/file-gate/download; File Gate verifies the grant and streams the file. The raw/system/filespath stays denied throughout.
Use cases
- Lead-generation gated content — whitepapers, datasheets, and reports behind an email or form.
- Member-only or purchase-only downloads.
- Any decoupled site that must protect files while keeping delivery fast and framework-neutral.
Extensible by design
The signing and minting core is deliberately target-agnostic — it protects an opaque resource, not "a file" — so the same foundation can grow to gate other things in the future without a rewrite.
Requirements
- Drupal 11.4+ (built on the modern
FileReferenceResolverAPI). - A configured private file system.
- A signing secret injected from the environment (never committed to configuration).