Digipacket Login Security
Standards-based two-factor authentication for any WordPress site, using TOTP (RFC 6238) — so it works with Google Authenticator, Authy, Microsoft Authenticator, FreeOTP and any standard app.
Digipacket Login Security
What it does
No external service and no cloud dependency: secrets, codes and logs are stored in your own WordPress database, and e-mail goes through your site's own wp_mail(). QR-code enrolment is rendered locally rather than through an image service.
-
TOTP, or a code by e-mail
Each user picks an authenticator app or a one-time code sent by e-mail at sign-in.
-
Local QR enrolment
The enrolment code is drawn on the profile screen itself, with no request to an external image service.
-
Brute-force lockout
Lock an account after a configurable number of failed attempts, for a configurable time — even with the correct password.
-
Enforced by role
Require 2FA for chosen roles with a grace period, reset a user's 2FA from the Users list, and see status as a column.
-
Single-use backup codes
For getting back in when the device is lost, each usable once.
-
Audit log
Every security event, filterable by role or user, alongside e-mail alerts for repeated wrong passwords or wrong codes.
What it needs
- WordPress
- 6.0 or newer
- PHP
- 8.2 or newer
- PHP extensions
- No extension beyond a standard PHP build.
Install it
The whole install, in one command
Downloads, checks the file against the SHA-256 below, unpacks it into your plugins directory and cleans up after itself. Any step that fails stops the rest.
cd /path/to/wordpress/wp-content/plugins \
&& curl -fL -O https://github.com/digipacket-net/Digipacket-Login-Security/releases/download/V1.0.1/digipacket-login-security.1.0.1.zip \
&& echo "df2237ff1d197458fc00d90a8fc5952cbe2851a973c3edbe4b7fd3c4e95d062c digipacket-login-security.1.0.1.zip" | sha256sum -c - \
&& unzip -q digipacket-login-security.1.0.1.zip \
&& rm digipacket-login-security.1.0.1.zip
Activate it
With WP-CLI. Without WP-CLI, the plugin is now listed under Plugins → Installed Plugins and the button there does the same thing.
wp plugin activate digipacket-login-security --path=/path/to/wordpress
Why the commands look like this
-
Why -f is not optional
Without it, curl writes the server's error page into your file and exits 0. You unzip an HTML document into wp-content/plugins and WordPress shows a broken plugin. With -f, curl writes nothing and exits 22.
-
Why the checksum is printed here
A hash served next to the file only proves the download was not corrupted in transit. This page is a second channel: if the number here and the number on the file agree, both would have had to be changed.
-
Why the steps are chained with &&
A semicolon runs the next command whether or not the last one worked. With &&, a failed download or a failed checksum stops the chain before anything is written into your plugins directory.
Verify the download
- Version
- 1.0.1 (V1.0.1)
- File
digipacket-login-security.1.0.1.zip- Size
- 99.7 KB 102,069 bytes
- SHA-256
df2237ff1d197458fc00d90a8fc5952cbe2851a973c3edbe4b7fd3c4e95d062c- Published
- 2 September 2026
Check what you downloaded
Prints OK, or names the file and exits non-zero. Run it before you unpack anything.
# GNU coreutils, on a Linux server
echo "df2237ff1d197458fc00d90a8fc5952cbe2851a973c3edbe4b7fd3c4e95d062c digipacket-login-security.1.0.1.zip" | sha256sum -c -
# macOS, and anywhere sha256sum is missing
echo "df2237ff1d197458fc00d90a8fc5952cbe2851a973c3edbe4b7fd3c4e95d062c digipacket-login-security.1.0.1.zip" | shasum -a 256 -c
Always the newest release
The pinned URL above is the one to use in documentation and in a change you want to be able to repeat. In a provisioning script you usually want whatever is current, and there is a trap in the obvious way of asking for it.
The obvious URL breaks on the next release
GitHub serves /releases/latest/download/<file>, but the file name here carries the version. The moment a new version ships, that URL is a 404 — and because it 404s rather than serving an older file, a script that omits -f will happily install an error page.
Ask the API which asset the latest release actually publishes, then download that:
Whatever the newest release is
Asks the API for the asset the latest release actually publishes, then downloads that — so it keeps working when the version and the file name change.
url=$(curl -fsSL https://api.github.com/repos/digipacket-net/Digipacket-Login-Security/releases/latest \
| grep -o '"browser_download_url": *"[^"]*\.zip"' \
| cut -d'"' -f4)
curl -fL -O "$url"
Update it
Removing the folder first is safe: every secret, backup code and log entry is stored in the WordPress database, not in the plugin directory.
Update an existing install
Same chain, with the old directory removed before the new one is written. Unzipping over the top would leave files from the previous version behind.
cd /path/to/wordpress/wp-content/plugins \
&& curl -fL -O https://github.com/digipacket-net/Digipacket-Login-Security/releases/download/V1.0.1/digipacket-login-security.1.0.1.zip \
&& echo "df2237ff1d197458fc00d90a8fc5952cbe2851a973c3edbe4b7fd3c4e95d062c digipacket-login-security.1.0.1.zip" | sha256sum -c - \
&& rm -rf digipacket-login-security \
&& unzip -q digipacket-login-security.1.0.1.zip \
&& rm digipacket-login-security.1.0.1.zip \
&& wp plugin activate digipacket-login-security --path=/path/to/wordpress
Remove it
Remove it
Deactivates first, so WordPress runs the plugin's own deactivation code rather than having the directory disappear underneath it.
wp plugin deactivate digipacket-login-security --path=/path/to/wordpress \
&& wp plugin delete digipacket-login-security --path=/path/to/wordpress
What it does not do
Written down for the same reason as everything else on this page: finding out after you have installed it is worse.
- Optional Telegram notifications are the one feature that leaves your server. They are off by default and need your own bot token and chat id; while enabled, event type, username, IP address and date go to api.telegram.org.
- Hardware security keys (WebAuthn / FIDO2) are not supported — the second factor is TOTP or e-mail.
If a command fails
curl: (22) The requested URL returned error: 404
The file name or the version in the URL is wrong. Copy the command again from this page rather than editing the version by hand — and note that curl wrote nothing, so there is nothing to clean up.
WARNING: 1 computed checksum did NOT match
Do not install it. The download was truncated, or it is not the file this page describes. Delete it and download it again; if it fails twice, write to us before running it.
The plugin appears but will not activate
Almost always the PHP version. Both plugins state their minimum above and refuse to run below it rather than failing halfway — check with php -v on the same server.
Stuck on an install
Send us the command and what it printed.
The output of the command that failed tells us more than a description of it does. Paste it in — there is nothing secret in a download.