{"id":335948,"date":"2026-08-10T16:45:48","date_gmt":"2026-08-10T16:45:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/takumi-private-gate\/"},"modified":"2026-08-20T21:54:40","modified_gmt":"2026-08-20T21:54:40","slug":"takumi-private-gate","status":"publish","type":"plugin","link":"https:\/\/hsb.wordpress.org\/plugins\/takumi-private-gate\/","author":23527591,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.2.3","stable_tag":"1.2.3","tested":"7.1","requires":"6.0","requires_php":"7.4","requires_plugins":null,"header_name":"Takumi Private Gate","header_author":"Yoshiro Moriyama (Takumi Web Services)","header_description":"Lock down your private WordPress site. Force login for all visitors, block REST API and XML-RPC, and lock out repeated failed login attempts.","assets_banners_color":"f7f9fb","last_updated":"2026-08-20 21:54:40","external_support_url":"","external_repository_url":"","donate_link":"https:\/\/takumi.ca","header_plugin_uri":"https:\/\/github.com\/moriyama-dev\/takumi-private-gate","header_author_uri":"https:\/\/takumi.ca","rating":0,"author_block_rating":0,"active_installs":0,"downloads":114,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.2.2":{"tag":"1.2.2","author":"yoshiromoriyama","date":"2026-08-20 21:33:47"},"1.2.3":{"tag":"1.2.3","author":"yoshiromoriyama","date":"2026-08-20 21:54:40"}},"upgrade_notice":{"1.2.3":"<p>Fixes two-factor authentication, which could not be switched on or off from the profile screen at all in earlier versions. Also closes an Application Password gap in the lockout and stops per-IP records accumulating in the database.<\/p>","1.2.2":"<p>Bundled translation files have been removed for guideline compliance; translations are now provided through translate.wordpress.org.<\/p>","1.2.1":"<p>Internationalization (English source strings plus a Japanese translation) and conflict-safe admin asset handles.<\/p>","1.2.0":"<p>Adds an IP whitelist, optional TOTP two-factor authentication, and multisite network-activation support.<\/p>","1.1.0":"<p>Adds a lockout list with manual unlock, a login attempt log, and email notifications on lockout.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3640984,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3640984,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3640984,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3640984,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.2.2","1.2.3"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3640984,"resolution":"1","location":"assets","locale":"","width":1824,"height":1907}},"screenshots":{"1":"Settings screen under Settings &gt; Private Gate."}},"plugin_section":[],"plugin_tags":[13868,602,870,23853,600],"plugin_category":[38,54,58],"plugin_contributors":[275062],"plugin_business_model":[],"class_list":["post-335948","plugin","type-plugin","status-publish","hentry","plugin_tags-lockout","plugin_tags-login","plugin_tags-private","plugin_tags-rest-api","plugin_tags-security","plugin_category-authentication","plugin_category-security-and-spam-protection","plugin_category-user-management","plugin_contributors-yoshiromoriyama","plugin_committers-yoshiromoriyama"],"banners":{"banner":"https:\/\/ps.w.org\/takumi-private-gate\/assets\/banner-772x250.png?rev=3640984","banner_2x":"https:\/\/ps.w.org\/takumi-private-gate\/assets\/banner-1544x500.png?rev=3640984","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/takumi-private-gate\/assets\/icon-128x128.png?rev=3640984","icon_2x":"https:\/\/ps.w.org\/takumi-private-gate\/assets\/icon-256x256.png?rev=3640984","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/takumi-private-gate\/assets\/screenshot-1.png?rev=3640984","caption":"Settings screen under Settings &gt; Private Gate."}],"raw_content":"<!--section=description-->\n<p>Takumi Private Gate turns a WordPress install into a fully private site: nothing is reachable without logging in first. It's built for people running a diary, notes site, or internal tool on WordPress that should never be publicly visible or crawlable.<\/p>\n\n<p>Unlike most \"force login\" or \"password protect\" plugins, Takumi Private Gate combines four protections in a single, dependency-free plugin:<\/p>\n\n<ul>\n<li><strong>Site-wide lockdown<\/strong>: every page, post, and feed redirects unauthenticated visitors to the standard WordPress login screen.<\/li>\n<li><strong>REST API blocking<\/strong>: unauthenticated requests to <code>\/wp-json\/<\/code> receive a <code>401 Unauthorized<\/code> response.<\/li>\n<li><strong>XML-RPC turned off<\/strong>: every XML-RPC method that requires authentication is refused, so <code>\/xmlrpc.php<\/code> cannot be used to log in, post, or brute-force credentials.<\/li>\n<li><strong>Failed-login lockout<\/strong>: an IP address is locked out for a configurable amount of time after too many failed login attempts, and by default the plugin says nothing that would tell an attacker they're locked out.<\/li>\n<\/ul>\n\n<p>Developed and maintained by Yoshiro Moriyama, founder of Takumi Web Services, a WordPress development studio based in Toronto, Canada.<\/p>\n\n<h4>Features<\/h4>\n\n<ul>\n<li>Redirects every unauthenticated front-end request to <code>wp-login.php<\/code>.<\/li>\n<li>Returns <code>401 Unauthorized<\/code> for unauthenticated REST API requests.<\/li>\n<li>Turns off XML-RPC by refusing every authenticated XML-RPC method (<code>xmlrpc_enabled<\/code>), which closes the login, publishing, and brute-force paths. WordPress still answers <code>\/xmlrpc.php<\/code> for its own unauthenticated introspection methods such as <code>system.listMethods<\/code>; blocking the file outright is a job for the web server.<\/li>\n<li>Locks out an IP address after a configurable number of failed login attempts (default: 5 attempts \/ 30 minutes).<\/li>\n<li>Counts failed Application Password attempts (REST and XML-RPC) toward the same per-IP limit, and refuses Application Password authentication while an IP is locked out.<\/li>\n<li>Lockout state is stored per IP address, not per username.<\/li>\n<li>Lists every currently locked-out IP with a one-click unlock button.<\/li>\n<li>Keeps a rolling log (most recent 1000 attempts) of login attempts with date, IP, username, and result.<\/li>\n<li>Emails the site admin address whenever an IP gets locked out (can be turned off).<\/li>\n<li>IP whitelist (single IPs or CIDR ranges) that bypasses the lockdown, the API blocking, and the lockout entirely.<\/li>\n<li>Optional per-user TOTP two-factor authentication (compatible with Google Authenticator, Authy, 1Password, etc.) enrolled from each user's own profile screen.<\/li>\n<li>Network-activation aware: sets up per-site defaults and its login-log table on every site of a multisite network.<\/li>\n<li>Single settings screen under Settings &gt; Private Gate.<\/li>\n<li>Uninstalling the plugin removes its options, its login-log table, and any 2FA secrets.<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>takumi-private-gate<\/code> folder to <code>\/wp-content\/plugins\/<\/code>, or install it directly from the Plugins screen.<\/li>\n<li>Activate the plugin through the \"Plugins\" screen in WordPress.<\/li>\n<li>Go to Settings &gt; Private Gate to adjust the failed-login threshold and lockout duration.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"will%20this%20lock%20me%20out%20of%20my%20own%20site%3F\"><h3>Will this lock me out of my own site?<\/h3><\/dt>\n<dd><p>Only if you fail to log in more times than the configured threshold (5 by default). <code>wp-login.php<\/code> itself is never blocked, since it's the only way to authenticate.<\/p><\/dd>\n<dt id=\"does%20this%20block%20search%20engines%20and%20rss%20readers%20too%3F\"><h3>Does this block search engines and RSS readers too?<\/h3><\/dt>\n<dd><p>Yes. Since the entire site requires authentication, no unauthenticated client (including search engine crawlers and feed readers) can access any content.<\/p><\/dd>\n<dt id=\"why%20doesn%27t%20the%20login%20form%20say%20i%27m%20locked%20out%3F\"><h3>Why doesn't the login form say I'm locked out?<\/h3><\/dt>\n<dd><p>By default, Takumi Private Gate intentionally shows a generic \"incorrect username or password\" message instead of revealing that the IP is locked out. This keeps an attacker running a brute-force attempt from learning that their requests are being blocked outright. This can be changed in Settings &gt; Private Gate.<\/p><\/dd>\n<dt id=\"will%20i%20get%20emailed%20every%20time%20someone%20fails%20to%20log%20in%3F\"><h3>Will I get emailed every time someone fails to log in?<\/h3><\/dt>\n<dd><p>No. An email is only sent when an IP actually crosses the failed-attempt threshold and gets locked out, not on every failed attempt. This can be turned off in Settings &gt; Private Gate.<\/p><\/dd>\n<dt id=\"does%20the%20login%20log%20grow%20forever%3F\"><h3>Does the login log grow forever?<\/h3><\/dt>\n<dd><p>No. Only the most recent 1000 login attempts are kept; older entries are pruned automatically.<\/p><\/dd>\n<dt id=\"can%20i%20make%20sure%20i%20never%20get%20locked%20out%3F\"><h3>Can I make sure I never get locked out?<\/h3><\/dt>\n<dd><p>Yes. Add your own IP address (or a CIDR range covering it) to the whitelist in Settings &gt; Private Gate. Whitelisted IPs bypass the site-wide lockdown, the REST API\/XML-RPC blocking, and the failed-login lockout.<\/p><\/dd>\n<dt id=\"how%20do%20i%20set%20up%20two-factor%20authentication%3F\"><h3>How do I set up two-factor authentication?<\/h3><\/dt>\n<dd><p>Go to your own Users &gt; Profile screen, find the \"Takumi Private Gate: Two-Factor Authentication (2FA)\" section, add the displayed key to an authenticator app, enter the 6-digit code it shows, then click \"Update Profile\" at the bottom of the page. To turn 2FA off later, tick the box in that same section and click \"Update Profile\" again. No QR code is generated by the plugin, since that would mean sending your secret to a third-party image service; the manual-entry key works with every authenticator app.<\/p><\/dd>\n<dt id=\"does%20%2Fxmlrpc.php%20still%20respond%3F\"><h3>Does \/xmlrpc.php still respond?<\/h3><\/dt>\n<dd><p>The file still exists and WordPress still answers its unauthenticated introspection methods (for example <code>system.listMethods<\/code>), but every method that requires authentication is refused, so it cannot be used to log in, publish, or brute-force credentials. If you want the file itself to return 403 or 404, block it in your web server configuration -- a plugin runs too late in the request to do that.<\/p><\/dd>\n<dt id=\"does%20this%20work%20on%20a%20multisite%20network%3F\"><h3>Does this work on a multisite network?<\/h3><\/dt>\n<dd><p>Yes. If you network-activate the plugin, each site gets its own settings and login-log table, including sites created after activation. Two-factor authentication is tied to the user account and applies network-wide.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.2.3<\/h4>\n\n<ul>\n<li>Fixed: the \"Enable 2FA\" and \"Disable 2FA\" buttons on the profile screen never did anything. Their form was nested inside the profile form, which browsers discard, so the request was never sent. The controls are now part of the profile form itself and are applied with the \"Update Profile\" button.<\/li>\n<li>Fixed: failed Application Password attempts (REST and XML-RPC) were neither logged nor counted toward the lockout, because that code path does not run the <code>authenticate<\/code> filter. They now count like any other failed login, and Application Password authentication is refused while an IP is locked out.<\/li>\n<li>Fixed: per-IP lockout and attempt records stayed in <code>wp_options<\/code> forever. They now expire and a daily cleanup event removes them.<\/li>\n<li>Changed: failed attempts now expire after the configured lockout duration, so an old, isolated failure no longer contributes to a later lockout. Existing attempt counters reset once on upgrade; active lockouts are unaffected.<\/li>\n<li>Changed: corrected the XML-RPC description. The plugin refuses authenticated XML-RPC methods; it does not make <code>\/xmlrpc.php<\/code> stop responding entirely.<\/li>\n<\/ul>\n\n<h4>1.2.2<\/h4>\n\n<ul>\n<li>Removed bundled .po\/.mo translation files; translations are now handled via translate.wordpress.org.<\/li>\n<\/ul>\n\n<h4>1.2.1<\/h4>\n\n<ul>\n<li>Internationalized the plugin: source strings are now in English with a bundled Japanese (ja) translation.<\/li>\n<li>Unique-prefixed the admin asset handles to avoid conflicts with other plugins.<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Added an IP whitelist (single IPs or CIDR ranges) that bypasses the lockdown, API blocking, and lockout.<\/li>\n<li>Added optional per-user TOTP two-factor authentication, enrolled from the user's own profile screen.<\/li>\n<li>Added proper multisite network-activation support (per-site setup on activation and on new site creation).<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Added a list of currently locked-out IPs with a manual unlock button.<\/li>\n<li>Added a login attempt log (date, IP, username, result), capped at the most recent 1000 entries.<\/li>\n<li>Added an email notification to the site admin address when an IP is locked out.<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release: site-wide lockdown, REST API blocking, XML-RPC disabling, and failed-login lockout.<\/li>\n<\/ul>","raw_excerpt":"Lock down your private WordPress site. Force login for all visitors, block REST API and XML-RPC, and lock out repeated failed login attempts.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/335948","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=335948"}],"author":[{"embeddable":true,"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/yoshiromoriyama"}],"wp:attachment":[{"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=335948"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=335948"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=335948"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=335948"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=335948"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/hsb.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=335948"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}