WordPress launch & staging

Stop relying on a robots.txt rule that a forwarded link ignores completely

Site Password Protection puts the entire public site behind a single shared password — pages, feeds, and the REST API — until the correct password is entered, exactly what's needed before a launch or while showing work to a client.

  • Gates pages, feeds, and the REST API together, not just one of them.
  • Logged-in staff bypass the gate entirely, automatically.
  • Changing the password instantly signs out every previously-granted visitor.
  • The gate never touches wp-admin or the login screen, so work continues normally.
Settings & Visitor GateSite Password Protection

Site password

A password is already set. Leave this field blank to keep it, or type a new one to replace it — this immediately signs out every visitor who was already let in.

Your Site NameThis site is password protected.
••••••••
Enter
Pages, feeds and the REST API, all gatedLogged-in staff bypass it completely.
Active
Quick answer

What does Site Password Protection do?

When the site_password_protection module is active with a password set, TOWP_Site_Password_Protection intercepts every front-end request at the earliest possible point, before any other module gets a chance to serve or redirect it, and shows a password gate to any visitor who isn't logged in and doesn't already have a valid access cookie. A separate, dedicated check gates the REST API, returning a proper 401 response rather than exposing data through an endpoint the HTML gate wouldn't cover. Once the visitor enters the correct password, a cookie derived from that password lets them back in without re-entering it; since the cookie ties directly to the password's current value, however, changing the password immediately invalidates every cookie already granted.

The "robots.txt isn't actually a lock" problem

A polite request to search engines isn't a real barrier for anyone else

Since a robots.txt entry only asks crawlers to stay away, it leaves a site fully open to anyone who has the direct address.

A disallow rule only asks crawlers not to look, it doesn't stop anyone

A robots.txt entry only asks search engines to honor a request, so it does nothing to stop a person who already has the direct URL from opening it.

A link forwarded by mistake still opens fine

Even a staging site shared once with the wrong person, or a URL accidentally sent to the wrong chat, stays completely viewable unless something actually requires a password.

Here's the fix

One password, gating the entire public site

The module closes off pages, feeds, and the REST API together, so there's no uncovered surface left for a forwarded link to slip through.

Every public surface gated together

The same check covers pages, feeds, and the REST API together, not just the pages a visitor would normally browse to.

Staff keep working, uninterrupted

Anybody already logged in bypasses the gate automatically, and consequently, the module never gates wp-admin or the login screen at all.

Changing the password locks everyone out instantly

Since the access cookie ties directly to the current password's value, rotating the password immediately invalidates every cookie already granted, without a separate revoke step.

Verified feature set

Layered defenses, not a single check

Every capability below is present in the supplied PHP class and its settings registration.

The REST API is gated separately

A dedicated check, not an afterthought

Since the REST API doesn't render an HTML page, a separate rest_authentication_errors check returns a proper 401 response instead, therefore closing a vector an HTML-only gate would miss entirely.

rest_authentication_errors401 response, not a redirect
The cookie is cryptographically derived, not just stored

An HMAC tied to the current password

The module generates the access cookie's value with hash_hmac() from the password and the site's own auth salt, rather than storing the password itself or a simple hash of it.

hash_hmac()wp_salt('auth')
Timing-safe comparisons throughout

hash_equals() on both password and cookie checks

The code compares both the submitted password and the stored access cookie using a timing-safe function, rather than a standard string comparison.

hash_equals()Timing-attack resistant
Encrypted at rest

The module never stores the password itself in plain text

The module encrypts the configured password before saving it, and decrypts it only momentarily to check a submission against it.

TOWP_FTP_Volume::encrypt()Encrypted storage
The gate page behaves like a real HTTP response

503 status, no caching, no indexing

The module serves the gate with a 503 status code, cache-prevention headers, and a noindex directive, so it behaves correctly for browsers, caches, and search engines alike.

503 statusX-Robots-Tag noindex
Practical use cases

Where a real password gate helps most

The module supports any site that genuinely isn't ready for open public access yet.

Pre-launch sites not ready for public visitors

Keep a site fully built and testable while genuinely closing it off from anyone without the shared password.

Showing work in progress to a client

Share one password with a client instead of relying on an obscure URL nobody's supposed to forward.

Staging environments used for real testing

Let a staging copy run with real content and real traffic patterns from the team, without exposing it to the open web.

Operational benefits

A genuine barrier, not a polite request

The module combines a real access barrier with zero disruption to the team actively working on the site.

A real barrier, not a polite requestUnlike a robots.txt rule, nobody can view the gated content at all without the password, regardless of how they got the link.
No uncovered surface for a link to slip throughThe gate covers feeds and the REST API just as thoroughly as the pages a visitor would normally browse, closing off paths a page-only gate would miss.
Zero disruption for the team actually building the siteStaff keep full access automatically, with nothing extra to configure or remember while the gate is active.
One password change clears every prior visitorThere's no separate step to revoke access; changing the password does that immediately for anyone who was previously let in.
Performance behaviour

One early check, then nothing else

The verified implementation stays out of the way entirely for logged-in visits and unconfigured sites.

One early check, then nothing else

The gate check runs once per request, at the earliest point WordPress offers, before any other page logic executes for a gated visitor.

No effect on a logged-in visit

The check exits immediately for anyone logged in, adding no overhead to the normal admin or staff experience.

No effect at all with no password configured

If the module is enabled but nobody has set a password yet, the check exits without gating anything, avoiding an accidental lockout.

Security implementation

Built like real access control, with honest limits stated

The code follows established security practices throughout, and documents plainly what it doesn't cover.

01

A real access barrier, not an indexing suggestion

The gate actually prevents anyone from viewing the content, closing a gap a robots.txt disallow rule leaves wide open for anyone with a direct link.

02

The cookie never exposes the password itself

The cookie stores an HMAC derived from the password, instead of the password itself or a reversible encoding of it.

03

Every comparison resists timing attacks

Both the password check and the cookie check use hash_equals(), avoiding the subtle timing differences a standard comparison can leak.

04

A documented limitation, stated plainly

The webserver serves direct file requests, like something inside wp-content/uploads, without routing them through WordPress at all, so this gate doesn't cover them; indeed, every WordPress-level gate shares this same inherent limitation, not just this module.

Verified compatibility

Built directly around WordPress's own request and REST APIs

The supplied code integrates through APIs present in WordPress core; this page makes no compatibility claim beyond the verified implementation.

Front-end request interception

template_redirect action, priority 0

The native WordPress action the module hooks to intercept and gate every front-end page request before rendering begins.

template_redirectPriority 0
REST API authentication

rest_authentication_errors filter

The native WordPress filter the module hooks to reject an unauthenticated REST API request with a proper 401 error.

rest_authentication_errorsNative REST filter
Encrypted password storage

TOWP_FTP_Volume::encrypt() / decrypt()

The plugin reuses its existing encryption utility here to store the configured password encrypted rather than in plain text.

Shared encryption utilityNot plaintext storage
Solution comparison

TheOneWP versus common alternatives

Compare the verified implementation with a typical robots.txt-only approach.

CapabilityTheOneWP Site Password ProtectionOther common solutions
What actually gets gated Pages, feeds and the REST API togetherA robots.txt rule only requests crawlers skip indexing, and stops nobody with a direct link
REST API coverage A dedicated 401 check, closing a separate vectorFrequently left completely open even when the HTML pages are gated
Cookie security An HMAC derived from the password and the site's own saltSome approaches store the password itself, or a reversible value, in the cookie
Password rotation Instantly invalidates every previously-granted cookieSome approaches require a separate step to revoke existing access
Hook priority relative to other modules Registered specifically to run first, closing a real bypass pathRarely considered, leaving room for another module to serve content first
Recommended workflow

Gate the site in four steps

Confirm the gate from a logged-out view before sharing the password.

01

Enable Site Password Protection

Activate the module from the TheOneWP Login settings tab.

02

Set a site password

Enter the password visitors will need; leaving the field blank later keeps whatever password already exists.

03

Confirm the gate as a logged-out visitor

Open the site in a private browser window and confirm the password gate appears before any content.

04

Rotate the password when access should change

Enter a new password whenever previously-granted access should stop working immediately.

Best practices

Share carefully, rotate deliberately

The gate only works as well as how thoughtfully someone actually handles the password itself.

01

Share the password through a separate channel than the link itself

Sending the password alongside the URL in the same message defeats the purpose of gating it in the first place.

02

Rotate the password after a review period ends

Once a client review or testing phase finishes, changing the password closes access cleanly without hunting down who had it.

03

Remember direct file requests aren't covered

Anything served straight from wp-content, like an uploaded file linked directly, bypasses this gate entirely; treat sensitive files accordingly.

04

Turn it off deliberately before launch

Disable the module, rather than just removing the password, to confirm the site is genuinely meant to be public again.

Common mistakes

Avoid assuming more coverage than the gate actually provides

A couple of details are worth understanding clearly before relying on this module.

Assuming a robots.txt rule offers the same protection

A disallow rule only asks search engines not to index a page; it does nothing to stop a person with the direct URL from viewing it.

Expecting this to cover direct file links

Files served straight from the webserver, like something in wp-content/uploads, aren't routed through WordPress and stay reachable regardless of the gate.

Forgetting that changing the password logs everyone out

Rotating the password is often exactly the point, but it's worth remembering that anyone previously let in will need to enter the new one too.

Frequently asked questions

Site Password Protection FAQ

These answers come directly from the verified class and its settings registration.

What does Site Password Protection do?

It puts the entire public site behind a single shared password, covering pages, feeds and the REST API, until someone enters the correct password.

Does this affect logged-in users?

No. Anybody already logged in bypasses the gate entirely, and wp-admin and the login screen are never gated.

Is the REST API protected too, or just the pages?

Both. A separate check gates the REST API specifically, returning a 401 response instead of leaving it open.

What happens if I change the password?

Every visitor who was previously let in gets signed out immediately, since the access cookie is tied to the current password.

Is the password stored securely?

Yes. The module encrypts it before saving, and decrypts it only momentarily to check a submitted password against it.

Does this protect files uploaded to the site, like images or PDFs?

No. The webserver serves direct file requests directly, without routing them through WordPress, so they bypass this gate; every WordPress-level gate shares this same limitation, not just this one.

What happens if the module is enabled but no password is set?

Nothing gets gated; the site remains fully public until a password is actually configured.

Will visitors need to re-enter the password on every visit?

No. A cookie keeps a visitor recognized for 30 days once the correct password has been entered.

Can a search engine index the gated site?

No. The module serves the gate page with a noindex directive and cache-prevention headers.

Who can configure the site password?

Only an administrator with access to the TheOneWP settings screen.

Stop relying on a rule that only asks nicely.Gate the entire site behind one real password.

Use Site Password Protection to close off pages, feeds, and the REST API behind a single password, with staff bypassing it automatically and rotation instantly revoking prior access.