Skip to content
Y
YAS.SH
Security

Password-Protected Links: Share Client Decks Without Leaks

When and how to use password gates for sensitive links — threat model, bcrypt hashing, POST-based gates, rate limiting, and expiry.

yas-team3 min readsecuritypasswordlinks
Password-Protected Links: Share Client Decks Without Leaks
Featured imagePassword-Protected Links: Share Client Decks Without Leaks

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-store so intermediate caches can't serve a stale gate or leak state.
  • Robots excluded. The gate page carries noindex, nofollow so 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.

Frequently asked questions

Is a password-protected link safe for confidential documents?

It's a solid gate for semi-sensitive sharing (client decks, beta invites, private previews) but not a substitute for access control on the destination itself. Pair it with expiry and treat the password as a handshake, not a vault.

Why does the password go through a POST form instead of the URL?

Passwords in URLs end up in browser history, referrer headers, and server logs. A POST body stays out of all three.

Can someone brute-force the password?

Attempts are rate-limited (10 per minute per link per IP) and the password is hashed with bcrypt — brute force is slowed at both layers.

What happens after the link expires?

Expired links return HTTP 410 Gone with a clear message, so recipients know the link is dead rather than broken.

Was this helpful? Share
🍪 Cookies & privacy. yas.sh uses only essential cookies to keep you signed in and remember your preferences. We do not run third-party trackers. See our cookie policy and privacy policy.
Settings