diff --git a/config/sync/user.role.moderator.yml b/config/sync/user.role.moderator.yml
index 9454584b9a7cc831163448d346b9a2dc801bbbdc..e4360ebe0591995f1d6e6af9cdaf1a3c8847122f 100644
--- a/config/sync/user.role.moderator.yml
+++ b/config/sync/user.role.moderator.yml
@@ -115,8 +115,8 @@ permissions:
   - 'create paragraph content image'
   - 'create paragraph content json_map'
   - 'create paragraph content row'
-  - 'create paragraph content testimony'
   - 'create paragraph content simple_paragraph'
+  - 'create paragraph content testimony'
   - 'create paragraph content video'
   - 'create rdf entity news'
   - 'create solution_banner media'
@@ -147,6 +147,7 @@ permissions:
   - 'delete paragraph content testimony'
   - 'delete paragraph content video'
   - 'delete site alerts'
+  - 'disable site auto-registration'
   - 'download subscribers report'
   - 'edit any collection_banner media'
   - 'edit any collection_logo media'
diff --git a/tests/features/authentication.feature b/tests/features/authentication.feature
index b321823260e19fff2070d3c463c07d58ae8a58fc..bfed0128a8c4cfce5ed8d068682d792da273f143 100644
--- a/tests/features/authentication.feature
+++ b/tests/features/authentication.feature
@@ -43,6 +43,7 @@ Feature: User authentication
       | admin/structure/media                               |
       | announcements                                       |
       | dashboard                                           |
+      | dashboard/disable-registration                      |
       | licence                                             |
       | licence/add                                         |
       | media/add                                           |
@@ -125,6 +126,7 @@ Feature: User authentication
       | admin/structure/media                               |
       | announcements                                       |
       | dashboard                                           |
+      | dashboard/disable-registration                      |
       | licence                                             |
       | licence/add                                         |
       | media/add                                           |
@@ -185,8 +187,9 @@ Feature: User authentication
       | admin/reporting/solutions-by-type           |
       | admin/reporting/subscribers-report          |
       | admin/structure/compatibility-document      |
-      | announcements                                       |
+      | announcements                               |
       | dashboard                                   |
+      | dashboard/disable-registration              |
       | licence                                     |
       | licence/add                                 |
       | media/add                                   |
diff --git a/tests/features/eulogin/eulogin.feature b/tests/features/eulogin/eulogin.feature
index e7f30cc9a385bab3f63685b439390a90b4ca5d20..e1e35fb856e994d3f7558665b542ae9f19acacaf 100644
--- a/tests/features/eulogin/eulogin.feature
+++ b/tests/features/eulogin/eulogin.feature
@@ -132,9 +132,9 @@ Feature: Log in through EU Login
     And I should see the following lines of text:
       | Account information                                                                                                                                                                                                       |
       | Your name and E-mail are inherited from EU Login. To update this information, you can visit your EU Login account page. Synchronisation will take a few minutes and it will be visible the next time you login on Joinup. |
-      | Your e-mail address is not made public. We will only send you necessary system notifications and you can opt in later if you wish to receive additional notifications about content you are subscribed to.                         |
-      | Your first name is publicly visible.                                                                                                                                                                                               |
-      | Your last name is publicly visible.                                                                                                                                                                                                |
+      | Your e-mail address is not made public. We will only send you necessary system notifications and you can opt in later if you wish to receive additional notifications about content you are subscribed to.                |
+      | Your first name is publicly visible.                                                                                                                                                                                      |
+      | Your last name is publicly visible.                                                                                                                                                                                       |
 
     When I press "Save"
     Then I should see the success message "The changes have been saved."
@@ -295,7 +295,7 @@ Feature: Log in through EU Login
     Then I should see the success message "You have been logged in."
     # The email ends up getting the upstream email so that correct character casing is applied.
     And the user joe should have the following data in their user profile:
-      | E-mail      | Joe_Case_Insensitive@example.com |
+      | E-mail | Joe_Case_Insensitive@example.com |
 
   Scenario: Anonymous user is asked to log in when accessing a protected page
     Given users:
@@ -328,3 +328,42 @@ Feature: Log in through EU Login
     Given I am logged in as an "authenticated user"
     When I go to "/user/password"
     Then the response status code should be 404
+
+  Scenario: As a moderator I can temporary disable the site registration.
+    Given CAS users:
+      | Username | E-mail          | Password |
+      | joe_doe  | joe@example.com | 123      |
+    And users:
+      | Username | Roles     |
+      | mod      | moderator |
+
+    Given I am logged in as mod
+    And I visit "Dashboard"
+    When I click "Disable registration"
+    And I check "Disable new accounts registration"
+    And I press "Submit"
+    Then I should see the warning message "Registering new users to Joinup is disabled"
+
+    Given I am an anonymous user
+    And I am on the homepage
+    When I click "Sign in"
+    When I fill in "E-mail address" with "joe@example.com"
+    When I fill in "Password" with "123"
+    And I press "Log in"
+    Then I should see the error message "Registering new accounts to Joinup is temporary disabled. Please come back later."
+    # Check that the user is not logged in.
+    And I should see the link "Sign in"
+
+    Given I am logged in as mod
+    And I visit "/dashboard/disable-registration"
+    And I uncheck "Disable new accounts registration"
+    And I press "Submit"
+    Then I should see the success message "Registering new users to Joinup is enabled"
+
+    Given I am an anonymous user
+    And I am on the homepage
+    When I click "Sign in"
+    When I fill in "E-mail address" with "joe@example.com"
+    When I fill in "Password" with "123"
+    And I press "Log in"
+    Then I should see the success message "Fill in the fields below to let the Joinup community learn more about you!"
diff --git a/web/modules/custom/dashboard/dashboard.permissions.yml b/web/modules/custom/dashboard/dashboard.permissions.yml
index 42e88eb3d649016df930558b16d43558cf6959d8..0415dc08d6e86962e503c0353c1fd0d8c2942614 100644
--- a/web/modules/custom/dashboard/dashboard.permissions.yml
+++ b/web/modules/custom/dashboard/dashboard.permissions.yml
@@ -1,2 +1,4 @@
 access dashboard:
   title: 'Access the dashboard'
+disable site auto-registration:
+  title: 'Disable site auto-registration'
diff --git a/web/modules/custom/dashboard/dashboard.routing.yml b/web/modules/custom/dashboard/dashboard.routing.yml
index 00f2bf7b19ef3a5036911ba63e2a386fa7cb33a5..e0e4ac283d34acac69c3e2e90a1675d63ab2424d 100644
--- a/web/modules/custom/dashboard/dashboard.routing.yml
+++ b/web/modules/custom/dashboard/dashboard.routing.yml
@@ -5,3 +5,11 @@ dashboard.page:
     _title: 'Dashboard'
   requirements:
     _permission: 'access dashboard'
+
+dashboard.disable_registration:
+  path: '/dashboard/disable-registration'
+  defaults:
+    _form: Drupal\dashboard\Form\DisableRegistrationForm
+    _title: Disable site registration
+  requirements:
+    _permission: 'disable site auto-registration'
diff --git a/web/modules/custom/dashboard/src/Controller/DashboardController.php b/web/modules/custom/dashboard/src/Controller/DashboardController.php
index 14f78cd9c572f5bda50e3a1637a70656d754635f..1e787b0230d50622c8cb7dab12dbdd46a3ac4fa9 100644
--- a/web/modules/custom/dashboard/src/Controller/DashboardController.php
+++ b/web/modules/custom/dashboard/src/Controller/DashboardController.php
@@ -56,6 +56,10 @@ public function page() {
         'title' => $this->t('Curated content listings'),
         'url' => Url::fromRoute('view.curated_content_listings.page'),
       ],
+      'disable_registration' => [
+        'title' => $this->t('Disable registration'),
+        'url' => Url::fromRoute('dashboard.disable_registration'),
+      ],
     ];
 
     $links = array_map(function (array $link): array {
diff --git a/web/modules/custom/dashboard/src/Form/DisableRegistrationForm.php b/web/modules/custom/dashboard/src/Form/DisableRegistrationForm.php
new file mode 100644
index 0000000000000000000000000000000000000000..e47b1b90276ee2bcf3d3c8ab317512cf49229ff5
--- /dev/null
+++ b/web/modules/custom/dashboard/src/Form/DisableRegistrationForm.php
@@ -0,0 +1,72 @@
+<?php
+
+declare(strict_types = 1);
+
+namespace Drupal\dashboard\Form;
+
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\State\StateInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Allows disabling the site CAS registration.
+ */
+class DisableRegistrationForm extends FormBase {
+
+  /**
+   * Constructs a new form instance.
+   *
+   * @param \Drupal\Core\State\StateInterface $state
+   *   The state service.
+   */
+  public function __construct(protected StateInterface $state) {
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container): self {
+    return new static($container->get('state'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, FormStateInterface $form_state): array {
+    $form['disabled'] = [
+      '#type' => 'checkbox',
+      '#title' => $this->t('Disable new accounts registration'),
+      '#default_value' => $this->state->get('joinup_eulogin.registration_disabled', FALSE),
+    ];
+    $form['actions'] = [
+      '#type' => 'actions',
+      'submit' => [
+        '#type' => 'submit',
+        '#value' => $this->t('Submit'),
+      ],
+    ];
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, FormStateInterface $form_state): void {
+    if ($form_state->getValue('disabled')) {
+      $this->state->set('joinup_eulogin.registration_disabled', TRUE);
+      $this->messenger()->addWarning($this->t('Registering new users to Joinup is disabled'));
+      return;
+    }
+    $this->state->delete('joinup_eulogin.registration_disabled');
+    $this->messenger()->addStatus($this->t('Registering new users to Joinup is enabled'));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormId(): string {
+    return 'dashboard_disable_registration';
+  }
+
+}
diff --git a/web/modules/custom/joinup_eulogin/joinup_eulogin.services.yml b/web/modules/custom/joinup_eulogin/joinup_eulogin.services.yml
index c875cf04cfca39839c428439025e211326912766..a8bd6aa2c5f3cd21485a09d8ab0a53ae180d5f8b 100644
--- a/web/modules/custom/joinup_eulogin/joinup_eulogin.services.yml
+++ b/web/modules/custom/joinup_eulogin/joinup_eulogin.services.yml
@@ -1,7 +1,7 @@
 services:
   joinup_eulogin.cas.subscriber:
     class: Drupal\joinup_eulogin\Event\Subscriber\JoinupEuLoginCasEventsSubscriber
-    arguments: ['@config.factory', '@user.data', '@entity_type.manager', '@request_stack', '@messenger']
+    arguments: ['@config.factory', '@user.data', '@entity_type.manager', '@request_stack', '@messenger', '@state']
     tags:
       - { name: 'event_subscriber' }
   joinup_eulogin.route.subscriber:
diff --git a/web/modules/custom/joinup_eulogin/src/Event/Subscriber/JoinupEuLoginCasEventsSubscriber.php b/web/modules/custom/joinup_eulogin/src/Event/Subscriber/JoinupEuLoginCasEventsSubscriber.php
index 49e594867c7c0ef1b82581edd1d3e780b0c2cec2..165dac01c2e72c8ca2a172a923d90fe97241f0f8 100644
--- a/web/modules/custom/joinup_eulogin/src/Event/Subscriber/JoinupEuLoginCasEventsSubscriber.php
+++ b/web/modules/custom/joinup_eulogin/src/Event/Subscriber/JoinupEuLoginCasEventsSubscriber.php
@@ -9,6 +9,7 @@
 use Drupal\Core\Config\ImmutableConfig;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Messenger\MessengerInterface;
+use Drupal\Core\State\StateInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Url;
 use Drupal\cas\Event\CasPostLoginEvent;
@@ -40,47 +41,38 @@ class JoinupEuLoginCasEventsSubscriber implements EventSubscriberInterface {
    */
   protected ImmutableConfig $casSettings;
 
-  /**
-   * The user data service.
-   */
-  protected UserDataInterface $userData;
-
-  /**
-   * The entity type manager service.
-   */
-  protected EntityTypeManagerInterface $entityTypeManager;
-
   /**
    * The current request.
    */
   protected Request $currentRequest;
 
-  /**
-   * The messenger service.
-   */
-  protected MessengerInterface $messenger;
-
   /**
    * Constructs a new event subscriber instance.
    *
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
    *   The config factory service.
-   * @param \Drupal\user\UserDataInterface $user_data
+   * @param \Drupal\user\UserDataInterface $userData
    *   The user data service.
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
    *   The entity type manager service.
-   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+   * @param \Symfony\Component\HttpFoundation\RequestStack $requestStack
    *   The request stack.
    * @param \Drupal\Core\Messenger\MessengerInterface $messenger
    *   The messenger service.
+   * @param \Drupal\Core\State\StateInterface $state
+   *   The state service.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, UserDataInterface $user_data, EntityTypeManagerInterface $entity_type_manager, RequestStack $request_stack, MessengerInterface $messenger) {
-    $this->settings = $config_factory->get('joinup_eulogin.settings');
-    $this->casSettings = $config_factory->get('cas.settings');
-    $this->userData = $user_data;
-    $this->entityTypeManager = $entity_type_manager;
-    $this->currentRequest = $request_stack->getCurrentRequest();
-    $this->messenger = $messenger;
+  public function __construct(
+    ConfigFactoryInterface $configFactory,
+    protected UserDataInterface $userData,
+    protected EntityTypeManagerInterface $entityTypeManager,
+    RequestStack $requestStack,
+    protected MessengerInterface $messenger,
+    protected StateInterface $state,
+  ) {
+    $this->settings = $configFactory->get('joinup_eulogin.settings');
+    $this->casSettings = $configFactory->get('cas.settings');
+    $this->currentRequest = $requestStack->getCurrentRequest();
   }
 
   /**
@@ -91,6 +83,7 @@ public static function getSubscribedEvents(): array {
       CasHelper::EVENT_PRE_VALIDATE => 'alterValidationUrl',
       CasHelper::EVENT_POST_VALIDATE => 'prepareAttributes',
       CasHelper::EVENT_PRE_REGISTER => [
+        ['disableRegistration', 1000],
         ['markAsNewAccountRegistration'],
         ['handleDrupalUsernameCollision'],
         ['preventRegisterEmailCollision'],
@@ -141,6 +134,20 @@ public function prepareAttributes(CasPostValidateEvent $event): void {
     };
   }
 
+  /**
+   * Disables the CAS automatic registration based on a kill-switch.
+   *
+   * @param \Drupal\cas\Event\CasPreRegisterEvent $event
+   *   The CAS pre-register event.
+   */
+  public function disableRegistration(CasPreRegisterEvent $event): void {
+    if ($this->state->get('joinup_eulogin.registration_disabled', FALSE)) {
+      $event
+        ->cancelAutomaticRegistration($this->t('Registering new accounts to Joinup is temporary disabled. Please come back later.'))
+        ->stopPropagation();
+    }
+  }
+
   /**
    * Marks this login as being preceded by account registration.
    *
@@ -166,12 +173,12 @@ public function handleDrupalUsernameCollision(CasPreRegisterEvent $event): void
       return;
     }
 
-    $new_name = $name = $event->getDrupalUsername();
-    while (user_load_by_name($new_name)) {
-      $new_name = $this->buildUserName($name);
+    $newName = $name = $event->getDrupalUsername();
+    while (user_load_by_name($newName)) {
+      $newName = $this->buildUserName($name);
     }
 
-    $event->setDrupalUsername($new_name);
+    $event->setDrupalUsername($newName);
   }
 
   /**
@@ -191,15 +198,15 @@ public function preventRegisterEmailCollision(CasPreRegisterEvent $event): void
       throw new \InvalidArgumentException("Unexpected empty 'mail' property value.");
     }
 
-    $same_mail_accounts = $this->entityTypeManager->getStorage('user')->loadByProperties([
+    $sameMailAccounts = $this->entityTypeManager->getStorage('user')->loadByProperties([
       'mail' => $mail,
     ]);
 
-    if ($same_mail_accounts) {
+    if ($sameMailAccounts) {
       $event->cancelAutomaticRegistration($this->t('While trying to register your account with Joinup, we found that your EU Login email address %mail is already in use on our site. Either change your EU Login email address or contact the <a href=":contact">Joinup support</a> if you feel that something is wrong.', [
         '%mail' => $mail,
         ':contact' => Url::fromRoute('contact_form.contact_page')->toString(),
-      ]));
+      ]))->stopPropagation();
     }
   }
 
@@ -223,15 +230,15 @@ public function preventRegisterEmailCollision(CasPreRegisterEvent $event): void
    */
   public function handlePotentialMailCollision(CasPreLoginEvent $event): void {
     $account = $event->getAccount();
-    $eulogin_email = $event->getCasPropertyBag()->getAttribute('email');
+    $euloginEmail = $event->getCasPropertyBag()->getAttribute('email');
 
     // A new email has been configured upstream, on the EU Login account. If the
     // account was linked manually, there is a chance that the email stored
     // locally does not share the same case sensitivity as the upstream account.
     // In these cases, allow to proceed so that the local account can retrieve
     // the correct case sensitivity email.
-    if (strtolower($account->getEmail()) !== strtolower($eulogin_email)) {
-      if (user_load_by_mail($eulogin_email)) {
+    if (strtolower($account->getEmail()) !== strtolower($euloginEmail)) {
+      if (user_load_by_mail($euloginEmail)) {
         $event->cancelLogin($this->t("You've recently changed your EU Login account email but that email is already used in Joinup by another user. You cannot login until, either you change your EU Login email or you <a href=':url'>contact support</a> to fix the issue.", [
           ':url' => Url::fromRoute('contact_form.contact_page')->setAbsolute()->toString(),
         ]));