diff --git a/class-wporg-webauthn-provider.php b/class-wporg-webauthn-provider.php
new file mode 100644
index 00000000..d279321b
--- /dev/null
+++ b/class-wporg-webauthn-provider.php
@@ -0,0 +1,131 @@
+_add_filters();
+ }
+
+ return $instance;
+ }
+
+ /**
+ * Check if the provider is available for the given user.
+ *
+ * This method includes caching for WordPress.org, as it's called on most pageloads.
+ */
+ public function is_available_for_user( $user ) {
+ $is_available = wp_cache_get( 'webauthn:' . $user->ID, 'users', false, $found );
+ if ( $found ) {
+ return $is_available;
+ }
+
+ $is_available = parent::is_available_for_user( $user );
+
+ wp_cache_set( 'webauthn:' . $user->ID, $is_available, 'users', HOUR_IN_SECONDS );
+
+ return $is_available;
+ }
+
+ /**
+ * See https://github.com/sjinks/wp-two-factor-provider-webauthn/pull/468
+ *
+ * @return string
+ */
+ public function get_alternative_provider_label() {
+ return __( 'Use your security key', 'wporg-two-factor' );
+ }
+
+ /**
+ * Add some filters to watch for WebAuthn events.
+ */
+ public function _add_filters() {
+ // Clear the cache when a user is updated.
+ add_action( 'wp_ajax_webauthn_preregister', [ $this, '_webauthn_ajax_request' ], 1 );
+ add_action( 'wp_ajax_webauthn_register', [ $this, '_webauthn_ajax_request' ], 1 );
+ add_action( 'wp_ajax_webauthn_delete_key', [ $this, '_webauthn_ajax_request' ], 1 );
+ add_action( 'wp_ajax_webauthn_rename_key', [ $this, '_webauthn_ajax_request' ], 1 );
+
+ // Disable the admin UI if it needs revalidation.
+ add_action( 'show_user_security_settings', [ $this, '_show_user_security_settings' ], -1 );
+
+ // Extend the session revalidation after registering a new key.
+ add_action( 'wp_ajax_webauthn_register', [ $this, '_extend_revalidation' ], 1 );
+ }
+
+ /**
+ * Force the user to revalidate their 2FA if they're updating their WebAuthn keys.
+ *
+ * This is pending an upstream PR for the revalidation.
+ */
+ public function _webauthn_ajax_request() {
+ // Check the users session is still active and 2FA revalidation isn't required.
+ if ( ! Two_Factor_Core::current_user_can_update_two_factor_options() ) {
+ wp_send_json_error( 'Your session has expired. Please refresh the page and try again.' );
+ }
+
+ // Clear the caches for this class after the request is finished.
+ add_action( 'shutdown', [ $this, '_clear_cache' ] );
+ }
+
+ /**
+ * Wrap the additional providers in a disabled fieldset if the user needs to revalidate.
+ *
+ * This is pending an upstream PR.
+ */
+ public function _show_user_security_settings() {
+ $show_2fa_options = Two_Factor_Core::current_user_can_update_two_factor_options();
+ if ( ! $show_2fa_options ) {
+ // TODO: Perhaps the Core UI should extend it's `