What you'll have when you finish
A WordPress install you can take offline behind a friendly 503 maintenance page during a migration, gate behind a single shared password during a staging cycle or soft launch, scope so that only specific pages are protected (or only specific pages are exempt), and configure so that user registration is off, post-login redirects go where you want them, and login sessions expire on a schedule. All five features ship in the free AdminEase, and all five are reversible from the same settings screens.
- Prerequisites: WordPress 5.0+, PHP 7.4+, and a basic AdminEase install.
- You'll need access to: a WordPress admin account, and the ability to test as both a logged-in admin and a logged-out visitor (use an incognito window).
- Time: 15 to 20 minutes for the lockdown features, another 5 to 10 for the related access toggles.
- When to reach for maintenance mode versus password protection
- Configure and enable maintenance mode
- What maintenance mode actually sends to visitors and search engines
- How AdminEase's password protection works under the hood
- Set the site password and the session length
- Scope protection: excluded pages, included pages, bypass archives
- IP binding, brute-force lockout, and the access log
- Pair it with disable frontend user registration
- Redirect after login and logout
- Auto-logout for stale sessions
Five features sit in this tutorial. The first two are different ways to take the site away from visitors: maintenance mode shows a friendly "we'll be back" page, full-site password protection gates the site behind a shared password. The other three tighten what happens when users do get in: disable frontend registration stops anonymous sign-ups, redirect after login and logout controls where users land, and auto-logout sets an expiry on stale sessions.
Each section names the exact path. Most of what we'll touch lives under AdminEase › Security › Site Lock and AdminEase › Users › Authentication. Maintenance mode is the odd one out: it sits under AdminEase › Debug › Maintenance Mode, on the principle that taking a site offline is a debugging or operational action, not a security action.
1. When to reach for maintenance mode versus password protection
These two features look superficially similar (both interrupt the normal site for visitors, both let admins through, both render a templated page) but they solve different problems.
Reach for maintenance mode when: the site is being changed and you do not want anyone to see broken intermediate states. Migrating to a new host, running a major plugin update, restructuring URLs. The audience is "everyone on the internet," and the message is "we'll be back shortly." Search engines need to know this is temporary, not a permanent removal.
Reach for password protection when: the site is finished but the audience is restricted. Pre-launch reviews for a client, a staging cycle where stakeholders need to click through, a private blog that only invited readers should see. The audience is "people who have the password," and the gate stays up until you remove it.
Retry-After header. Search engines treat this as temporary and come back later. Password protection returns a normal HTML page (the password form) with a 200 response. To search engines, that just looks like your site's content, which is not what you want long-term. If you intend a site to be private for weeks or months, add noindex headers via your theme or a separate plugin alongside the password protection.
2. Configure and enable maintenance mode
Maintenance mode replaces the front-end of the site with a single templated page for every logged-out visitor. Admins (anyone with the edit_posts capability) bypass it automatically and see the site normally, which is what makes it safe to flip on without locking yourself out.
The defaults are sensible: page title set to {your blog name} - Maintenance Mode, headline set to your blog name, message set to "We are currently performing scheduled maintenance. Please check back soon!", colors at WordPress-admin blue and dark grey, and Retry-After at 3600 seconds (1 hour). The message field accepts basic HTML, so you can add a link to your status page, a Twitter handle, or an expected return time.
3. What maintenance mode actually sends to visitors and search engines
When maintenance mode is active and a logged-out visitor hits the site, AdminEase intercepts the request at template_redirect priority 0 (early enough that no template loading happens) and emits the following:
- HTTP status:
503 Service Temporarily Unavailable. Retry-Afterheader, set to the value you configured (default 3600). Setting Retry-After to 0 in the settings disables this header.- Cache-busting headers:
Cache-Control: no-store, no-cache, must-revalidate, max-age=0plusPragma: no-cache. - Three PHP constants defined for cooperating cache and minification plugins:
DONOTCACHEPAGE,DONOTCACHEOBJECT, andDONOTMINIFY. WP Rocket, W3 Total Cache, Autoptimize, and most major caching plugins honor these.
The Classic theme renders the page using your configured colors, headline, message, and (optionally) the Customizer logo. The full output HTML is passed through the adminease_maintenance_mode_html filter before being echoed, so a developer can replace the template entirely from a mu-plugin if needed.
no-cache headers in place, edge caches will not pick up the change until they expire or get purged. Purge the cache the moment you enable maintenance mode, and again when you disable it.
4. How AdminEase's password protection works under the hood
Before configuring it, understand the mechanism. Password protection in AdminEase is stateless: it does not use PHP sessions and it does not store anything per-visitor in the database. Authentication is carried entirely in a signed cookie. This matters because PHP sessions break page caches (every visitor gets a unique session cookie, defeating the cache key), and stateless cookie auth does not.
The mechanics, in order:
- Visitor submits the site password through the form. The submission goes via AJAX, with a nonce.
- AdminEase checks the submitted password against the stored hash using WordPress's
wp_check_password(). The stored value is a phpass, bcrypt, or argon2 hash. The plaintext is never stored. If a site is migrating from an older AdminEase that stored plaintext, the first successful login transparently rewrites the stored value as a hash. - On success, AdminEase issues a cookie containing a JSON blob:
{v: 2, t: issued-timestamp, e: expiration-timestamp, h: HMAC-SHA256-signature}. The signature key is derived fromwp_salt('auth')and the stored password hash, so changing the password instantly invalidates every existing cookie on the site. - The cookie is set with
HttpOnly,Secure(when SSL is active), andSameSite=Lax. The cookie name isadminease_pps_auth_followed by a CRC32 hash of the site's home URL, which keeps multi-site installs separated. - On every subsequent request, AdminEase reads the cookie, verifies the signature with
hash_equals()(timing-safe), and lets the request through if it matches.
Failed attempts are tracked per-IP via a WordPress transient (no extra database table). After 5 failed attempts within a 30-minute window, the IP is locked out for the rest of the window. Successful login clears the counter.
5. Set the site password and the session length
Choose a strong password (long, random, not reused). The "Force strong passwords" feature from Article 1 does not apply to the site password, because that is a different authentication flow. Pick something that would survive a brute-force attempt even without the rate-limit lockout.
Session length is governed by the password_protect_site_remember_device setting. The defaults: if "remember device" is not requested at login, the cookie is a browser-session cookie and expires when the browser closes. If "remember device" is requested, the cookie persists across browser sessions for 1 day. Both can be overridden via the adminease_password_protect_site_remember_device_expiration filter from a mu-plugin if your use case needs a longer remember window.
6. Scope protection: excluded pages, included pages, bypass archives
The default behavior of password protection is "gate the whole site." You can narrow that in two opposite directions:
- Excluded pages: a multi-select of any published post, page, or custom post type. Selected items bypass protection while everything else stays gated. Typical use: keep the privacy policy and contact page public on an otherwise password-gated site.
- Included pages: the inverse. When set, ONLY the selected items show the password form, and everything else passes through unprotected. Typical use: protect a single landing page or a small group of pages on an otherwise public site.
- Bypass on archives & home: a single toggle that lets archive pages, the blog index, the front page, search results, and 404 pages through without authentication. Useful for sites where the homepage is meant to be public but individual articles are gated.
Both lists support any public post type, not just pages. The selector queries via AJAX as you type, so it scales to thousands of posts without slowing the settings page.
7. IP binding, brute-force lockout, and the access log
Three more controls round out the password protection feature.
Bind Authentication To IP is a toggle that adds the client IP hash to the cookie signature payload. When enabled, the cookie becomes invalid the moment the visitor's IP changes. The trade-off is security versus convenience: it stops a stolen cookie from being replayed elsewhere, but it also logs out mobile users who switch between Wi-Fi and cellular. Leave it off if your audience is mobile-heavy, turn it on for a desktop-only audience like an agency review portal.
Brute-force lockout is on by default and not configurable from the UI. After 5 failed password attempts from the same IP within 30 minutes, that IP gets a "too many attempts" response on every subsequent attempt until the window expires. The counter is stored as a per-IP transient (key derived from md5(client_ip)) and the window is anchored on the first attempt, not the most recent, so the lockout is a fixed half-hour rather than a sliding one.
Access log records every authentication attempt (success, failure, lockout) with timestamp, IP, user agent, status, and (for failures) a SHA-256 hash of the attempted password. The default retention is 1000 entries, configurable up to 10000 or set to 0 to disable logging entirely. The log is stored as a non-autoloaded WordPress option, so it does not bloat every page load even when long.
8. Pair it with disable frontend user registration
If you have password protection on a public site, or you have a finished site that should not accept new user accounts, the frontend registration form is dead weight. AdminEase has a one-toggle disable that handles it on four levels at once.
When enabled, AdminEase:
- Sets the WordPress core option
users_can_registerto 0 on everyinithook at priority 1 (so even if a plugin re-enables it, it gets reset). - Blocks the default
wp-login.php?action=registerform by returning a 403 page titled "Registration Disabled" when that URL is requested. - Filters
register_urlto return an empty string, so any theme code that prints a "Register" link gets nothing. - Registers a REST API override at
POST /wp/v2/usersthat returns a 403 with the message "User registration is disabled." This blocks programmatic registration via the REST API.
9. Redirect after login and logout
By default, WordPress sends users to the admin dashboard after login and to the login page after logout. Neither default is what you want on most non-admin sites: editors get dropped into an admin they do not need to see, and logged-out users end the journey on a generic WP login screen rather than back at your homepage.
Behind the scenes, AdminEase hooks into wp_login at priority 999 (high enough to run after most other plugins that might also redirect, so the AdminEase setting wins) and wp_logout at priority 1. Both redirects use wp_redirect() with esc_url_raw() on the configured URL.
wp_login hook. AdminEase's redirect is a global one-URL-fits-all setting.
10. Auto-logout for stale sessions
The default WordPress login session lasts two days (48 hours), or 14 days if "remember me" is checked. For most sites that is too long. A laptop left on a coffee-shop table with WordPress admin open is a real, common scenario, and the longer the session, the larger the window of risk.
What it actually does: AdminEase filters auth_cookie_expiration and returns your configured value instead of the WordPress default. Existing sessions keep their original expiry (the cookie is already issued), but every new login from this point on will get a session that expires after your chosen interval. The filter is exposed as adminease_auth_cookie_expiration for further customization in code.
For agency-managed client sites, 8 hours is a reasonable default: long enough that an editor working a full day will not get logged out mid-task, short enough that a forgotten session expires by morning. For higher-security contexts (financial, healthcare, anything regulated) 30 minutes to 1 hour is more appropriate.
Where to go from here
You now have two distinct ways to make a WordPress site unavailable to visitors (maintenance mode for "temporarily down" with proper SEO signals, password protection for "permanently private" with a stateless cookie gate), plus the three access toggles that pair naturally with both: no anonymous registration, controlled post-login destinations, and session expiry that matches your risk tolerance.
The companion tutorials in the security set cover the layers above and below this one. Below: "Hardening WordPress Security with AdminEase" closes the most-exploited attack surfaces at the configuration layer. Above: "Geo-Blocking & Bot Protection" filters traffic by country and bot identity at the web-server layer. Together the three tutorials cover most of what AdminEase's Security tab does.
Frequently asked questions
Can I use maintenance mode and password protection at the same time?
Yes, and they layer in a specific order. Maintenance mode runs first (at template_redirect priority 0). Password protection also hooks template_redirect at priority 0 but checks is_user_logged_in(). If maintenance mode is on, logged-out visitors get the maintenance page before they ever see the password form. If you specifically want the password form to be reachable during a maintenance window (for client previews), you have to gate maintenance mode with the adminease_maintenance_mode_check_access filter, returning true for password-protected visitors.
Will password protection break my page cache?
No, by design. The authentication is carried in a single cookie that varies between authenticated and unauthenticated visitors, but the cookie name is fixed and predictable. Most page-cache plugins can be configured to vary cache keys on the presence of this cookie. Without that configuration, cached pages may briefly show to unauthenticated visitors and vice versa. WP Rocket's "User Cache" and W3 Total Cache's "Vary by cookie" options both handle this. On host-managed caches (WP Engine, Kinsta), open a support ticket and reference the cookie name adminease_pps_auth_*.
What happens if I forget the site password?
The password is stored hashed, so it cannot be recovered. Reset it by going to AdminEase › Security › Site Lock › Site Password in the admin and entering a new value. (You can still get into the admin because is_user_logged_in() bypasses the password gate.) If you have somehow lost both the WordPress admin password and the site password, you need standard WordPress recovery: SFTP to the server, reset the WP admin via WP-CLI or the database, then reset the site password from the dashboard.
Can different team members have different site passwords?
Not in the current release. The Site Lock feature uses a single shared password for all gate-passers. If you need per-user access, the right tool is the regular WordPress user system (give your reviewers actual user accounts) and password protection is the wrong layer. Site Lock is intended for short-term shared-secret access (a soft launch, a beta cycle, a client review), not for ongoing per-user authentication.
Do these features work on a multisite network?
Maintenance mode and password protection are configured per site, not network-wide. The cookie name includes a CRC32 hash of home_url(), which keeps authenticated state separated between sites in the same network: a visitor authenticated on site-a.example.com is not automatically authenticated on site-b.example.com. The other three toggles (registration, redirects, auto-logout) work per-site as well.
If I enable auto-logout at 30 minutes, does that log out users mid-session?
No. Auto-logout sets the expiry on new auth cookies issued at login. A user who was already logged in keeps their existing session until that cookie's original expiry passes. The new shorter expiry kicks in on their next login. If you need to force-expire current sessions immediately, use Users › Your Profile › Log Out Everywhere Else on each user, or programmatically destroy session tokens via WP-CLI.