Title: Rapls Passkey
Author: rapls
Published: <strong>August 11, 2026</strong>
Last modified: August 12, 2026

---

Search plugins

![](https://ps.w.org/rapls-passkey/assets/banner-772x250.png?rev=3642248)

![](https://ps.w.org/rapls-passkey/assets/icon-256x256.png?rev=3642248)

# Rapls Passkey

 By [rapls](https://profiles.wordpress.org/rapls/)

[Download](https://downloads.wordpress.org/plugin/rapls-passkey.0.13.70.zip)

 * [Details](https://vec.wordpress.org/plugins/rapls-passkey/#description)
 * [Reviews](https://vec.wordpress.org/plugins/rapls-passkey/#reviews)
 *  [Installation](https://vec.wordpress.org/plugins/rapls-passkey/#installation)
 * [Development](https://vec.wordpress.org/plugins/rapls-passkey/#developers)

 [Support](https://wordpress.org/support/plugin/rapls-passkey/)

## Description

Rapls Passkey lets users sign in to WordPress with passkeys (WebAuthn / FIDO2).

 * Passwordless, phishing-resistant sign-in
 * Same-device passkeys (Touch ID / Windows Hello)
 * Cross-device sign-in using the browser’s native passkey flow when the browser
   offers it (scan with your phone). A custom QR approval flow is available in Pro.
 * Shortcodes and Gutenberg blocks (login / passkey management) you can embed on
   any page
 * Rename, suspend and resume individual passkeys — a device that is temporarily
   out of reach can be cut off without destroying the credential
 * A site-wide passkey list for administrators (Users -> Passkeys), searchable by
   owner or name
 * Works with two-factor plugins (Wordfence Login Security, Two-Factor, …): a passkey
   counts as the second factor, while weaker alternative logins must still pass 
   the site’s 2FA
 * Fully translatable UI (English source; translations come from translate.wordpress.
   org)

#### Shortcodes

Embed them in any page, post, or widget. In the block editor they are also available
as the “Sign in with a passkey” and “Manage passkeys” blocks.

 * `[rapls_passkey_login]` — a passkey sign-in button for logged-out visitors. Supports
   the `redirect` (URL to go to after success) and `label` (button text) attributes.
 * `[rapls_passkey_register]` — a management UI where logged-in users can register
   and remove their own passkeys.

#### Requirements

 * PHP 8.2 or later
 * WordPress 6.0 or later
 * HTTPS (except on localhost)

#### Rapls Passkey Pro

Everything above is free, and stays free. Pro is a separate add-on for the part

that comes after the first passkey: moving a whole site across, and keeping a way
in when a device goes missing.

 * **Sign in from another device** — approve a login on your computer from your 
   phone, with a QR code and a four-digit confirmation code so a relayed code cannot
   be used elsewhere
 * **A way back in that is not a password** — one-time recovery codes and email 
   magic-link sign-in
 * **Roll out by role** — require passkeys for the roles you choose, with a grace
   period, then turn password login off once everyone is across
 * **Adaptive step-up** — ask for a passkey again after a password sign-in from 
   somewhere unfamiliar
 * **Authenticator policy** — FIDO Metadata Service checks, AAGUID allow and deny
   lists, trusted-device management
 * **Operations** — security webhooks, adoption reports, multisite network settings,
   WP-CLI

One-time purchase, no subscription, with a year of updates and a 14-day refund.

[Details and pricing](https://raplsworks.com/rapls-passkey-pro/)

### External services

This plugin sends nothing to any external service by default. One optional
 integration,
off unless you turn it on, contacts a third party:

**Google reCAPTCHA v3** — used only when you enable reCAPTCHA for password
 logins.
When it is on, the visitor’s browser loads https://www.google.com/recaptcha/api.
js, and the plugin sends the resulting token together with the request IP address
to https://www.google.com/recaptcha/api/siteverify so that Google can score the 
request. Nothing is sent while the option is off. This service is provided by Google
and its use is governed by Google’s terms and privacy policy:

 * Terms of Service: https://policies.google.com/terms
 * Privacy Policy: https://policies.google.com/privacy

No other host is contacted. The plugin bundles the public suffix list it needs
 (`
data/public_suffix_list.dat`) rather than fetching it, and passkey ceremonies happen
between the browser and your own site.

### Privacy

Authentication data is stored on your own site.

What is stored:

 * Passkey credential records (public key, credential ID, sign counter, a label 
   and timestamps) in a custom database table.
 * A per-user WebAuthn user handle in user meta, plus one row in the options table
   recording that the account has one. The handle carries nothing about the person:
   for accounts created from this version it is derived from the account id and 
   a site secret, and accounts that already had a random handle keep it.
 * An optional audit log of passkey events (registration, sign-in, removal) with
   the acting user, IP address and timestamp.

Retention and removal:

 * Passkey records remain until the user or an administrator deletes them; deleting
   a user removes their passkey records.
 * The plugin integrates with WordPress’s built-in personal-data export and erase
   tools, so a user’s passkey and audit data are included in export/erase requests.
 * Uninstalling the plugin (delete from the Plugins screen) drops its custom table
   and options.

This plugin does not use cookies for tracking. It sets only short-lived, functional
cookies during a login ceremony (for example the pending second-factor login), which
expire within minutes.

## Screenshots

[⌊Sign in with a passkey from the normal WordPress login screen.⌉⌊Sign in with a
passkey from the normal WordPress login screen.⌉[

Sign in with a passkey from the normal WordPress login screen.

[⌊The browser offers the passkeys saved for this site.⌉⌊The browser offers the passkeys
saved for this site.⌉[

The browser offers the passkeys saved for this site.

[⌊Your registered passkeys: rename, suspend or delete each one.⌉⌊Your registered
passkeys: rename, suspend or delete each one.⌉[

Your registered passkeys: rename, suspend or delete each one.

[⌊Registering a passkey from your profile screen.⌉⌊Registering a passkey from your
profile screen.⌉[

Registering a passkey from your profile screen.

[⌊Touch ID confirms before the passkey is saved.⌉⌊Touch ID confirms before the passkey
is saved.⌉[

Touch ID confirms before the passkey is saved.

[⌊Choose where the passkey is stored.⌉⌊Choose where the passkey is stored.⌉[

Choose where the passkey is stored.

[⌊The first-run check: HTTPS, the relying-party ID, and the WebAuthn library.⌉⌊The
first-run check: HTTPS, the relying-party ID, and the WebAuthn library.⌉[

The first-run check: HTTPS, the relying-party ID, and the WebAuthn library.

[⌊Every registration, sign-in and removal, exportable as CSV.⌉⌊Every registration,
sign-in and removal, exportable as CSV.⌉[

Every registration, sign-in and removal, exportable as CSV.

## Blocks

This plugin provides 2 blocks.

 *   Sign in with a passkey
 *   Manage passkeys

## Installation

 1. Place the plugin in `wp-content/plugins/rapls-passkey`.
 2. Activate “Rapls Passkey” from the Plugins screen.
 3. Register a passkey from your profile screen.

## FAQ

### Is the free version limited?

No. Passkey sign-in, registration, management, the shortcodes and blocks, the
 administrator’s
passkey list and the two-factor integrations are all in the free plugin, without
a cap, a trial period or a licence key. Rapls Passkey Pro is a separate add-on that
adds different features — cross-device QR login, recovery codes, enforcement by 
role — and installing it is not required for anything described above to work.

### What if I lose my passkey and cannot sign in?

Password login still works alongside passkeys, so sign in with your password as 
usual and then remove or re-register passkeys from your profile screen.

You can also manage passkeys from the server with WP-CLI:

    ```
    wp rapls-passkey list --user=admin
    wp rapls-passkey remove <id>
    ```

In an emergency, add the following to wp-config.php to temporarily disable passkey
enforcement (remove it once you have recovered):

    ```
    define( 'RAPLS_PASSKEY_BYPASS', true );
    ```

## Reviews

There are no reviews for this plugin.

## Contributors & Developers

“Rapls Passkey” is open source software. The following people have contributed to
this plugin.

Contributors

 *   [ rapls ](https://profiles.wordpress.org/rapls/)

“Rapls Passkey” has been translated into 1 locale. Thank you to [the translators](https://translate.wordpress.org/projects/wp-plugins/rapls-passkey/contributors)
for their contributions.

[Translate “Rapls Passkey” into your language.](https://translate.wordpress.org/projects/wp-plugins/rapls-passkey)

### Interested in development?

[Browse the code](https://plugins.trac.wordpress.org/browser/rapls-passkey/), check
out the [SVN repository](https://plugins.svn.wordpress.org/rapls-passkey/), or subscribe
to the [development log](https://plugins.trac.wordpress.org/log/rapls-passkey/) 
by [RSS](https://plugins.trac.wordpress.org/log/rapls-passkey/?limit=100&mode=stop_on_copy&format=rss).

## Changelog

#### 0.13.70

 * **Fixed: on PHP older than 8.2 the whole site went down, front end included.**
   The bundled dependencies require 8.2, and Composer’s platform check throws the
   moment the autoloader is read — inside WordPress’s plugin loading, where nothing
   catches it. The plugin now checks the version first and steps aside with an admin
   notice, leaving the rest of the site alone. The `Requires PHP` header does not
   cover this on its own: WordPress reads it when activating and when offering an
   update, so a server whose PHP is lowered afterwards, or a WP-CLI running an older
   PHP than the web server, went straight past it.

#### 0.13.69

 * The Rapls Passkey Pro panel moved into a sidebar that follows the page down. 
   It sat at the very bottom of a single column, below the audit table, where nobody
   scrolls. It also says what the add-on is for rather than listing features, the
   Plugins screen gains “Settings” and “Go Pro” row links, and the adoption figure
   names what closes the gap. Nothing on the page is gated: the readme now has a
   Pro section and an FAQ entry saying plainly that the free version has no cap,
   trial or licence key.
 * Asks for a WordPress.org review, once. After a week of use, and only if a passkey
   has actually been registered, a notice on this plugin’s own two screens asks 
   for one. Every button — including the close button — settles it for good, and
   rapls_passkey/show_review_prompt turns it off entirely. It never appears anywhere
   else in wp-admin and never comes back.
 * Corrected: the readme claimed a bundled Japanese translation, which has not been
   true since 0.13.62. Translations come from translate.wordpress.org.

#### 0.13.68

 * Screenshots for the plugin directory listing, and the readme section that names
   them. No change to the plugin.

#### 0.13.67

 * Tests only, and one that was worth finding: nothing asserted that registering
   a passkey for another user is on by default. The stub in the enrolment test answered
   the filter itself, so the shipped default was never read — flip it back to off
   and every test still passed. The default is now under test, on both call sites,
   and the source is checked for wording that ties the feature to the paid add-on.

#### 0.13.66

 * **Registering a passkey for another user is on by default.** It was implemented
   but switched off, and the Pro add-on turned it on — which made a built-in feature
   depend on a licence, and that is not allowed here. The capability check was always
   the real bound and it has not changed: only someone who can already edit that
   user, and could therefore reset their password and sign in as them, can enrol
   for them. Pro’s setting now only turns the feature off.
 * The second-factor screen filters the markup its 2FA provider prints, to the form
   controls such a screen needs. The two bundled adapters are unaffected, byte for
   byte; inline JavaScript from a provider is dropped, and a provider that needs
   it should enqueue it.
 * The package no longer carries the Japanese catalogue or `load_plugin_textdomain()`.
   WordPress.org builds translations for every locale from translate.wordpress.org
   and loads them on demand, and a bundled copy would only shadow that.
 * Dropped two test-only directories that Composer installs inside third-party packages(`
   doctrine/deprecations`, `symfony/clock`).

#### 0.13.65

 * Clears the last of the WordPress Plugin Check warnings against the shipped package.`
   $_SERVER['REQUEST_METHOD']`, a `redirect_to` from the query string and the “seen
   device” cookie are now unslashed and sanitised on the way in rather than only
   validated afterwards; the uninstall script’s two loop variables are prefixed,
   since a file that runs at global scope defines globals; and the exemption on 
   the DROP TABLE in uninstall named the wrong rule.
 * `composer.json` ships with the package again. WordPress.org’s scan asks for it
   wherever a `vendor/` directory is present, and it is the manifest that says what
   is in there. `composer.lock` stays out. Note for anyone reading the package: `
   vendor/` has already been namespace-prefixed by the build, so do not run `composer
   install` inside an installed copy.
 * No functional change.

#### 0.13.64

 * Readme only: `Tested up to` named a patch release (7.0.2). WordPress.org’s automated
   scan requires the major version alone, and rejected the upload over it. It reads
   7.0 now; the plugin is unchanged and was tested against 7.0.2.

#### 0.13.63

 * **Direct-access protection was missing from every file in the distributed package.**
   The plugin guards each file with `if ( ! defined( 'ABSPATH' ) )`, which the build
   rewrites to `if ( ! \defined( 'ABSPATH' ) )` — a form the WordPress Plugin Check
   tool does not recognise. Every shipped file therefore read as unprotected to 
   the tooling, while the repository looked correct. The guard is now written in
   the form that survives the build.
 * **The code-standard exemptions in the shipped files were pointing at the wrong
   lines.** They were written at the end of the line they applied to, and the build
   moves a trailing comment onto the following line — so each one silenced the line
   after the one it was meant to cover. All of them are now written above the line
   they apply to.
 * Fixes the findings these two hid: an unescaped exception message, a missing translators
   comment, a database call whose exemption named the wrong rule, and the CSV export’s
   file handle. Behaviour is unchanged; the audit-log CSV, the two-factor integrations
   and the passkey cap all work exactly as before.
 * Also: `Plugin URI` pointed at this plugin’s WordPress.org page, which the plugin
   header documentation does not allow, and `Author URI` was missing. The readme’s
   external-service disclosure (optional reCAPTCHA) is now its own section, and 
   releases older than 0.13.46 have moved to changelog.txt.

#### 0.13.62

 * No change to the plugin. Release-tooling only: the rebuild check reported “identical”
   beside two different archive checksums, when what matches is every file inside
   them.

#### 0.13.61

 * No change to the plugin. Release-tooling only: the rebuild check exempted two
   whole files from comparison instead of two fields inside them.

#### 0.13.60

 * No change to the plugin. Release-tooling only: the rebuild check now runs in 
   CI on every release and compares the two packages as file trees.

#### 0.13.59

 * No change to the plugin. Release-tooling only: the claim made by the verification
   bundle is now narrower, accurate, and checked by a script.

#### 0.13.58

 * No change to the plugin. Release-tooling only: the source shipped for review 
   can now rebuild itself.

#### 0.13.56

 * No change to the plugin. Release-tooling only: the bundle no longer writes a 
   record into the directory that record describes.

#### 0.13.55

 * No change to the plugin. Release-tooling only: the bundled dependency tree is
   verified on every build, not only when a record was already present.

#### 0.13.54

 * No change to the plugin. Release-tooling only: the bundled dependency tree is
   verified file by file against a recorded manifest before packaging.

#### 0.13.53

 * **Audit CSV export: a formula hidden behind leading whitespace is now neutralised
   too.** The check looked at the first byte, so a username beginning with a space,
   a tab, a non-breaking space or a byte-order mark before `=`, `+`, `-` or `@` 
   was written to the file unguarded — and a spreadsheet skips that whitespace before
   deciding whether a cell is a formula.
 * The readme now links Google’s terms and privacy policy for the optional reCAPTCHA
   integration, and names the endpoints it contacts.

#### 0.13.52

 * No change to the plugin. Release-tooling only: CI now requires every job in a
   run to have succeeded before a release is assembled.

#### 0.13.50

 * No change to the plugin. Release-tooling only: CI attests to the outcome of every
   job and the release tooling verifies it.

#### 0.13.49

 * No change to the plugin. Release-tooling and documentation corrections only.

#### 0.13.48

 * No change to the plugin. Release-tooling only: the end-to-end test procedure 
   and the recorded CI provenance were corrected.

#### 0.13.47

 * No change to the plugin. Release-tooling only: the bundled test procedure and
   the real-database test harness were corrected.

#### 0.13.46

 * **Packaging fix: the previous package contained development files that should
   never have shipped** — the test suite, build scripts, CI configuration and Composer
   manifests. They were harmless to run but had no business being in a plugin ZIP.
   This release contains runtime files only, and the build now checks the finished
   package for them.

For the change history of 0.13.45 and earlier releases, see changelog.txt.

## Meta

 *  Version **0.13.70**
 *  Last updated **8 hours ago**
 *  Active installations **Fewer than 10**
 *  WordPress version ** 6.0 or higher **
 *  Tested up to **7.0.4**
 *  PHP version ** 8.2 or higher **
 *  Languages
 * [English (US)](https://wordpress.org/plugins/rapls-passkey/) and [Japanese](https://ja.wordpress.org/plugins/rapls-passkey/).
 *  [Translate into your language](https://translate.wordpress.org/projects/wp-plugins/rapls-passkey)
 * Tags
 * [fido2](https://vec.wordpress.org/plugins/tags/fido2/)[login](https://vec.wordpress.org/plugins/tags/login/)
   [passkey](https://vec.wordpress.org/plugins/tags/passkey/)[passwordless](https://vec.wordpress.org/plugins/tags/passwordless/)
   [webauthn](https://vec.wordpress.org/plugins/tags/webauthn/)
 *  [Advanced View](https://vec.wordpress.org/plugins/rapls-passkey/advanced/)

## Ratings

No reviews have been submitted yet.

[Your review](https://wordpress.org/support/plugin/rapls-passkey/reviews/#new-post)

[See all reviews](https://wordpress.org/support/plugin/rapls-passkey/reviews/)

## Contributors

 *   [ rapls ](https://profiles.wordpress.org/rapls/)

## Support

Got something to say? Need help?

 [View support forum](https://wordpress.org/support/plugin/rapls-passkey/)