I Protected Files on a WordPress Multisite. Here’s What Worked (and What Didn’t)

I run a WordPress Multisite with seven sites. Think school forms, client PDFs, and a few videos for training. I wear the webmaster hat. I also make the coffee. On a rainy Tuesday, I found out our private files were getting shared by direct links. Not cool. I eventually pulled everything into a step-by-step case study—the full story lives here.

So I spent two weeks locking things down. I tried three paths. Some easy, some fussy, and one that was fast but rough around the edges. Here’s what I learned, the hard way.

My setup and the problem (in plain talk)

  • WordPress Multisite with sub-sites like /hr/, /staff/, and /courses/.
  • Shared media folder: wp-content/uploads/sites/2/, sites/3/, and so on.
  • Staff PDFs, parent forms, and course videos.
  • People pasted direct file links in chat. Guests could open them. Yikes.

I needed file links that check “who are you?” before they load. On every sub-site, not just one.

The fast fix: Prevent Direct Access Gold (works on Multisite)

First, I used Prevent Direct Access Gold (PDA Gold). I network-activated it. Then I went to each sub-site and marked files as “private.” Their detailed walkthrough on protecting media files across a WordPress Multisite was a lifesaver.

Real example:

  • File: /wp-content/uploads/sites/3/2025/08/Staff-Handbook.pdf
  • I clicked Protect in the Media Library.
  • PDA gave me a private link like /?pda=staff-handbook-abc123.
  • The old URL stopped working for guests. Logged-in staff could see it on that sub-site.

What I liked:

  • It worked right away. No code. No tears.
  • It shows a lock icon in Media Library. Handy when you’re half-awake.

What bugged me:

  • Rules live per site. So I had to protect the file on each sub-site where I used it.
  • Hotlinking from other sub-sites still tried to sneak around. PDA blocked most of it, but edge cases popped up.
  • Thumbnails and attachment pages could leak info if I wasn’t careful.

Small note: I set a rule to protect only PDFs, DOCX, and ZIPs. I didn’t protect images used on public pages; that would break design.

The membership gate: MemberPress + files behind roles

On our courses site, I used MemberPress with “Teachers” and “Parents” roles. I set rules so only Teachers could view certain PDFs.

Real example:

  • Course plan PDFs in /sites/4/.
  • I added the file link to a page that only Teachers can view.
  • The direct old URL still needed a block, so I kept PDA on too.

What I liked:

  • Good for human logic: “if Teacher, show file.”
  • Easy to explain to non-tech folks.

What didn’t fly:

  • Rules don’t jump across sub-sites. Each site needs its own rules.
  • If someone got the raw file URL, MemberPress alone didn’t stop it. It’s page-level, not file-level. So yes, I still needed PDA or server rules.

Cloud route: WP Offload Media to S3 + CloudFront signed URLs

For videos, I went cloud. I used WP Offload Media to push big MP4 files to Amazon S3 and served them with CloudFront. I turned on signed URLs so only allowed users can watch.

Real example:

  • Video: lesson-3.mp4 on the courses site (site 4).
  • Player: Presto Player worked well with signed URLs.
  • The signed link expires. If a student shares it, it fails after a short time.

What I liked:

  • Fast video. Less load on my server.
  • Signed URLs felt solid. Like a bouncer at the door.

Trade-offs:

  • Cost. Not huge, but not zero.
  • Setup takes patience. The first time, I mixed up a policy and locked myself out. Fun.
  • Domain mapping can confuse cookies. I kept a tight cookie path and it smoothed out.

Tip: If you use Cloudflare on top, bypass cache for signed URLs. I set a page rule to skip cache on /media/* and the timeouts stopped.

The nerdy bit: server rules that actually block files

I also tried server rules. On Apache, I blocked direct PDF hits and sent them to a PHP check. On Nginx, I used X-Accel-Redirect. Sounds fancy, but here’s the point: WordPress checks “who are you?” then the server streams the file. It’s faster than loading the whole file through PHP.

Real example:

  • File: /wp-content/uploads/sites/2/policies/leave-policy.pdf
  • If not logged in, you see a 403 page. If you’re HR staff, you get the file.

Good:

  • It’s strong and fast once set.
  • It works across all sub-sites with one rule, if you plan the paths.

But:

  • Easy to break if you use a CDN wrong.
  • You’ll need a tiny custom plugin or function to check roles. Not hard, but not click-and-go.

I still used PDA on top for quick toggles. A belt and suspenders thing.

What broke on me (and how I fixed it)

  • Attachment pages: Even when files were blocked, the WordPress attachment page could leak the file name. I killed attachment pages with a small mu-plugin that redirects them to the parent post.
  • Thumbnails: Some image thumbs stayed public. I didn’t care for images on public pages, but I did for scans of IDs. I kept those scans as PDFs and used PDA.
  • Caching: One time, Cloudflare cached a private response. I set no-store headers for private links and made a cache bypass rule. Problem gone.
  • Editors moving files: A team member replaced a file with the same name. The private link changed. I trained folks to re-copy the link after any replace. We also used “Enable Media Replace,” which helped.

What I ended up using (my real stack)

  • PDA Gold for PDFs, DOCX, and ZIPs on all sub-sites.
  • MemberPress for role logic on course pages.
  • WP Offload Media + S3 + CloudFront for videos, with signed URLs.
  • A tiny mu-plugin to disable attachment pages and block direct file access for sensitive types.
  • Cloudflare rules that skip cache on private links and set no-store headers.

It’s not perfect. But it’s stable. And my support inbox is quiet now, which is priceless.

Step-by-step: How I’d set this up again

  • Network-activate PDA Gold. Protect PDFs and ZIPs only.
  • On each sub-site, mark private files in Media Library.
  • Turn off attachment pages with a small mu-plugin.
  • For courses, protect pages with MemberPress roles.
  • For big files (video), offload to S3 and use signed URLs.
  • Set CDN rules to bypass cache for private paths.
  • Train editors: always use the private link, not the raw URL.
  • Test as a logged-out user, on each sub-site, every time you change a rule.

Real examples you can picture

  • HR site (site 2): Staff-Handbook.pdf is private. Only logged-in HR can view it. The old uploads URL throws a 403.
  • School site (site 3): Parent-Form-2025.docx is private. Teachers see it on a locked page. Guests see a friendly “please log in.”
  • Courses site (site 4): Lesson-3.mp4 streams from CloudFront with a signed URL that lasts 15 minutes. Students watch; shared links expire.

Tiny gotchas I wish someone told me

  • Changing file names breaks private links. Keep names stable.
  • Backups: make sure your backup tool can still copy protected files.
  • Staging: protect rules on staging too, or you’ll think it’s broken when it’s not.
  • Domain mapping: cookies can get weird across subsites. I used secure cookies and a consistent login page. It helped a lot.
  • Revenue experiments: before you plan a blind drop-shipping side hustle, read this cautionary tale for a reality check.

If your network ever finds itself distributing 18-plus or explicit materials, you’ll need airtight user verification before anyone even sees a download button. To see how a high-traffic dating platform solves instant, location-based access control, check out this breakdown of how to get free sex tonight—hint: try this app. It walks through their friction-less onboarding flow, age-gate tactics, and privacy safeguards you can borrow for your own WordPress build.

In a similar vein, if you’re curious how a hyper-local sugar-dating network tightens access to seductive photos and chat logs, study the flow employed by Sugar Baby Georgetown—the article breaks down its selective onboarding, ID checks, and pay-walled media vault, offering blueprints you can translate to WordPress.

Alternatively, a hosted storefront like CandyPress bakes in secure file delivery so you can skip the Multisite wrangling altogether. If you’re eyeing