diff --git a/modules/jsonapi_security_tfa/jsonapi_security_tfa.module b/modules/jsonapi_security_tfa/jsonapi_security_tfa.module
index f15f669..ee248bd 100644
--- a/modules/jsonapi_security_tfa/jsonapi_security_tfa.module
+++ b/modules/jsonapi_security_tfa/jsonapi_security_tfa.module
@@ -5,6 +5,8 @@
  * Contains jsonapi_security_tfa.module.
  */
 
+use Drupal\Core\Hook\Attribute\LegacyHook;
+use Drupal\jsonapi_security_tfa\Hook\JsonapiSecurityTfaHooks;
 use Drupal\Core\Session\AccountInterface;
 
 /**
@@ -18,21 +20,7 @@ use Drupal\Core\Session\AccountInterface;
  *
  * The TfaEnforcementSubscriber checks this flag to authorize JSON:API requests.
  */
+#[LegacyHook]
 function jsonapi_security_tfa_user_login(AccountInterface $account): void {
-  // Check if the user has TFA enabled via user.data service.
-  // This follows the same pattern used internally by the TFA module.
-  /** @var \Drupal\user\UserDataInterface $user_data */
-  $user_data = \Drupal::service('user.data');
-  $tfa_data = $user_data->get('tfa', $account->id(), 'tfa_user_settings');
-
-  if (empty($tfa_data) || empty($tfa_data['status'])) {
-    // User has not enabled TFA. Do not set the completion flag.
-    // The TfaEnforcementSubscriber will block their JSON:API access.
-    return;
-  }
-
-  $request = \Drupal::request();
-  if ($request->hasSession()) {
-    $request->getSession()->set('tfa_enabled', TRUE);
-  }
+  \Drupal::service(JsonapiSecurityTfaHooks::class)->userLogin($account);
 }
diff --git a/modules/jsonapi_security_tfa/jsonapi_security_tfa.services.yml b/modules/jsonapi_security_tfa/jsonapi_security_tfa.services.yml
index d5587c2..6d9db23 100644
--- a/modules/jsonapi_security_tfa/jsonapi_security_tfa.services.yml
+++ b/modules/jsonapi_security_tfa/jsonapi_security_tfa.services.yml
@@ -9,3 +9,7 @@ services:
       - '@jsonapi_security.helper'
     tags:
       - { name: event_subscriber }
+
+  Drupal\jsonapi_security_tfa\Hook\JsonapiSecurityTfaHooks:
+    class: Drupal\jsonapi_security_tfa\Hook\JsonapiSecurityTfaHooks
+    autowire: true
diff --git a/modules/jsonapi_security_tfa/src/Hook/JsonapiSecurityTfaHooks.php b/modules/jsonapi_security_tfa/src/Hook/JsonapiSecurityTfaHooks.php
new file mode 100644
index 0000000..39911d5
--- /dev/null
+++ b/modules/jsonapi_security_tfa/src/Hook/JsonapiSecurityTfaHooks.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Drupal\jsonapi_security_tfa\Hook;
+
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Core\Hook\Attribute\Hook;
+
+/**
+ * Hook implementations for jsonapi_security_tfa.
+ */
+class JsonapiSecurityTfaHooks {
+
+  /**
+   * Implements hook_user_login().
+   *
+   * Sets the TFA completion flag for users who have TFA enabled.
+   * This hook is triggered by user_login_finalize(), which is called:
+   * - After successful TFA entry form submission
+   * - After trusted browser bypass
+   * - After grace period bypass.
+   *
+   * The TfaEnforcementSubscriber checks this flag to authorize JSON:API requests.
+   */
+  #[Hook('user_login')]
+  public static function userLogin(AccountInterface $account): void {
+    // Check if the user has TFA enabled via user.data service.
+    // This follows the same pattern used internally by the TFA module.
+    /** @var \Drupal\user\UserDataInterface $user_data */
+    $user_data = \Drupal::service('user.data');
+    $tfa_data = $user_data->get('tfa', $account->id(), 'tfa_user_settings');
+    if (empty($tfa_data) || empty($tfa_data['status'])) {
+      // User has not enabled TFA. Do not set the completion flag.
+      // The TfaEnforcementSubscriber will block their JSON:API access.
+      return;
+    }
+    $request = \Drupal::request();
+    if ($request->hasSession()) {
+      $request->getSession()->set('tfa_enabled', TRUE);
+    }
+  }
+
+}
diff --git a/modules/jsonapi_security_tfa/tests/src/Functional/TfaEnforcementTest.php b/modules/jsonapi_security_tfa/tests/src/Functional/TfaEnforcementTest.php
index 53b32eb..541bfb8 100644
--- a/modules/jsonapi_security_tfa/tests/src/Functional/TfaEnforcementTest.php
+++ b/modules/jsonapi_security_tfa/tests/src/Functional/TfaEnforcementTest.php
@@ -2,6 +2,8 @@
 
 namespace Drupal\Tests\jsonapi_security_tfa\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\jsonapi\Functional\JsonApiRequestTestTrait;
 use GuzzleHttp\Exception\ClientException;
@@ -12,6 +14,8 @@ use GuzzleHttp\RequestOptions;
  *
  * @group jsonapi_security
  */
+#[Group('jsonapi_security')]
+#[RunTestsInSeparateProcesses]
 class TfaEnforcementTest extends BrowserTestBase {
 
   use JsonApiRequestTestTrait;
diff --git a/tests/src/Functional/CollectionRestrictionFunctionalTest.php b/tests/src/Functional/CollectionRestrictionFunctionalTest.php
index 5ab589f..9182046 100644
--- a/tests/src/Functional/CollectionRestrictionFunctionalTest.php
+++ b/tests/src/Functional/CollectionRestrictionFunctionalTest.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\Tests\jsonapi\Functional\JsonApiRequestTestTrait;
 
@@ -12,6 +14,8 @@ use Drupal\Tests\jsonapi\Functional\JsonApiRequestTestTrait;
  *
  * @group jsonapi_security
  */
+#[Group('jsonapi_security')]
+#[RunTestsInSeparateProcesses]
 class CollectionRestrictionFunctionalTest extends BrowserTestBase {
 
   use JsonApiRequestTestTrait;
diff --git a/tests/src/Functional/Uid1LockdownFunctionalTest.php b/tests/src/Functional/Uid1LockdownFunctionalTest.php
index c24c5d2..292b0a7 100644
--- a/tests/src/Functional/Uid1LockdownFunctionalTest.php
+++ b/tests/src/Functional/Uid1LockdownFunctionalTest.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Functional;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\Tests\BrowserTestBase;
 use Drupal\user\Entity\User;
 use GuzzleHttp\RequestOptions;
@@ -13,6 +15,8 @@ use GuzzleHttp\RequestOptions;
  *
  * @group jsonapi_security
  */
+#[Group('jsonapi_security')]
+#[RunTestsInSeparateProcesses]
 class Uid1LockdownFunctionalTest extends BrowserTestBase {
 
   /**
diff --git a/tests/src/Kernel/ConfigurationTest.php b/tests/src/Kernel/ConfigurationTest.php
index aff9deb..6a7a89f 100644
--- a/tests/src/Kernel/ConfigurationTest.php
+++ b/tests/src/Kernel/ConfigurationTest.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
 use Drupal\KernelTests\KernelTestBase;
 
 /**
@@ -11,6 +13,8 @@ use Drupal\KernelTests\KernelTestBase;
  *
  * @group jsonapi_security
  */
+#[Group('jsonapi_security')]
+#[RunTestsInSeparateProcesses]
 class ConfigurationTest extends KernelTestBase {
 
   /**
diff --git a/tests/src/Kernel/DepthLimitingTest.php b/tests/src/Kernel/DepthLimitingTest.php
index 6f80bdf..a4407d0 100644
--- a/tests/src/Kernel/DepthLimitingTest.php
+++ b/tests/src/Kernel/DepthLimitingTest.php
@@ -4,6 +4,9 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use Drupal\Tests\user\Traits\UserCreationTrait;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\node\Entity\NodeType;
 use Symfony\Component\HttpFoundation\Request;
@@ -15,9 +18,11 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
  *
  * @group jsonapi_security
  */
+#[Group('jsonapi_security')]
+#[RunTestsInSeparateProcesses]
 class DepthLimitingTest extends KernelTestBase {
 
-  use \Drupal\Tests\user\Traits\UserCreationTrait;
+  use UserCreationTrait;
 
   /**
    * {@inheritdoc}
diff --git a/tests/src/Kernel/ReadOnlyModeTest.php b/tests/src/Kernel/ReadOnlyModeTest.php
index 8a0854e..b9f9eb5 100644
--- a/tests/src/Kernel/ReadOnlyModeTest.php
+++ b/tests/src/Kernel/ReadOnlyModeTest.php
@@ -4,6 +4,9 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Kernel;
 
+use PHPUnit\Framework\Attributes\Group;
+use PHPUnit\Framework\Attributes\RunTestsInSeparateProcesses;
+use Drupal\Tests\user\Traits\UserCreationTrait;
 use Drupal\KernelTests\KernelTestBase;
 use Drupal\node\Entity\Node;
 use Drupal\node\Entity\NodeType;
@@ -16,9 +19,11 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
  *
  * @group jsonapi_security
  */
+#[Group('jsonapi_security')]
+#[RunTestsInSeparateProcesses]
 class ReadOnlyModeTest extends KernelTestBase {
 
-  use \Drupal\Tests\user\Traits\UserCreationTrait;
+  use UserCreationTrait;
 
   /**
    * The test node.
diff --git a/tests/src/Unit/Event/JsonApiSecurityAnonymizeEventTest.php b/tests/src/Unit/Event/JsonApiSecurityAnonymizeEventTest.php
index a9f0066..19f056d 100644
--- a/tests/src/Unit/Event/JsonApiSecurityAnonymizeEventTest.php
+++ b/tests/src/Unit/Event/JsonApiSecurityAnonymizeEventTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Unit\Event;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\jsonapi_security\Event\JsonApiSecurityAnonymizeEvent;
 use Drupal\Tests\UnitTestCase;
 
@@ -13,6 +14,7 @@ use Drupal\Tests\UnitTestCase;
  * @group jsonapi_security
  * @coversDefaultClass \Drupal\jsonapi_security\Event\JsonApiSecurityAnonymizeEvent
  */
+#[Group('jsonapi_security')]
 class JsonApiSecurityAnonymizeEventTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/Event/JsonApiSecurityDepthCheckEventTest.php b/tests/src/Unit/Event/JsonApiSecurityDepthCheckEventTest.php
index d2490ef..649f35f 100644
--- a/tests/src/Unit/Event/JsonApiSecurityDepthCheckEventTest.php
+++ b/tests/src/Unit/Event/JsonApiSecurityDepthCheckEventTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Unit\Event;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\jsonapi_security\Event\JsonApiSecurityDepthCheckEvent;
 use Drupal\Tests\UnitTestCase;
 use Symfony\Component\HttpFoundation\Request;
@@ -14,6 +15,7 @@ use Symfony\Component\HttpFoundation\Request;
  * @group jsonapi_security
  * @coversDefaultClass \Drupal\jsonapi_security\Event\JsonApiSecurityDepthCheckEvent
  */
+#[Group('jsonapi_security')]
 class JsonApiSecurityDepthCheckEventTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/Event/JsonApiSecurityWriteCheckEventTest.php b/tests/src/Unit/Event/JsonApiSecurityWriteCheckEventTest.php
index 6a32b7e..68ab935 100644
--- a/tests/src/Unit/Event/JsonApiSecurityWriteCheckEventTest.php
+++ b/tests/src/Unit/Event/JsonApiSecurityWriteCheckEventTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Unit\Event;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\jsonapi_security\Event\JsonApiSecurityWriteCheckEvent;
 use Drupal\Tests\UnitTestCase;
 use Symfony\Component\HttpFoundation\Request;
@@ -14,6 +15,7 @@ use Symfony\Component\HttpFoundation\Request;
  * @group jsonapi_security
  * @coversDefaultClass \Drupal\jsonapi_security\Event\JsonApiSecurityWriteCheckEvent
  */
+#[Group('jsonapi_security')]
 class JsonApiSecurityWriteCheckEventTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/EventSubscriber/CacheTagsSubscriberTest.php b/tests/src/Unit/EventSubscriber/CacheTagsSubscriberTest.php
index 1d2e5d8..75e2bb5 100644
--- a/tests/src/Unit/EventSubscriber/CacheTagsSubscriberTest.php
+++ b/tests/src/Unit/EventSubscriber/CacheTagsSubscriberTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Unit\EventSubscriber;
 
+use PHPUnit\Framework\Attributes\Group;
 use Drupal\Core\Cache\CacheableMetadata;
 use Drupal\Core\Cache\CacheableResponse;
 use Drupal\jsonapi_security\EventSubscriber\CacheTagsSubscriber;
@@ -18,6 +19,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface;
  * @coversDefaultClass \Drupal\jsonapi_security\EventSubscriber\CacheTagsSubscriber
  * @group jsonapi_security
  */
+#[Group('jsonapi_security')]
 class CacheTagsSubscriberTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/EventSubscriber/DepthLimitSubscriberTest.php b/tests/src/Unit/EventSubscriber/DepthLimitSubscriberTest.php
index 375bf17..4fade78 100644
--- a/tests/src/Unit/EventSubscriber/DepthLimitSubscriberTest.php
+++ b/tests/src/Unit/EventSubscriber/DepthLimitSubscriberTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Unit\EventSubscriber;
 
+use PHPUnit\Framework\Attributes\Group;
 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Config\ImmutableConfig;
@@ -22,6 +23,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
  * @group jsonapi_security
  * @coversDefaultClass \Drupal\jsonapi_security\EventSubscriber\DepthLimitSubscriber
  */
+#[Group('jsonapi_security')]
 class DepthLimitSubscriberTest extends UnitTestCase {
 
   /**
diff --git a/tests/src/Unit/EventSubscriber/ReadOnlySubscriberTest.php b/tests/src/Unit/EventSubscriber/ReadOnlySubscriberTest.php
index b9a207e..96d0684 100644
--- a/tests/src/Unit/EventSubscriber/ReadOnlySubscriberTest.php
+++ b/tests/src/Unit/EventSubscriber/ReadOnlySubscriberTest.php
@@ -4,6 +4,7 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\jsonapi_security\Unit\EventSubscriber;
 
+use PHPUnit\Framework\Attributes\Group;
 use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Config\ImmutableConfig;
@@ -22,6 +23,7 @@ use Symfony\Component\HttpKernel\KernelEvents;
  * @group jsonapi_security
  * @coversDefaultClass \Drupal\jsonapi_security\EventSubscriber\ReadOnlySubscriber
  */
+#[Group('jsonapi_security')]
 class ReadOnlySubscriberTest extends UnitTestCase {
 
   /**
