Agencies share client decks. Product teams share beta builds. Finance shares draft numbers. In all three cases the destination is too sensitive for a public URL but too lightweight for a full access-control system. Password-protected links sit exactly in that gap — provided they're built safely. This guide covers the threat model, the safe implementation, and the operational rules.
What a password gate is (and isn't)
A password gate is a handshake: it verifies that the person holding the link also knows the shared secret. It is not a vault:
| Threat | Gate stops it? |
|---|---|
| Casual link sharing beyond the intended group | Yes |
| Search-engine indexing of the destination | Yes (gate precedes destination) |
| Brute force by a determined attacker | Slowed (rate limit + bcrypt) |
| Someone with the password sharing it onward | No — password is shared knowledge |
| A compromised recipient device | No |
The correct pairing is gate + expiry: the password proves the handshake, and the expiry limits how long the handshake is valid. Link expiration strategy covers the timing rules.
How a safe gate is built
The naive implementation puts the password in the URL: https://yas.sh/deck?password=Summer2026!. That's broken in three ways at once — the password lands in browser history, in the Referer header when the destination page loads, and in server access logs.
The safe flow uses a POST form:
1. Visitor requests GET /client-deck
2. Platform responds 401 + HTML gate (no password in the URL)
3. Visitor submits POST /client-deck password=…
4. Platform verifies bcrypt(password) against stored hash
5. On match: 302 → destination (click recorded)
Server-side rules that make this robust:
- Hashed at rest. The stored value is bcrypt with cost 12 — the same treatment as account passwords. A database leak doesn't reveal link passwords.
- Rate-limited attempts. 10 attempts per minute per link per IP, with a plain-text 429 response. Brute force becomes a slow, noisy, detectable process.
- No caching. The gate page is served
no-storeso intermediate caches can't serve a stale gate or leak state. - Robots excluded. The gate page carries
noindex, nofollowso search engines don't index or chase it.
Use cases that fit
Client deliverables. Proposal PDFs, brand decks, campaign previews. Password sent in a separate channel from the link (Slack DM + email, or email + SMS) — the two-channel rule is what makes this genuinely safer than a plain link.
Beta and private previews. Pre-release builds, private pricing pages, early-access signups. Pair with expiry so previews self-destruct on schedule.
Internal documents on the edge. Docs you'd rather not put in the public web but that live behind a short link for convenience. Gate + expiry + audit (click count) gives you visibility into who opened what.
Semi-sensitive contracts. Term sheets, partnership drafts, MSA redlines. Not secrets-grade, but not public either.
Operational rules
- Send the link and password separately. One channel is a handshake; two channels are a protocol.
- Set an expiry. Every gated link should die on a date — decks for a pitch that already happened don't need to live forever.
- Watch the analytics. Bot-filtered click counts show you when the link is being opened and from what devices; unexpected spikes from unknown countries are a signal to rotate the password.
- Rotate per engagement. A new client gets a new link and password, not the same one from last quarter.
The API contract
# Create a gated link
curl -X POST https://yas.sh/api/v1/links \
-H "Authorization: Bearer yas_live_..." -H "Content-Type: application/json" \
-d '{"originalUrl":"https://drive.example.com/deck-q3","customAlias":"q3-deck","password":"Tr0ub4dor&3!","expiresAt":"2026-09-01T00:00:00Z"}'
# The gate is automatic — GET /q3-deck returns the 401 gate page
# POST /q3-deck with form field password=… unlocks the redirect
Conclusion
Password-protected links are the right tool for semi-sensitive sharing when built with the right discipline: POST-based gates, bcrypt at rest, rate-limited attempts, expiry, and two-channel password delivery. The yas.sh link engine implements all of it — create your first gated link or read the API docs for the full contract.
