Revenue leakage is a silent killer for digital products. You launch a premium report or audio course, and within a week, the direct S3 link appears on Reddit or Discord.
While you cannot stop a determined pirate from re-hosting a file, you can (and must) stop the far more common vector of casual link sharing.
This occurs because most “security” implementations protect the page, not the asset. They hide a permanent link behind a login wall. Once that link is exposed, authentication becomes irrelevant.
When I started building out the premium content library for GetViajo.com, my personal R&D lab for growth systems, I knew this was a critical, foundational problem to solve. A simple “members-only” page wasn’t enough.
My architectural solution was to shift from linking to a file to brokering a secure transaction. I built a “Digital Vault” system that never exposes the origin URL. Instead, it treats every download request as a unique security event.
Here’s the architectural blueprint for how I engineered it and, more importantly, the business decisions that drove the design.
The Core Problem: A Link Is Not a Lock
The fundamental flaw in most systems is that they protect the page, not the asset.
A typical setup looks like this: a user logs in, visits /my-premium-content, and clicks a button that links to .../assets/my-secret-ebook.pdf. Even if that URL is long and unguessable, the moment one paying customer copies and shares that link, the asset is free for the world.
My guiding principle for this build was: Never link to the file. Ever.
I built a “gatekeeper” API endpoint that intercepts every download request. Applying the same architectural rigor used in my full-funnel marketing intelligence system, this endpoint validates two distinct conditions before serving a single byte:
- Who are you? (Authentication)
- Are you allowed to be here? (Authorization)
Only after verifying “yes” to both does the system generate a temporary “key” that stops working after an hour, and hand it to the user.
The core architectural principle: I don’t give users a key to the vault. I have a gatekeeper who validates them and then fetches the content for them.
The Architecture: Three Components of the Digital Vault
This “gatekeeper” API is the core of the system. I built it using a serverless function that integrates three cloud services to work in perfect concert.
1. The “Bouncer”: Resourceful Authorization
The Engineering Constraint: Building a bespoke authorization system (custom tables for permissions, payment status syncing) introduces significant complexity and maintenance overhead. The goal was to achieve robust security without incurring technical debt.
The Solution: I used Stripe as the source of truth for whether someone has paid. When a payment succeeds, Stripe sends a webhook to my backend. My backend validates it, then makes a server-to-server call to PostHog that sets the is_premium: true property on that customer. The browser is never part of this chain.
Technical Detail: When a download request comes in, the API first works out who is asking, using the email address tied to the request. Then it decides what they can access: it queries the PostHog API for that email and checks for the is_premium: true property my backend set when Stripe confirmed the payment.
The Outcome: This reuses a tool already in my stack (PostHog) to hold premium status, so there is no separate permissions database to build or maintain.
2. The “Expiring Key”: AWS S3 Pre-Signed URLs
Business Problem: Once a user is authenticated, how do I give them the file without giving them the source link?
My Solution: I used one of the most powerful and effective features of AWS S3: pre-signed URLs.
Technical Detail: After the PostHog check passes, the API uses the AWS SDK to generate a unique, temporary URL for the requested file. I configured this URL to expire after 3,600 seconds (one hour). This link grants temporary GetObject permission for that specific file and nothing else.
Business Outcome: This is what directly protects the revenue. A user can download their file, but if they copy and share that pre-signed link, it’s completely useless an hour later. This effectively neutralizes casual link-sharing.
3. The “White Glove” Delivery: A Focus on User Experience
The UX Challenge: Secure backend systems often degrade the frontend experience, serving files with cryptic internal filenames (e.g., ASSET_001-v3-FINAL.pdf) that confuse the end user.
My Solution: I used the API to ensure the experience felt premium, not clunky. I stored the “human-friendly” metadata for each lesson (like the real title) in a DynamoDB database.
Technical Detail: When the API generates the expiring link, it also fetches the file’s real name from DynamoDB. It then sets the Content-Disposition header in the API response.
Business Outcome: When the user clicks download, their browser doesn’t see PT-EU-001.pdf. It sees At The Café - Ordering From a Café in Portugal (Cheat Sheet).pdf. This is a small, but critical, piece of engineering. It proves that you don’t have to sacrifice user experience for security. You can (and should) do both.
[!tip] Never Underestimate a Good Filename The
Content-Dispositionheader is one of the most overlooked tools for improving user experience in a secure system. It’s a single line of code that takes the user from “what is this cryptic file?” to “ah, exactly what I wanted.” This builds trust and makes the product feel more polished.
Sign up for my newsletter to get my latest updates directly in your inbox.
By clicking Sign Me Up, you confirm you are 16+ and agree to our Terms of Use and Privacy Policy.
The complete, end-to-end runtime flow. This API queries PostHog for the user’s premium status, which is securely set via a server-to-server webhook from Stripe, ensuring the authorization check is based on a trusted source.
How This Applies to a Growth Team
These “Digital Vault” principles apply to any organization managing high-value digital assets, from SaaS platforms to enterprise research firms.
- Audit Your Asset “Vault”: Where is your premium content actually stored? Ask your team for the direct links. If it’s just an unguessable S3 URL or a file in a password-protected WordPress folder, you have a revenue leak, not a vault.
- Run the “Forward Test”: Get the direct link to your most valuable asset. Email it to a personal account. Now, forward that email to a friend. If they can open it, you don’t have a secure system.
- Audit Your Vendors: That third-party course platform you use? Find out how they secure your files. Are they using expiring links, or is the platform itself the source of the leak?
Future-Facing Questions & Next Steps
[!faq]- How would this system scale to serving video or streaming content? The principle stays the same, but the delivery would change. Instead of an S3 pre-signed URL for a single file, the “gatekeeper” API would issue CloudFront signed URLs or signed cookies for a streaming version of the video. (AWS MediaConvert is the service that would create that streaming version.) The user gets time-limited permission to stream the content, never access to the source video file.
[!faq]- What if a user’s link expires before they click it? This is a key part of the user experience design. The “download” button on the website doesn’t link anywhere. It triggers a function that calls the “gatekeeper” API. This means every time a user clicks the button, they are always running the full authentication and link-generation process. If a link expires, they can simply go back to the page and click the button again to get a fresh, valid one. The user never even knows the links are temporary.