Open-source project
WordPress/two-factor avatar
WordPress/two-factor

two-factor: the WordPress plugin that adds a second step to the login

Two-Factor Authentication for WordPress.

824 stars191 forksPHPGPL-2.0

At a glance

What is it?
The WordPress Two-Factor plugin requires users to supply a second form of authentication in addition to their password, and it is shipped, installed and updated through the WordPress.org plugin directory. The interesting parts of the repository are the ones a security plugin rarely shows: a Docker based development environment, two separate test suites for single site and multisite installs, and releases that deploy themselves from a tag.
Who is it for?
Adopt the Two-Factor plugin if you run WordPress sites where a password alone is not enough protection, especially with administrators, because it adds a second authentication step that is enforced at the login rather than left to a policy. Do not adopt it as a replacement for good credential hygiene, since it protects against compromised passwords rather than weak ones.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One feature, and the plugin directory does the installing

The Two-Factor plugin is described as adding an extra layer of security to a WordPress login by requiring users to provide a second form of authentication in addition to their password, and it says plainly that this helps protect against unauthorised access even if passwords are compromised.

That is the entire scope, and it is worth noticing what the plugin does not try to be. It is not a password manager, not a policy engine and not a session hardening tool. It is a second factor.

The distribution model is what shapes how a site owner meets it. The plugin lives in the WordPress.org plugin directory, where it is installed and updated the way any other plugin is, and the repository carries the assets that directory needs, including the plugin banner and the metadata that the directory reads. The readme badges in the repository show the required PHP version, the required WordPress version, the version tested up to, the licence, the directory rating, the download count and the number of active installations.

There is also a WordPress Playground blueprint, which means you can open a live instance of the plugin in a browser sandbox and click through the enrolment flow without installing anything. For a plugin whose whole purpose is a security-critical screen, being able to try the flow in a throwaway environment is a genuinely useful affordance.

The topic list for the repository is short and accurate: two-factor authentication, authentication, time-based one-time passwords, WordPress and the plugin category. The last push was on 2026-10-18, and the recent releases are 0.16.0 in March 2026, a release candidate for 0.17.0 in September, and 0.17.0 a few days later.

The file layout shows a plugin with a compatibility layer and a provider split

The repository listing is short, and the names carry most of the information.

The entry point is a file named for the plugin, and beside it are two class files whose names say exactly what they are: a core class and a compatibility class. The compatibility file is the interesting one to notice, because in a plugin that ships to millions of sites, supporting the older PHP and WordPress versions still in use is a separate, deliberate piece of work rather than an accident.

Then there are directories with obvious jobs. An includes directory, a providers directory and a settings directory, and a command line directory. That last one is a signal about how the project has grown: a plugin that ships its own command line entry point is doing more than rendering a settings screen.

There is also a stylesheet for the user edit screen, which is the one piece of user interface the plugin has, since adding a second factor means the account page has to show and manage it.

The packaging metadata is in the root as well, a distribution ignore file that decides what does not go into the plugin directory, a WordPress environment file, and a WordPress.org assets directory. The environment file matters more than it looks, because it describes the local development cluster that the test suites run against.

The code quality tooling is split by language, which is normal for a WordPress project where the JavaScript is front end glue and the PHP is the plugin itself: a coding standards configuration for PHP, a static analysis configuration, two separate PHPUnit configuration files for the single site and multisite suites, a watcher configuration, an ESLint configuration and a Grunt file.

Development runs inside a Docker environment, not on your machine

The contribution section is unusually practical, and it starts by telling you what you need: Docker, installed and running, for the provided development environment.

The sequence is four commands from a fresh clone:

bash
git clone https://github.com/wordpress/two-factor.git
cd two-factor
npm install
npm run build
npm run env start

The interesting part is the split between the JavaScript build and the environment. The build step runs a task runner over the front end assets, and the environment step starts a WordPress instance in containers. Nothing in the loop expects a PHP installation on your machine or a database, which is the correct trade for a plugin that has to work against several WordPress and PHP versions.

The project file backs this up. The package requires Node 24 or newer, it is marked private so it is never published, and the environment script is a thin wrapper around the WordPress environment tooling. There is also a preinstall hook that runs the PHP dependency install, so a single npm install sets up both sides.

The rest of the script list is the ordinary surface of a WordPress plugin project, and it is worth reading because it shows what the maintainers consider part of the definition of done. There are lint scripts for PHP, for static analysis, for styles and for JavaScript, matching format scripts for the same four, a blueprint script for the Playground URL, and a composer script that runs the PHP tooling inside the environment container rather than on the host, pinned to the plugin directory inside the WordPress installation.

Two suites, because a WordPress plugin has two ways to exist

The testing section explains the split that anyone who has tested a WordPress plugin will recognise immediately.

Running the test command executes the single site and the multisite suites in sequence. The watch variants run one suite at a time, and the README points at a separate document for the full set of runners, which suggests the script list has grown beyond what a readme can hold.

The distinction is not a detail. A plugin that is installed on a single site and a plugin that is installed on a network of sites are different software in several ways, from how roles and capabilities work to how a second factor is scoped per user, and a test suite that only covers the first will pass happily while the second is broken.

The coverage story is also spelled out. To generate a coverage report you start the testing environment with coverage support enabled, which is a flag passed to the environment script, and then you open the generated HTML report from a path in the tests directory. The codecov configuration and badge are in the repository, and the continuous integration workflow is separate from the deploy workflow.

What is not described is what the tests assert, and that is where the interesting question for an adopter lies. The repository has a test directory, a unit test configuration and a multisite configuration, but the README does not summarise the coverage of the plugin's own behaviour, so a reader has to look at the tests themselves to judge how much of the authentication path is exercised.

Releases are a tag and a workflow, not a manual upload

The deployment section describes a process that has clearly been set up to avoid manual steps, and it is the part of a WordPress plugin repository that most maintainers get wrong.

Deployments to the plugin directory are handled automatically by a GitHub action. Versioned releases are deployed from Git tags, and the tagged versions are published into a tags directory in the plugin repository's own tracker, which is the standard way the WordPress.org directory keeps old versions available for download. The README points at the workflow file for the current branch and release conditions that govern when the readme and assets are updated, and there is a separate release document for the process itself.

The recent release history shows that process working. A release candidate for 0.17.0 went out on 2026-09-25, and the 0.17.0 release itself on 2026-09-28, three days later, with 0.16.0 in March. A candidate that ships first and the final shortly after is a pattern for letting users and reviewers look at a build before it lands in the directory.

Two more files complete the picture. A changelog with a complete listing of all notable changes, and a credits file, since the plugin is released under the GPL and its licence file is in the repository alongside the readme and the plugin metadata.

The security route is the one that matters most for a security plugin, and it is the most properly handled. Non-security issues go to the public tracker, while potential security and privacy vulnerabilities are to be reported privately to the WordPress HackerOne programme, and the contribution section points at both.

Editorial conclusion

Adopt the Two-Factor plugin if you run WordPress sites where a password alone is not enough protection, especially with administrators, because it adds a second authentication step that is enforced at the login rather than left to a policy. Do not adopt it as a replacement for good credential hygiene, since it protects against compromised passwords rather than weak ones. Before you enable it, read the installation notes in the plugin readme file, plan the recovery path for accounts without a second factor, and check which role the plugin requires you to assign, because a misconfigured rollout can lock people out of their own site.

Frequently asked questions

What does the WordPress Two-Factor plugin do?

It adds an extra layer of security to a WordPress login by requiring users to provide a second form of authentication in addition to their password, which helps protect against unauthorised access even if passwords are compromised. It is published through the WordPress.org plugin directory and is MIT-style permissive in the sense of the GPL, being released under GPLv2 or later.

How do I set up a development environment for the Two-Factor plugin?

Install and start Docker first, then clone the repository, run npm install, run the build step and start the environment. The project file requires Node 24 or newer, and its preinstall hook also runs the PHP dependency install, so one npm install prepares both sides.

How are the Two-Factor plugin tests run?

The test command runs the single site and the multisite suites in sequence, and there are watch variants that run one suite at a time. A separate document lists the full set of runners, and a coverage report is produced by starting the environment with coverage support enabled.

How are new versions of the Two-Factor plugin released?

Deployments to the WordPress.org plugin repository are handled automatically by a GitHub action, and versioned releases are deployed from Git tags into a tags directory in the plugin repository. The repository holds a changelog of all notable changes and a separate release document describing the process.

How do I report a security problem in the Two-Factor plugin?

The README asks for potential security and privacy vulnerabilities to be reported privately to the WordPress HackerOne programme. Non-security issues, and pull requests, go to the public issue tracker on GitHub, and there is a channel on WordPress Slack for discussion.

Official sources

  1. License: GPL-2.0
  2. Project website
  3. README
  4. Releases
  5. WordPress/two-factor on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/wordpress-two-factor.svg)](https://hysenlabs.com/projects/wordpress-two-factor)

Was this useful?