diff --git a/.ddev/commands/host/install b/.ddev/commands/host/install
index a7bc84c896ca7f938ced2bb767048476e8844eef..745623f7ba4b876f523e7f8f5e7e72ba1125d015 100755
--- a/.ddev/commands/host/install
+++ b/.ddev/commands/host/install
@@ -6,6 +6,6 @@
 
 ddev solr:empty
 ddev exec vendor/bin/run toolkit:install-clean
-ddev exec scripts/switch config-readonly off
+ddev exec vendor/bin/run config-readonly:disable
 ddev exec vendor/bin/run dev:install-modules
-ddev exec scripts/switch config-readonly on
+ddev exec vendor/bin/run config-readonly:enable
diff --git a/.ddev/commands/host/rebuild b/.ddev/commands/host/rebuild
index c8a8a9abe16eb8b546bade0a7decd8db077903ed..95cd7825de61c10aed01aae89460035fb7df882d 100755
--- a/.ddev/commands/host/rebuild
+++ b/.ddev/commands/host/rebuild
@@ -7,7 +7,7 @@
 ddev solr:restore
 ddev virtuoso:restore
 ddev run toolkit:install-clone
-ddev exec scripts/switch config-readonly off
+ddev run config-readonly:disable
 ddev run dev:install-modules
 ddev drush user:unblock --uid=1
-ddev exec scripts/switch config-readonly on
+ddev run config-readonly:enable
diff --git a/.env.example b/.env.example
index b93332a7adc0dc6f722756fc7b4fe3d61fa02804..ad74c13ac9bc234b478858845b85b5b00654c8a4 100644
--- a/.env.example
+++ b/.env.example
@@ -18,7 +18,3 @@ NEXTCLOUD_PASS=
 # The GitHub token. Generate a personal access token if you want to be able to
 # use the GitHub feed paragraph.
 JOINUP_GITHUB_TOKEN=
-
-# Set this variable "false" in your .env file to permanently disable the config
-# read-only feature on your development environment.
-CONFIG_READONLY=
diff --git a/.gitignore b/.gitignore
index f5e9d58a8791a1f7513057ef460f91418e7f043c..a38f1aa36ef91835eb96710586cb3d8db167f7b8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -43,6 +43,8 @@
 /.vscode/
 /.devcontainer/
 
+# Ignore the config_readonly killswitch.
+/disable-config-readonly
 # Ignore the cookie consent killswitch.
 /disable-cookie-consent
 
diff --git a/.opts.yml b/.opts.yml
index fd5159c78c30d8080cb6218aab7eeefb0b381f9e..6ba43c612e139f80de47548c1c556d1ee3f45888 100644
--- a/.opts.yml
+++ b/.opts.yml
@@ -5,36 +5,31 @@
 # See \EcEuropa\Toolkit\TaskRunner\Commands\CloneCommands::runDeploy().
 upgrade_commands:
   default:
-    - scripts/switch config-readonly off
-    - ./vendor/bin/drush deploy --yes
-    - ./vendor/bin/drush search-api:reset-tracker --yes
-    - ./vendor/bin/drush joinup:node-access-rebuild
-    - ./vendor/bin/drush joinup:search-api-tasks
-    - ./vendor/bin/drush twigc --yes
-    - scripts/switch config-readonly on
-    - ./vendor/bin/drush joinup:unpublish-alert --category
-    - ./scripts/check_status_report.php
-    - test ! -f vendor/bin/run || vendor/bin/run eu-oss-catalogue:enable
+    - touch disable-config-readonly
+    - vendor/bin/drush deploy --yes
+    - vendor/bin/drush search-api:reset-tracker --yes
+    - vendor/bin/drush joinup:node-access-rebuild
+    - vendor/bin/drush joinup:search-api-tasks
+    - vendor/bin/drush twigc --yes
+    - rm disable-config-readonly
+    - vendor/bin/drush joinup:unpublish-alert --category
+    - scripts/check_status_report.php
   append:
     production:
-      - scripts/switch eu-oss-catalogue off
+      # TODO: Remove this command in ISAICP-9053.
+      - vendor/bin/drush state:set joinup.oss_catalogue_is_disabled 1 --input-format=boolean
     acceptance:
-      - scripts/switch config-readonly off
-      - ./vendor/bin/drush joinup:acc
-      - ./vendor/bin/drush cache:rebuild
-      - scripts/switch config-readonly on
-      # Remove this line when deploying to POC.
-      - scripts/switch eu-oss-catalogue off
-      - ./vendor/bin/drush eu-oss:fetch developers_italia
-      - ./vendor/bin/drush eu-oss:fetch hosting_platform:open_code
-      - ./vendor/bin/drush queue:run eu_oss_catalogue
-      - ./vendor/bin/drush queue:run joinup_oss_catalogue_imagecache_warmer
+      - touch disable-config-readonly
+      - vendor/bin/drush joinup:acc
+      - vendor/bin/drush cache:rebuild
+      - rm disable-config-readonly
+      # TODO: Remove this command in ISAICP-9053.
+      - vendor/bin/drush state:set joinup.oss_catalogue_is_disabled 1 --input-format=boolean
     ephemeral:
-      - scripts/switch config-readonly off
-      - ./vendor/bin/drush joinup:acc
-      - ./vendor/bin/drush cache:rebuild
-      - scripts/switch config-readonly on
-
+      - touch disable-config-readonly
+      - vendor/bin/drush joinup:acc
+      - vendor/bin/drush cache:rebuild
+      - rm disable-config-readonly
 php_version: 8.3
 extra_pkgs:
   - php8.3-apcu
diff --git a/README.md b/README.md
index b18a479c202bd870b99cdf1735ded77d22428432..812a443623d8c2a02c8b0b966a932179fd5d1c80 100644
--- a/README.md
+++ b/README.md
@@ -82,7 +82,7 @@ ddev composer install
 
 This will install the PHP and Node dependencies. The codebase is deployed.
 
-### Configure secrets and local settings
+### Configure sensitive data (secrets)
 
 * Copy the `.env.example` file as `.env`. The `.env` file is not under VCS
   control and is used to override values stored into `.env.dist` file but, more
@@ -90,12 +90,6 @@ This will install the PHP and Node dependencies. The codebase is deployed.
   passwords, etc.
 * You should fill the `.env` file environment variables with values. Each
   variable is documented in `.env.example`.
-* On production, the site uses the `config_readonly` module to prevent config
-  changes. This is a safety measure. You can turn this protection on/off by
-  running `ddev exec scripts/switch config-readonly [operation]`, where
-  `[operation]` is `enable` or `disable`. However, when developing locally, this
-  could become annoying. To completely turn off the protection locally, just add
-  `CONFIG_READONLY=false` in your `.env` file.
 
 ### Install Joinup
 
@@ -241,7 +235,16 @@ Note that Toolkit uses its own configuration. Few aspects:
 * Apart from configuration provided by Toolkit, Joinup exposes its own
   configuration under `resources/runner`.
 * You can override any configuration by creating a `runner.yml` file in the
-  project's root directory. Note that this file is not under VCS control.
+  project's root directory. Note that this file is not under VCS control. For
+  instance, you may want to disable the "config read-only" feature while you
+  work on the project. All you need to do is to add this line in `runner.yml`:
+  ```yaml
+  config_readonly: false
+  ```
+* You can inspect the configuration. Find out how by running this command:
+  ```yaml
+  ddev run config --help
+  ```
 
 #### Developer local commands
 
diff --git a/resources/runner/config_readonly.yml b/resources/runner/config_readonly.yml
new file mode 100644
index 0000000000000000000000000000000000000000..da4e29a358b0ee1ab3592bb5555266d948f49811
--- /dev/null
+++ b/resources/runner/config_readonly.yml
@@ -0,0 +1,16 @@
+# Config readonly settings and commands.
+
+# Set this config to `false` in your runner.yml to permanently disable the
+# config read-only feature on your development environment.
+config_readonly: true
+
+commands:
+
+  # Config readonly kill-switch.
+  config-readonly:enable:
+    - task: exec
+      command: (test "${config_readonly}" = "1" && rm -f ${joinup.dir}/disable-config-readonly) || true
+
+  config-readonly:disable:
+    - task: touch
+      file: ${joinup.dir}/disable-config-readonly
diff --git a/resources/runner/dev.yml b/resources/runner/dev.yml
index dad18a4fd6be676014211477086f8b3ebc682fb9..1639e5ba024962993099f139eda4ed4426332a2f 100644
--- a/resources/runner/dev.yml
+++ b/resources/runner/dev.yml
@@ -32,17 +32,17 @@ commands:
       command: solr:download-snapshot
 
   dev:install-modules:
-    - task: exec
-      command: ${joinup.dir}/scripts/switch config-readonly off
+    - task: run
+      command: config-readonly:disable
     - task: run
       command: drush:module-install
       arguments: ${dev.modules}
-    - task: exec
-      command: ${joinup.dir}/scripts/switch config-readonly on
+    - task: run
+      command: config-readonly:enable
 
   dev:demo-users:
-    - task: exec
-      command: ${joinup.dir}/scripts/switch config-readonly off
+    - task: run
+      command: config-readonly:disable
     # Make sure CAS mock server module is installed.
     - task: run
       command: drush:module-install
@@ -194,8 +194,8 @@ commands:
       options:
         yes: null
         root: ${joinup.site_dir}
-    - task: exec
-      command: ${joinup.dir}/scripts/switch config-readonly on
+    - task: run
+      command: config-readonly:enable
 
   dev:import-sparql-fixtures:
     - task: run
diff --git a/resources/runner/drupal.yml b/resources/runner/drupal.yml
index 7a4a0c6473628053b3f3bd18355847dc28c74f31..883e0cc29c5528d850d2f9e8accab610dbca158e 100644
--- a/resources/runner/drupal.yml
+++ b/resources/runner/drupal.yml
@@ -245,7 +245,7 @@ drupal:
         ];
         // Location of the site configuration files.
         $settings['config_sync_directory'] = '../config/sync';
-        $settings['config_readonly'] = getenv('CONFIG_READONLY') !== 'false' && !file_exists(getenv('DRUPAL_PRIVATE_FILE_SYSTEM') . '/killswitch/disable-config-readonly');
+        $settings['config_readonly'] = !file_exists(getcwd() . '/../disable-config-readonly');
       Testing configuration alters: |
         // The video from the home page interacts with Selenium tests.
         $config['page_manager.page_variant.homepage-layout_builder-0']['variant_settings']['sections'][4]['components']['6ab0ceea-4541-4153-8b64-227e02369d30']['configuration']['text'] = 'Some joinup video';
@@ -380,7 +380,6 @@ drupal:
         $settings['reverse_proxy'] = (bool) getenv('DRUPAL_REVERSE_PROXY_ENABLE');
         $settings['reverse_proxy_addresses'] = array_filter(explode(',', (string) getenv('DRUPAL_REVERSE_PROXY_ADDRESSES')));
       EU OSS Catalogue: |
-        $settings['eu_oss_catalogue']['enabled'] = !file_exists(getenv('DRUPAL_PRIVATE_FILE_SYSTEM') . '/killswitch/disable-eu-oss-catalogue');
         $settings['eu_oss_catalogue']['platform_github']['access_token'] = getenv('JOINUP_GITHUB_TOKEN');
       Stage file proxy: |
         $config['stage_file_proxy.settings']['hotlink'] = TRUE;
diff --git a/resources/runner/joinup.yml b/resources/runner/joinup.yml
index 7e8ff875d91f9af126692465d2ac1810fc2c7779..5d5c08ab6adb93b55dc81e9ee190334c7e5b00c1 100644
--- a/resources/runner/joinup.yml
+++ b/resources/runner/joinup.yml
@@ -6,11 +6,3 @@ joinup:
   files_private_dir: ${joinup.site_dir}/${env.DRUPAL_PRIVATE_FILE_SYSTEM}
   files_temp_dir: ${joinup.site_dir}/${env.DRUPAL_FILE_TEMP_PATH}
   ddev_dir: ${joinup.dir}/.ddev
-
-
-commands:
-  # Drop when EU OSS Catalogue is enabled in production, in ISAICP-9053.
-  eu-oss-catalogue:enable:
-    - task: exec
-      command: ${drush.bin} eval 'if (joinup_oss_catalogue_is_enabled()) \Drupal::entityTypeManager()->getStorage("rdf_entity")->load("http://data.europa.eu/w21/6d621a47-71ce-4f1a-90e2-8859403d3ecd")->set("field_ar_state", "published")->save();'
-
diff --git a/resources/runner/toolkit.yml b/resources/runner/toolkit.yml
index 8c7864ede22b6fa4e8dd5f5cc2bbdb05335324a0..fb5b5164dbec4a573f8c2e3e0cdc1837002e9293 100644
--- a/resources/runner/toolkit.yml
+++ b/resources/runner/toolkit.yml
@@ -52,8 +52,8 @@ toolkit:
               - install
         after:
           # The `toolkit:run-deploy` command has enabled config read-only.
-          - task: exec
-            command: ${joinup.dir}/scripts/switch config-readonly off
+          - task: run
+            command: config-readonly:disable
           - task: run
             command: testing:install-modules
           - task: exec
@@ -72,8 +72,8 @@ toolkit:
             command: drupal:settings
             arguments:
               - site-clone
-          - task: exec
-            command: ${joinup.dir}/scripts/switch config-readonly on
+          - task: run
+            command: config-readonly:enable
           - task: exec
             command: test ! -z "$CI" || vendor/bin/run solr:build-core-config
 
@@ -113,8 +113,8 @@ commands:
       command: drupal:settings
       arguments:
         - install
-    - task: exec
-      command: ${joinup.dir}/scripts/switch config-readonly off
+    - task: run
+      command: config-readonly:disable
     - task: run
       command: drupal:site-install
       options:
@@ -146,8 +146,8 @@ commands:
       arguments:
         - php:eval
         - if (node_access_needs_rebuild()) { node_access_rebuild(); }
-    - task: exec
-      command: ${joinup.dir}/scripts/switch config-readonly on
+    - task: run
+      command: config-readonly:enable
     - task: exec
       command: test ! -z "$CI" || vendor/bin/run solr:build-core-config
 
diff --git a/scripts/switch b/scripts/switch
deleted file mode 100755
index 7aeefc2edf3060f467b28312063a46a8b65de636..0000000000000000000000000000000000000000
--- a/scripts/switch
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env php
-<?php
-
-use Symfony\Component\Filesystem\Filesystem;
-
-include_once __DIR__ . '/../vendor/autoload.php';
-
-// Logs messages
-$log = function (string $type, string $message): void {
-  $message = trim($message);
-  print match($type) {
-    'info' => "\033[36m$message\033[0m",
-    'warning' => "\033[33m$message\033[0m",
-    'error' => "\033[31m$message\033[0m",
-  };
-  print "\n";
-  if ($type === 'error') {
-    exit(1);
-  }
-};
-
-[, $switch, $operation] = $argv;
-
-// Check command arguments.
-$errors = [];
-if (!in_array($switch, ['config-readonly', 'eu-oss-catalogue'])) {
-  $errors[] = "First argument should be 'config-readonly' or 'eu-oss-catalogue' but '$switch' given";
-}
-if (!in_array($operation, ['on', 'off'])) {
-  $errors[] = "Second argument should be 'on' or 'off' but '$operation' given";
-}
-if (($count = count($argv) -1 ) > 2) {
-  $errors[] = "This command only accepts 2 arguments but $count given";
-}
-if ($errors) {
-  $log('error', implode("\n", $errors));
-}
-
-$fileSystem = new Filesystem();
-$path = getenv('DRUPAL_PRIVATE_FILE_SYSTEM');
-
-if (empty($path)) {
-  $log('error', 'The DRUPAL_PRIVATE_FILE_SYSTEM environment variable is not set');
-}
-
-// Drupal expects the private filesystem path as relative to web root but in
-// CI/CD it might be set as absolute. Convert to absolute path.
-if (!$fileSystem->isAbsolutePath($path)) {
-  $dir = DRUPAL_ROOT . '/' . $path;
-  $path = realpath($dir);
-  if ($path === FALSE) {
-    $log('error', "The directory $dir doesn't exist");
-  }
-}
-
-$path .= '/killswitch';
-
-if (!$fileSystem->exists($path)) {
-  // Create the directory if it's missing.
-  $fileSystem->mkdir($path);
-  $fileSystem->chmod($path, 0770);
-}
-
-// File used as kill-switch.
-$killSwitch = "$path/disable-$switch";
-
-if ($operation === 'on') {
-  if ($fileSystem->exists($killSwitch)) {
-    $fileSystem->remove($killSwitch);
-  }
-
-  if ($switch === 'config-readonly' && getenv('CONFIG_READONLY') === 'false') {
-    $log('warning', "Config read-only is permanently disabled because the CONFIG_READONLY environment\nvariable is set to 'false'");
-  }
-  else {
-    $log('info', "The $switch functionality has been enabled");
-  }
-}
-elseif ($operation === 'off') {
-  $fileSystem->touch($killSwitch);
-  $log('info', "The $switch functionality has been disabled");
-}
diff --git a/tests/features/communities/oss_catalogue/killswitch.feature b/tests/features/communities/oss_catalogue/oss_catalogue_visibility.feature
similarity index 57%
rename from tests/features/communities/oss_catalogue/killswitch.feature
rename to tests/features/communities/oss_catalogue/oss_catalogue_visibility.feature
index a77ba248f2d5cef1154291507e167d6f533eed80..de3d282ba23f562d8d49a2cd4299d86c63b7bd6f 100644
--- a/tests/features/communities/oss_catalogue/killswitch.feature
+++ b/tests/features/communities/oss_catalogue/oss_catalogue_visibility.feature
@@ -1,12 +1,21 @@
+# TODO: Remove this test in ISAICP-9053
 @api @group-clone
 Feature: Test EU OSS Catalogue killswitch
 
   Scenario: Switch ON/OFF
+    Given oss_solution content:
+      | title                  | oss_development_status | oss_source        | oss_categories     | oss_short_description | status    |
+      | The Opensource Panacea | development            | developers_italia | content-management | The cure              | published |
 
     When I go to "/eu-oss-catalogue"
     Then the response status code should be 200
+    But I should not see "Sign in to continue"
     And I go to "/eu-oss-catalogue/solutions"
     Then the response status code should be 200
+    But I should not see "Sign in to continue"
+    And I go to the content page of the type "oss_solution" with the title "The Opensource Panacea"
+    Then the response status code should be 200
+    But I should not see "Sign in to continue"
 
     Given I am logged in as an "authenticated"
     When I go to "/eu-oss-catalogue"
@@ -15,6 +24,8 @@ Feature: Test EU OSS Catalogue killswitch
     Then the response status code should be 200
     And I go to "/eu-oss-catalogue/solutions"
     Then the response status code should be 200
+    And I go to the content page of the type "oss_solution" with the title "The Opensource Panacea"
+    Then the response status code should be 200
 
     Given I am logged in as a "developer"
     When I go to "/eu-oss-catalogue"
@@ -27,14 +38,20 @@ Feature: Test EU OSS Catalogue killswitch
     Then the response status code should be 200
     And I go to "/admin/content/eu-oss-catalogue/log"
     Then the response status code should be 200
+    And I go to the content page of the type "oss_solution" with the title "The Opensource Panacea"
+    Then the response status code should be 200
 
-    Given I disable EU OSS Catalogue
+    Given I visit "/dashboard"
+    When I press "Disable EU OSS Catalogue"
+    Then I should see the success message "EU OSS Catalogue has been disabled"
 
     Given I am an anonymous user
     When I go to "/eu-oss-catalogue"
     Then I should see the heading "Sign in to continue"
     And I go to "/eu-oss-catalogue/solutions"
     Then I should see the heading "Sign in to continue"
+    And I go to the content page of the type "oss_solution" with the title "The Opensource Panacea"
+    Then I should see the heading "Sign in to continue"
 
     Given I am logged in as an "authenticated"
     When I go to "/eu-oss-catalogue"
@@ -43,6 +60,8 @@ Feature: Test EU OSS Catalogue killswitch
     Then the response status code should be 403
     And I go to "/eu-oss-catalogue/solutions"
     Then the response status code should be 403
+    And I go to the content page of the type "oss_solution" with the title "The Opensource Panacea"
+    Then the response status code should be 403
 
     Given I am logged in as a "developer"
     When I go to "/eu-oss-catalogue"
@@ -55,31 +74,44 @@ Feature: Test EU OSS Catalogue killswitch
     Then the response status code should be 403
     And I go to "/admin/content/eu-oss-catalogue/log"
     Then the response status code should be 403
+    # Developer is and amin role, they can still see the node.
+    And I go to the content page of the type "oss_solution" with the title "The Opensource Panacea"
+    Then the response status code should be 200
 
-    Given I enable EU OSS Catalogue
+    Given I visit "/dashboard"
+    When I press "Enable EU OSS Catalogue"
+    Then I should see the success message "EU OSS Catalogue has been enabled"
 
-    Given I am an anonymous user
     When I go to "/eu-oss-catalogue"
     Then the response status code should be 200
     And I go to "/eu-oss-catalogue/solutions"
     Then the response status code should be 200
+    And I go to "/admin/content/eu-oss-catalogue"
+    Then the response status code should be 200
+    And I go to "/admin/content/eu-oss-catalogue/oss-solutions"
+    Then the response status code should be 200
+    And I go to "/admin/content/eu-oss-catalogue/log"
+    Then the response status code should be 200
+    And I go to the content page of the type "oss_solution" with the title "The Opensource Panacea"
+    Then the response status code should be 200
 
-    Given I am logged in as an "authenticated"
+    Given I am an anonymous user
     When I go to "/eu-oss-catalogue"
-    And I check "I agree to the Legal notice document"
-    And I press "Submit"
     Then the response status code should be 200
+    But I should not see "Sign in to continue"
     And I go to "/eu-oss-catalogue/solutions"
     Then the response status code should be 200
+    But I should not see "Sign in to continue"
+    And I go to the content page of the type "oss_solution" with the title "The Opensource Panacea"
+    Then the response status code should be 200
+    But I should not see "Sign in to continue"
 
-    Given I am logged in as a "developer"
+    Given I am logged in as an "authenticated"
     When I go to "/eu-oss-catalogue"
+    And I check "I agree to the Legal notice document"
+    And I press "Submit"
     Then the response status code should be 200
     And I go to "/eu-oss-catalogue/solutions"
     Then the response status code should be 200
-    And I go to "/admin/content/eu-oss-catalogue"
-    Then the response status code should be 200
-    And I go to "/admin/content/eu-oss-catalogue/oss-solutions"
-    Then the response status code should be 200
-    And I go to "/admin/content/eu-oss-catalogue/log"
+    And I go to the content page of the type "oss_solution" with the title "The Opensource Panacea"
     Then the response status code should be 200
diff --git a/tests/features/eulogin/eulogin.feature b/tests/features/eulogin/eulogin.feature
index 2a0be93c14832e5601a8d19022e0373cdd370240..db96a511c19ba7991b34c920a498c21d84e69930 100644
--- a/tests/features/eulogin/eulogin.feature
+++ b/tests/features/eulogin/eulogin.feature
@@ -329,6 +329,8 @@ Feature: Log in through EU Login
     When I go to "/user/password"
     Then the response status code should be 404
 
+  # TODO: Re-enable this test in ISAICP-9059
+  @wip
   Scenario: As a developer I can temporary disable the site registration.
     Given CAS users:
       | Username | E-mail          | Password |
diff --git a/tests/features/update/ISAICP-8911.feature b/tests/features/update/ISAICP-8911.feature
deleted file mode 100644
index b654cfff6dc51d9e02ee66aacc284efb301a18da..0000000000000000000000000000000000000000
--- a/tests/features/update/ISAICP-8911.feature
+++ /dev/null
@@ -1,39 +0,0 @@
-@api @group-clone
-Feature: Test the converted videos into document.
-
-  @update:joinup_core_update_111200
-  Scenario: Videos have migrated correctly.
-    When I visit "node/125946"
-    Then I should see the heading "eGovernment Reduction of Administrative Burden-ePractice TV interview: Mr Siim Sikkut"
-    And I should see the text "Mr Siim Sikkut, Government office of Estonia"
-    And I should see the text "Published on: 10/06/2014"
-    And I should see the text "Last update: 09/06/2014"
-
-    When I visit "node/125943"
-    Then I should see the heading "Concluding Remarks - Terje Peetso, DG CONNECT"
-    And I should see the text "Terje Peetso, DG CONNECT - eHealth and the Brain - ICT for Neuropsychiatric Health, 5 November, Brussels"
-    And I should see the text "Published on: 20/11/2013"
-
-    When I visit "node/125865"
-    Then I should see the heading "EIF workshop-ePractice TV:Soeren Bittins, Massimiliano Massi"
-    And I should see the text "EIF workshop, 16 April 2012"
-    And I should see the text "Interviewees: Soeren Bittins, Massimiliano Massi, Fraunhofer Fokus"
-    And I should see the text "Published on: 11/05/2012"
-
-    When I visit "/community/epractice/video/egov-reduction-admininstrative-burden-epractice-tv-interview-kris-blancke"
-    Then I should see the heading "eGov Reduction of Admininstrative Burden-ePractice TV interview: Kris Blancke"
-    And I should see the text "Mr Kris Blancke, Chancellery of the Prime Minister, Administrative Simplification Agency (DAV/ASA)"
-    And I should see the text "Published on: 10/06/2014"
-
-  @update:joinup_core_update_111200
-  Scenario Outline: Ensure old /elibrary/video/* redirects are maintained and are pointing to the new document nodes.
-    Given I visit "<source>"
-    Then I should be on "<destination>"
-
-    Examples:
-      | source                                                                                                | destination                                                                                                                                 |
-      | /elibrary/video/us-national-information-exchange-model-niem-explained                                 | /collection/semic-support-centre/document/us-national-information-exchange-model-niem-explained                                             |
-      | /elibrary/video/e-codex-e-justice-communication-online-data-exchange                                  | /collection/justice-law-and-security/document/e-codex-e-justice-communication-online-data-exchange                                          |
-      | /elibrary/video/eu-declan-deasy-about-digital-single-market                                           | /collection/egovernment/document/eu-declan-deasy-about-digital-single-market                                                                |
-      | /elibrary/video/eu-story-explaining-digital-single-market-and-large-scale-pilots                      | /collection/egovernment/document/eu-story-explaining-digital-single-market-and-large-scale-pilots                                           |
-      | /elibrary/video/presenting-osepa-project-share-knowledge-and-experience-about-foss-public-administrat | /collection/open-source-observatory-osor/document/presenting-osepa-project-share-knowledge-and-experience-about-foss-public-administrations |
diff --git a/tests/features/user/developer.feature b/tests/features/user/developer.feature
index ce9ad8758bd062e7bc711d2920827e4f6948be2c..299cf3d57aae3e1934c79a325717f2511dd17ba2 100644
--- a/tests/features/user/developer.feature
+++ b/tests/features/user/developer.feature
@@ -55,31 +55,3 @@ Feature: Variety tests for the developer role.
     Given I am logged in as an authenticated
     And I am on the homepage
     Then I should not see the text "Warning: You are working on production. Please, be extra cautious!"
-
-  Scenario: Configuration is locked and unlocked on developers login and logout.
-    Given users:
-      | Username   | Roles     |
-      | Some dev 1 | Developer |
-
-    When I am logged in as "Some dev 1"
-    Then the configuration should be locked
-
-    When I go to "/dashboard"
-    And I press "Disable config readonly"
-    Then I should see the success message "Disabled config readonly"
-    And the configuration should be unlocked
-    And I should not see the button "Disable config readonly"
-    And I should see the button "Enable config readonly"
-    And I should see the warning message "Config readonly is disabled!"
-
-    When I press "Enable config readonly"
-    Then I should see the success message "Enabled config readonly"
-    And the configuration should be locked
-    And I should see the button "Disable config readonly"
-    And I should not see the button "Enable config readonly"
-    And I should not see the warning message "Config readonly is disabled!"
-
-    When I press "Disable config readonly"
-    And I am on the homepage
-    And I click "Sign out"
-    Then the configuration should be locked
diff --git a/tests/src/Context/FeatureContext.php b/tests/src/Context/FeatureContext.php
index d4b879f7f129967fe372947372e5cbef523918ca..a303b7baf038f3c2d572e11ccd174f742472aa50 100644
--- a/tests/src/Context/FeatureContext.php
+++ b/tests/src/Context/FeatureContext.php
@@ -2428,23 +2428,6 @@ public function iRunTheQueueWorker(string $queue_name): void {
     sleep(1);
   }
 
-  /**
-   * Asserts that configuration is editable or locked.
-   *
-   * @param string $state
-   *   The state of the configuration. Either 'locked' or 'unlocked'.
-   *
-   * @Then the configuration should be :state
-   */
-  public function theConfigurationState(string $state): void {
-    \assert(in_array($state, ['locked', 'unlocked']));
-
-    /** @var \Drupal\joinup_core\JoinupSwitcherInterface $fileReadOnly */
-    $fileReadOnly = \Drupal::service('joinup_core.switcher');
-
-    Assert::assertTrue($fileReadOnly->isEnabled('config-readonly') === ($state === 'locked'));
-  }
-
   /**
    * Check the items in a queue.
    *
diff --git a/tests/src/Context/JoinupOSSSolutionContext.php b/tests/src/Context/JoinupOSSSolutionContext.php
index 70209e25493d8151ecfc2d5dbe9c1ed50db83e65..8f392676e1e91df6a6c9353b03da35ed8b95246b 100644
--- a/tests/src/Context/JoinupOSSSolutionContext.php
+++ b/tests/src/Context/JoinupOSSSolutionContext.php
@@ -52,26 +52,4 @@ public static function disableOssCron(): void {
     $state->set('eu_oss_catalogue.last_check', strtotime('- 1 hour'));
   }
 
-  /**
-   * Toggles ON/OFF EU OSS Catalogue functionality.
-   *
-   * @param string $toggle
-   *   Could be 'enable', 'disable'.
-   *
-   * @Given I :toggle EU OSS Catalogue
-   */
-  public function toggleEuOssCatalogue(string $toggle): void {
-    assert(in_array($toggle, ['enable', 'disable'], TRUE));
-
-    $switcher = \Drupal::getContainer()->get('joinup_core.switcher');
-    if ($toggle === 'enable') {
-      $switcher->enable('eu-oss-catalogue');
-    }
-    else {
-      $switcher->enable('eu-oss-catalogue');
-    }
-
-    \Drupal::getContainer()->get('cache.page')->deleteAll();
-  }
-
 }
diff --git a/tests/src/Traits/ConfigReadOnlyTrait.php b/tests/src/Traits/ConfigReadOnlyTrait.php
index 36640d0fd00e7a72c0e741c38dc0431a0d3b9673..54e258b40da093e7f91a154be522c7dd2a736877 100644
--- a/tests/src/Traits/ConfigReadOnlyTrait.php
+++ b/tests/src/Traits/ConfigReadOnlyTrait.php
@@ -16,6 +16,13 @@
  */
 trait ConfigReadOnlyTrait {
 
+  /**
+   * The initial state of config_readonly.
+   *
+   * @var bool
+   */
+  protected static $isConfigReadonlyEnabled;
+
   /**
    * Temporarily disables read only configuration.
    *
@@ -24,7 +31,17 @@ trait ConfigReadOnlyTrait {
    */
   public static function bypassReadOnlyConfig(): void {
     static::checkConfigReadOnlyKillSwitch();
-    \Drupal::getContainer()->get('joinup_core.switcher')->disable('config-readonly');
+
+    /** @var \Drupal\joinup_core\ConfigReadOnlyInterface $fileReadOnly */
+    $fileReadOnly = \Drupal::service('joinup_core.file_config_read_only');
+
+    if (!isset(static::$isConfigReadonlyEnabled)) {
+      // Save the initial state of config_readonly kill-switch.
+      static::$isConfigReadonlyEnabled = $fileReadOnly->isReadOnlyEnabled();
+    }
+
+    $fileReadOnly->disableReadOnly();
+
     // Ensure the new value also for the current request.
     new Settings(['config_readonly' => FALSE] + Settings::getAll());
   }
@@ -33,11 +50,18 @@ public static function bypassReadOnlyConfig(): void {
    * Restores the read only configuration functionality if available.
    */
   public static function restoreReadOnlyConfig(): void {
-    \Drupal::getContainer()->get('joinup_core.switcher')->enable('config-readonly');
-    // Ensure the new value also for the current request.
-    new Settings([
-      'config_readonly' => getenv('CONFIG_READONLY') !== 'false',
-    ] + Settings::getAll());
+    /** @var \Drupal\joinup_core\ConfigReadOnlyInterface $fileReadOnly */
+    $fileReadOnly = \Drupal::service('joinup_core.file_config_read_only');
+
+    // Restore as enabled only if initially has been enabled. This allows to
+    // keep config_readonly disabled on a local development environment (i.e.
+    // where the Task Runner config `config_readonly` was set to `false`), after
+    // the tests had finished.
+    if (static::$isConfigReadonlyEnabled) {
+      $fileReadOnly->enableReadOnly();
+      // Ensure the new value also for the current request.
+      new Settings(['config_readonly' => TRUE] + Settings::getAll());
+    }
   }
 
   /**
@@ -50,9 +74,9 @@ protected static function checkConfigReadOnlyKillSwitch(): void {
     /** @var \Drupal\Core\DrupalKernelInterface $kernel */
     $kernel = \Drupal::service('kernel');
     $site_path = $kernel->getSitePath();
-    $needle = "\$settings['config_readonly'] = getenv('CONFIG_READONLY') !== 'false' && !file_exists(getenv('DRUPAL_PRIVATE_FILE_SYSTEM') . '/killswitch/disable-config-readonly');";
-    $settingsPhp = file_get_contents("{$site_path}/settings.php");
-    if (!str_contains($settingsPhp, $needle)) {
+    $needle = "\$settings['config_readonly'] = !file_exists(getcwd() . '/../disable-config-readonly');";
+    $settings_php = file_get_contents("{$site_path}/settings.php");
+    if (strpos($settings_php, $needle) === FALSE) {
       throw new \Exception("The following line is missing from web/sites/default/settings.php\n$needle");
     }
   }
diff --git a/web/modules/custom/dashboard/src/Form/DashboardForm.php b/web/modules/custom/dashboard/src/Form/DashboardForm.php
index a0c82cd99eb88290f1a8283c3677c13b836a29a4..0c0a74d9098a74612df358c64a5aec2923ca8e63 100644
--- a/web/modules/custom/dashboard/src/Form/DashboardForm.php
+++ b/web/modules/custom/dashboard/src/Form/DashboardForm.php
@@ -5,13 +5,12 @@
 namespace Drupal\dashboard\Form;
 
 use Drupal\Core\Access\AccessResultInterface;
-use Drupal\Core\Cache\CacheTagsInvalidatorInterface;
+use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\State\StateInterface;
 use Drupal\Core\Url;
-use Drupal\joinup_core\JoinupSwitcherInterface;
 use Drupal\joinup_core\Logger\Handler\MailHandler;
 use Drupal\joinup_core\Logger\Handler\TelegramHandler;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -23,8 +22,7 @@ class DashboardForm extends FormBase {
 
   public function __construct(
     protected StateInterface $state,
-    protected JoinupSwitcherInterface $switcher,
-    protected CacheTagsInvalidatorInterface $invalidator,
+    protected CacheBackendInterface $pageCache,
   ) {
   }
 
@@ -34,8 +32,7 @@ public function __construct(
   public static function create(ContainerInterface $container): self {
     return new static(
       $container->get('state'),
-      $container->get('joinup_core.switcher'),
-      $container->get('cache_tags.invalidator')
+      $container->get('cache.page'),
     );
   }
 
@@ -102,19 +99,20 @@ public function buildForm(array $form, FormStateInterface $form_state): array {
       '#value' => $this->t('Submit'),
     ];
 
-    $hasEnableDisablePermission = $this->currentUser()->hasPermission('enable/disable config readonly');
-    $configReadonlyIsEnabled = $this->switcher->isEnabled('config-readonly');
+    // @todo Remove this button in ISAICP-9053.
+    $hasEnableDisablePermission = $this->currentUser()->hasPermission('toggle eu oss catalogue state');
     $form['actions']['enable'] = [
       '#type' => 'submit',
-      '#value' => $this->t('Enable config readonly'),
-      '#submit' => ['::enableConfigSubmitForm'],
-      '#access' => $hasEnableDisablePermission && !$configReadonlyIsEnabled,
+      '#value' => $this->t('Enable EU OSS Catalogue'),
+      '#submit' => ['::enableEuOssCatalogueSubmitForm'],
+      '#access' => $hasEnableDisablePermission && !joinup_oss_catalogue_is_enabled(),
     ];
+    // @todo Remove this button in ISAICP-9053.
     $form['actions']['disable'] = [
       '#type' => 'submit',
-      '#value' => $this->t('Disable config readonly'),
-      '#submit' => ['::disableConfigSubmitForm'],
-      '#access' => $hasEnableDisablePermission && $configReadonlyIsEnabled,
+      '#value' => $this->t('Disable EU OSS Catalogue'),
+      '#submit' => ['::disableEuOssCatalogueSubmitForm'],
+      '#access' => $hasEnableDisablePermission && joinup_oss_catalogue_is_enabled(),
     ];
 
     return $form;
@@ -122,20 +120,26 @@ public function buildForm(array $form, FormStateInterface $form_state): array {
 
   /**
    * Enable the configuration submit form.
+   *
+   * @todo Remove this method in ISAICP-9053.
    */
-  public function enableConfigSubmitForm(): void {
-    $this->switcher->enable('config-readonly');
-    $this->invalidator->invalidateTags(['joinup_user:read_only_config']);
-    $this->messenger()->addStatus($this->t('Enabled config readonly'));
+  public function enableEuOssCatalogueSubmitForm(): void {
+    $this->state->delete('joinup.oss_catalogue_is_disabled');
+    // Only clear cache for anonymous.
+    $this->pageCache->deleteAll();
+    $this->messenger()->addStatus($this->t('EU OSS Catalogue has been enabled'));
   }
 
   /**
    * Disables the config submit form.
+   *
+   * @todo Remove this method in ISAICP-9053.
    */
-  public function disableConfigSubmitForm(): void {
-    $this->switcher->disable('config-readonly');
-    $this->invalidator->invalidateTags(['joinup_user:read_only_config']);
-    $this->messenger()->addStatus($this->t('Disabled config readonly'));
+  public function disableEuOssCatalogueSubmitForm(): void {
+    $this->state->set('joinup.oss_catalogue_is_disabled', TRUE);
+    // Only clear cache for anonymous.
+    $this->pageCache->deleteAll();
+    $this->messenger()->addStatus($this->t('EU OSS Catalogue has been disabled'));
   }
 
   /**
diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.deploy.php b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.deploy.php
deleted file mode 100644
index 265203b6ed226a49ce09edf77b7b71a788044b48..0000000000000000000000000000000000000000
--- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.deploy.php
+++ /dev/null
@@ -1,136 +0,0 @@
-<?php
-
-/**
- * @file
- * Deploy functions for Joinup OSS.
- */
-
-declare(strict_types=1);
-
-use Drupal\Core\Url;
-use Drupal\joinup_oss_catalogue\OssCatalogueCollectionInterface;
-
-/**
- * Update path alias for EU OSS catalogue.
- */
-function joinup_oss_catalogue_deploy_111200(): void {
-  /** @var \Drupal\collection\Entity\CollectionInterface $collection */
-  $collection = \Drupal::entityTypeManager()->getStorage('rdf_entity')
-    ->load(OssCatalogueCollectionInterface::COLLECTION_ENTITY_ID);
-  $collection
-    ?->set('path', ['alias' => '/eu-oss-catalogue', 'pathauto' => 0])
-      ->save();
-}
-
-/**
- * Update title of EU OSS catalogue collection.
- */
-function joinup_oss_catalogue_deploy_111201(): void {
-  /** @var \Drupal\collection\Entity\CollectionInterface $collection */
-  $collection = \Drupal::entityTypeManager()->getStorage('rdf_entity')
-    ->load(OssCatalogueCollectionInterface::COLLECTION_ENTITY_ID);
-
-  $collection
-    ?->set('label', 'EU Open Source Solutions Catalogue')
-      ->save();
-}
-
-/**
- * Import content for EU OpenSource Software Solutions Catalogue.
- */
-function joinup_oss_catalogue_deploy_111202(): void {
-  /** @var \Drupal\Core\Extension\ModuleInstallerInterface $moduleInstaller */
-  $moduleInstaller = \Drupal::service('module_installer');
-  /** @var \Drupal\Core\Entity\EntityRepositoryInterface $entityRepository */
-  $entityRepository = \Drupal::service('entity.repository');
-
-  // Delete faulty meta entity.
-  $entityRepository
-    ->loadEntityByUuid('meta_entity', 'ad9be48e-7116-44b3-8df2-db8cb9343268')
-    ?->delete();
-
-  // Import content.
-  $moduleInstaller->install(['default_content']);
-  /** @var \Drupal\default_content\ImporterInterface $importer */
-  \Drupal::service('default_content.importer')
-    ->importContent('joinup_oss_catalogue', TRUE);
-  $moduleInstaller->uninstall(['default_content']);
-
-  // Disable auto-created left-side menu link.
-  $landingPage = $entityRepository->loadEntityByUuid('node', '54acbd6f-47f0-4280-ad09-0a07c397318b');
-  $linkPlugins = \Drupal::service('plugin.manager.menu.link')
-    ->loadLinksByRoute('entity.node.canonical', ['node' => $landingPage->id()], 'ogmenu-3728');
-  /** @var \Drupal\menu_link_content\Plugin\Menu\MenuLinkContent $linkPlugin */
-  $linkPlugin = reset($linkPlugins);
-  $entityRepository
-    ->loadEntityByUuid('menu_link_content', $linkPlugin->getDerivativeId())
-    ->setUnpublished()
-    ->save();
-}
-
-/**
- * Rename menu items for EU OSS catalogue.
- */
-function joinup_oss_catalogue_deploy_111203(): void {
-  $entityTypeManager = \Drupal::entityTypeManager();
-  /** @var  \Drupal\menu_link_content\MenuLinkContentStorageInterface $menuLinkContentStorage */
-  $menuLinkContentStorage = $entityTypeManager->getStorage('menu_link_content');
-
-  $menuName = 'ogmenu-3728';
-  // Collect the IDs of links to the custom page.
-  $ids = $menuLinkContentStorage->getQuery()->accessCheck(FALSE)
-    ->condition('bundle', 'menu_link_content')
-    ->condition('menu_name', $menuName)
-    ->execute();
-
-  $links = $menuLinkContentStorage->loadMultiple($ids);
-  foreach ($links as $link) {
-    $title = $link->getTitle();
-    if ($title === 'About' || $title === 'Members') {
-      $link->setUnpublished()->save();
-    }
-    elseif ($title === 'Overview') {
-      $link->set('title', 'Welcome')->save();
-    }
-  }
-  $link = [
-    'uri' => Url::fromRoute('view.search_oss_catalogue.search')->toUriString(),
-  ];
-  $menuLinkContentStorage->create([
-    'title' => t('Search'),
-    'menu_name' => $menuName,
-    'link' => $link,
-    'weight' => -6,
-  ])->save();
-}
-
-/**
- * Make sure that oss_archived has a default value.
- */
-function joinup_oss_catalogue_deploy_111204(array &$sandbox): string {
-  $entityTypeManager = \Drupal::entityTypeManager();
-  /** @var \Drupal\node\NodeStorage $nodeStorage */
-  $nodeStorage = $entityTypeManager->getStorage('node');
-
-  if (empty($sandbox['ids'])) {
-    $results = $nodeStorage->getQuery()->accessCheck(FALSE)
-      ->condition('type', 'oss_solution')
-      ->notExists('oss_archived')
-      ->execute();
-
-    $sandbox['ids'] = array_values($results);
-    $sandbox['progress'] = 0;
-    $sandbox['count'] = count($sandbox['ids']);
-  }
-
-  $ids = array_splice($sandbox['ids'], 0, 50);
-  foreach ($nodeStorage->loadMultiple($ids) as $solution) {
-    $solution->set('oss_archived', 0);
-    $solution->save();
-  }
-
-  $sandbox['progress'] += count($ids);
-  $sandbox['#finished'] = (int) empty($sandbox['ids']);
-
-  return "Processed {$sandbox['progress']} out of {$sandbox['count']} solutions.";
-}
diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.install b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.install
index f811958465d62aff8c7f3a9cafadaf143229141c..8de55f0c533be8000fa8748bfd737656825e9c4b 100644
--- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.install
+++ b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.install
@@ -2,31 +2,19 @@
 
 /**
  * @file
- * Install, update, and uninstall functions for the Joinup OSS module.
+ * Install, update hooks for Joinup OSS Catalogue module.
  */
 
 declare(strict_types=1);
 
-use Drupal\Core\Serialization\Yaml;
+use Drupal\joinup_oss_catalogue\OssCatalogueCollectionInterface;
 
 /**
- * Pre-creates OSS vocabularies.
+ * Publish the EU OSS Catalogue collection.
  */
-function joinup_oss_catalogue_update_111200(): void {
-  // Pre-create the new controlled vocabularies provided by eu_oss_catalogue
-  // module. Normally, these are imported as config but eu_oss_catalogue install
-  // goes first and its install process is also populating them with terms, so
-  // they should be available at that point.
-  $config_factory = \Drupal::configFactory();
-  foreach ([
-    'category',
-    'licence',
-    'intended_audience_scope',
-    'software_type',
-  ] as $vocab) {
-    $name = "taxonomy.vocabulary.oss_$vocab";
-    $config_factory->getEditable($name)
-      ->setData(Yaml::decode(file_get_contents(DRUPAL_ROOT . "/../config/sync/$name.yml")))
-      ->save();
-  }
+function joinup_oss_catalogue_update_200001(): void {
+  $collection = \Drupal::entityTypeManager()->getStorage('rdf_entity')
+    ->load(OssCatalogueCollectionInterface::COLLECTION_ENTITY_ID);
+  $collection->skip_notification = TRUE;
+  $collection->set('field_ar_state', 'published')->save();
 }
diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.module b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.module
index b3e79545028481150c328b3f85668378eabf4499..8212527be9fd2c44c856ef9a4e6facb2ff2bdd1f 100644
--- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.module
+++ b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.module
@@ -9,10 +9,12 @@
 
 use Drupal\Core\Access\AccessResult;
 use Drupal\Core\Access\AccessResultInterface;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Session\AccountInterface;
-use Drupal\Core\Site\Settings;
 use Drupal\Core\Url;
 use Drupal\block\BlockInterface;
+use Drupal\collection\Entity\CollectionInterface;
+use Drupal\custom_page\Entity\CustomPageInterface;
 use Drupal\eu_oss_catalogue\Entity\OssSolutionInterface;
 use Drupal\joinup_group\Entity\GroupInterface;
 use Drupal\joinup_oss_catalogue\Entity\JoinupOssSolution;
@@ -190,13 +192,39 @@ function joinup_oss_catalogue_preprocess_views_view__eu_oss_catalogue_admin_caro
  *
  * @return bool
  *   Whether the EU OSS Catalogue functionality is enabled.
+ *
+ * @todo Remove this function in ISAICP-9053.
  */
 function joinup_oss_catalogue_is_enabled(): bool {
-  return Settings::get('eu_oss_catalogue')['enabled'] ?? FALSE;
+  return !\Drupal::state()->get('joinup.oss_catalogue_is_disabled', FALSE);
+}
+
+/**
+ * Implements hook_entity_access().
+ *
+ * @todo Remove this function in ISAICP-9053.
+ */
+function joinup_oss_catalogue_entity_access(EntityInterface $entity): AccessResultInterface {
+  if (
+    // The entity is the EU OSS Catalogue collection...
+    ($entity instanceof CollectionInterface && $entity->id() === OssCatalogueCollectionInterface::COLLECTION_ENTITY_ID) ||
+    // ...or the EU OSS Catalogue collection landing page...
+    ($entity instanceof CustomPageInterface && $entity->uuid() === OssCatalogueCollectionInterface::LANDING_PAGE) ||
+    // ...or an OSS Solution.
+    ($entity instanceof OssSolutionInterface)
+  ) {
+    return AccessResult::forbiddenIf(
+      !joinup_oss_catalogue_is_enabled(),
+      'EU OSS Catalogue is disabled',
+    )->addCacheableDependency($entity);
+  }
+  return AccessResult::neutral();
 }
 
 /**
  * Implements hook_module_implements_alter().
+ *
+ * @todo Remove this function in ISAICP-9053.
  */
 function joinup_oss_catalogue_module_implements_alter(array &$implementations, string $hook): void {
   if ($hook === 'cron') {
@@ -209,6 +237,8 @@ function joinup_oss_catalogue_module_implements_alter(array &$implementations, s
 
 /**
  * Implements hook_cron().
+ *
+ * @todo Remove this function in ISAICP-9053.
  */
 function joinup_oss_catalogue_cron(): void {
   if (joinup_oss_catalogue_is_enabled()) {
diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.permissions.yml b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.permissions.yml
index a2b76e0424d157c1ff8e2b3e1b29aefc02fe1a2c..7b38dbd0147dea12c4f75e8803c3a81f06a21236 100644
--- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.permissions.yml
+++ b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.permissions.yml
@@ -1,2 +1,6 @@
 eu oss catalogue log:
   title: 'Access eu oss catalogue log'
+# TODO: Drop this permission in ISAICP-9053.
+toggle eu oss catalogue state:
+  title: 'Toggle ON/OFF the EU OSS Catalogue'
+  restrict access: true
diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.services.yml b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.services.yml
index bb66d2ef8365e52c6b0455433f9bbba5afe4e18d..8b719cbe32783a8b0986d36cb38a6cdcfbc8943b 100644
--- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.services.yml
+++ b/web/modules/custom/joinup_communities/joinup_oss_catalogue/joinup_oss_catalogue.services.yml
@@ -16,6 +16,7 @@ services:
     arguments:
       - '@queue'
 
+  # TODO: Remove this service in ISAICP-9053.
   joinup_oss_catalogue.killswitch_check:
     class: Drupal\joinup_oss_catalogue\Access\KillSwitchCheck
     tags:
diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/Access/KillSwitchCheck.php b/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/Access/KillSwitchCheck.php
index a13856cc66f4819007e935e41ff457196d382e1c..5c68df86ad23a526d89f9acc5dfc5ffb5b7be707 100644
--- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/Access/KillSwitchCheck.php
+++ b/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/Access/KillSwitchCheck.php
@@ -8,15 +8,15 @@
 use Drupal\Core\Access\AccessResultInterface;
 use Drupal\Core\Routing\Access\AccessInterface;
 use Drupal\Core\Routing\RouteMatchInterface;
-use Drupal\collection\Entity\CollectionInterface;
 use Drupal\eu_oss_catalogue\EuOssCatalogueInterface;
-use Drupal\joinup_oss_catalogue\OssCatalogueCollectionInterface;
 use Symfony\Component\Routing\Route;
 
 /**
  * Access checker for _eu_oss_catalogue_check_enabled routes.
+ *
+ * @todo Remove this service in ISAICP-9053.
  */
-class KillSwitchCheck implements AccessInterface {
+final readonly class KillSwitchCheck implements AccessInterface {
 
   public function __construct(
     protected readonly EuOssCatalogueInterface $service,
@@ -33,15 +33,6 @@ public function access(Route $route, RouteMatchInterface $routeMatch): AccessRes
     if ($requirement !== 'TRUE') {
       throw new \Exception("The _eu_oss_catalogue_check_enabled route requirement when present can only have 'TRUE' as value but '$requirement' was given.");
     }
-
-    if ($routeMatch->getRouteName() === 'entity.rdf_entity.canonical') {
-      $rdf_entity = $routeMatch->getParameter('rdf_entity');
-      if (!$rdf_entity instanceof CollectionInterface || $rdf_entity->id() !== OssCatalogueCollectionInterface::COLLECTION_ENTITY_ID) {
-        // Any page except the EU OSS Catalogue landing page is allowed.
-        return AccessResult::allowed();
-      }
-    }
-
     return joinup_oss_catalogue_is_enabled() ? AccessResult::allowed() : AccessResult::forbidden('EU OSS Catalogue functionality is disabled');
   }
 
diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/Drush/Commands/JoinupOssCatalogueCommands.php b/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/Drush/Commands/JoinupOssCatalogueCommands.php
index a792d38b2026fda2e409f33a3fca8dd41c39b45c..78e167c5de1a1825e12e3ffd7fef21e748aac977 100644
--- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/Drush/Commands/JoinupOssCatalogueCommands.php
+++ b/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/Drush/Commands/JoinupOssCatalogueCommands.php
@@ -18,6 +18,8 @@
 
 /**
  * EU OSS Catalogue commands replacements.
+ *
+ * @todo Remove this class in ISAICP-9053.
  */
 class JoinupOssCatalogueCommands extends DrushCommands {
 
diff --git a/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/OssRouteSubscriber.php b/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/OssRouteSubscriber.php
index fc04b4f9b546380fb46ab755a47a7843245e2dd6..bffe6453ee01d8bb3e7c3ce92bd8ef20e05d2d64 100644
--- a/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/OssRouteSubscriber.php
+++ b/web/modules/custom/joinup_communities/joinup_oss_catalogue/src/OssRouteSubscriber.php
@@ -26,6 +26,7 @@ public function alterRoutes(RouteCollection $collection): void {
       $route->setRequirement('_oss_access_check', 'TRUE');
     }
 
+    // @todo Remove this route alteration in ISAICP-9053.
     $routeNames = [
       'eu_oss_catalogue.provider.collection',
       'eu_oss_catalogue.hosting_platform_add',
@@ -33,7 +34,6 @@ public function alterRoutes(RouteCollection $collection): void {
       'view.eu_oss_catalogue_admin.page',
       'view.eu_oss_catalogue_log.page',
       'view.search_oss_catalogue.search',
-      'entity.rdf_entity.canonical',
     ];
     foreach ($routeNames as $routeName) {
       if ($route = $collection->get($routeName)) {
diff --git a/web/modules/custom/joinup_core/joinup_core.install b/web/modules/custom/joinup_core/joinup_core.install
index fabb9b35dc69b2b1dbad5cb56f57bce4dd137b58..823aea261c333394859790febb776eeaa9003fd8 100644
--- a/web/modules/custom/joinup_core/joinup_core.install
+++ b/web/modules/custom/joinup_core/joinup_core.install
@@ -7,11 +7,7 @@
 
 declare(strict_types=1);
 
-use Drupal\Core\Datetime\DrupalDateTime;
 use Drupal\Core\Site\Settings;
-use Drupal\datetime\Plugin\Field\FieldType\DateTimeItemInterface;
-use Drupal\node\Entity\Node;
-use Drupal\paragraphs\Entity\Paragraph;
 use Drupal\user\Entity\User;
 
 /**
@@ -96,118 +92,3 @@ function joinup_core_requirements($phase): array {
 
   return $requirements;
 }
-
-/**
- * Convert videos into document.
- */
-function joinup_core_update_111200(array &$sandbox): string {
-  if (!isset($sandbox['video_nids'])) {
-    // Collect all video nodes to migrate.
-    $video_nids = \Drupal::entityQuery('node')
-      ->accessCheck(FALSE)
-      ->condition('type', 'video')
-      ->execute();
-
-    $sandbox['max'] = count($video_nids);
-    $sandbox['count'] = 0;
-    $sandbox['video_nids'] = $video_nids;
-  }
-
-  // Load video nodes.
-  $video_nids = array_slice($sandbox['video_nids'], $sandbox['count'], 20);
-  $entity_type_manager = \Drupal::entityTypeManager();
-  $video_nodes = $entity_type_manager->getStorage('node')->loadMultiple($video_nids);
-
-  /** @var \Drupal\redirect\RedirectRepository $redirect_repository */
-  $redirect_repository = \Drupal::service('redirect.repository');
-
-  // Migrate each video.
-  foreach ($video_nodes as $video_node) {
-    // Find redirects to the video node to preserve after deletion.
-    /* @see redirect_entity_delete */
-    $redirects = $redirect_repository->findByDestinationUri([
-      "internal:/node/{$video_node->id()}",
-      "entity:node/{$video_node->id()}",
-    ]);
-
-    // Prepare new document node.
-    $formatted_date = (new DrupalDateTime())->setTimestamp($video_node->getCreatedTime())->format(DateTimeItemInterface::DATETIME_STORAGE_FORMAT);
-    $created_time = $video_node->getCreatedTime();
-    $document_node = Node::create([
-      'type' => 'document',
-      'nid' => $video_node->id(),
-      'title' => $video_node->getTitle(),
-      'uid' => $video_node->getOwnerId(),
-      'status' => $video_node->isPublished(),
-      'created' => $created_time,
-      'changed' => $video_node->getChangedTime(),
-      'og_audience' => $video_node->get('og_audience')->target_id,
-      'field_document_spatial_coverage' => $video_node->get('field_video_spatial_coverage')->target_id,
-      'field_keywords' => $video_node->get('field_keywords')->getValue(),
-      'field_document_publication_date' => $formatted_date,
-      'published_at' => $created_time,
-      'field_state' => 'published',
-    ]);
-
-    $layout_paragraph = Paragraph::create(['type' => 'layout']);
-    $layout_paragraph->setBehaviorSettings('layout_paragraphs', [
-      'layout' => 'layout_onecol',
-      'config' => ['label' => ''],
-      'parent_uuid' => NULL,
-      'region' => NULL,
-    ]);
-
-    $body_paragraph = Paragraph::create([
-      'type' => 'text',
-      'field_body' => [
-        'value' => $video_node->get('body')->value,
-        'format' => 'text_html',
-      ],
-    ]);
-    $body_paragraph->setBehaviorSettings('layout_paragraphs', [
-      'parent_uuid' => $layout_paragraph->uuid(),
-      'region' => 'content',
-    ]);
-
-    $video_paragraph = Paragraph::create([
-      'type' => 'video',
-      'paragraph_video_url' => $video_node->get('field_video')->getValue(),
-    ]);
-    $video_paragraph->setBehaviorSettings('layout_paragraphs', [
-      'parent_uuid' => $layout_paragraph->uuid(),
-      'region' => 'content',
-    ]);
-
-    $document_node->set('field_paragraphs_body', [
-      ['entity' => $layout_paragraph],
-      ['entity' => $body_paragraph],
-      ['entity' => $video_paragraph],
-    ]);
-
-    // Delete video node.
-    $video_node->delete();
-
-    // Save new document node.
-    // Create 2 revisions (1 published and 1 archived); un-archiving requires a
-    // previous published revision otherwise a fatal error occurs.
-    /* @see \Drupal\joinup_workflow\WorkflowHelper::unarchiveEntity */
-    $document_node->setRevisionCreationTime($created_time);
-    $document_node->skip_notification = TRUE;
-    $document_node->save();
-
-    $document_node->set('field_state', 'archived');
-    $document_node->setNewRevision();
-    $document_node->skip_notification = TRUE;
-    $document_node->save();
-
-    // Restore redirects.
-    foreach ($redirects as $redirect) {
-      $redirect->createDuplicate()->save();
-    }
-
-    $sandbox['count']++;
-  }
-
-  $sandbox['#finished'] = $sandbox['count'] === $sandbox['max'];
-  return "{$sandbox['count']} out of {$sandbox['max']} video nodes processed.";
-}
diff --git a/web/modules/custom/joinup_core/joinup_core.services.yml b/web/modules/custom/joinup_core/joinup_core.services.yml
index 7d15ddfbae57947e48942f538508b7e4b8b48741..9ed58a6e572f9b7eaaf8ecdecd928e52f375d18c 100644
--- a/web/modules/custom/joinup_core/joinup_core.services.yml
+++ b/web/modules/custom/joinup_core/joinup_core.services.yml
@@ -42,9 +42,9 @@ services:
     tags:
       - { name: event_subscriber }
 
-  joinup_core.switcher:
-    class: Drupal\joinup_core\JoinupSwitcher
-    arguments: ['@file_system']
+  joinup_core.file_config_read_only:
+    class: Drupal\joinup_core\FileConfigReadOnly
+    arguments: [ '@file_system' ]
 
   # Prevent errors in twigc by implementing the missing get_dummy_text function,
   # which is referenced in BCL component templates.
diff --git a/web/modules/custom/joinup_core/src/Commands/JoinupDataSanitizationCommands.php b/web/modules/custom/joinup_core/src/Commands/JoinupDataSanitizationCommands.php
index fc64beb5af89e32ea69ca2e40d78c7003b216957..8734c8dff365ce1acda7ce8a5552212badbcb57e 100644
--- a/web/modules/custom/joinup_core/src/Commands/JoinupDataSanitizationCommands.php
+++ b/web/modules/custom/joinup_core/src/Commands/JoinupDataSanitizationCommands.php
@@ -47,6 +47,8 @@ public function sanitize($result, CommandData $commandData): void {
     $this->sanitizeLogAlertsSettings();
     $this->sanitizeEmailConfirmerData();
     $this->sanitizeDownloadEventData();
+    // @todo Remove this call in ISAICP-9053.
+    $this->sanitizeEuOssCatalogueSwitcher();
   }
 
   /**
@@ -60,6 +62,8 @@ public function messages(&$messages, InputInterface $input): void {
     $messages[] = dt('Sanitize log alerts settings.');
     $messages[] = dt('Sanitize email confirmer data.');
     $messages[] = dt('Sanitize download event data.');
+    // @todo Remove this message in ISAICP-9053.
+    $messages[] = dt('Sanitize EU OSS Catalogue switcher.');
   }
 
   /**
@@ -179,4 +183,17 @@ protected function sanitizeEntityFieldsData(string $entityType, array $fieldName
     }
   }
 
+  /**
+   * Sanitizes the EU OSS Catalogue switcher.
+   *
+   * @todo Remove this method in ISAICP-9053.
+   */
+  protected function sanitizeEuOssCatalogueSwitcher(): void {
+    $this->db->delete('key_value')
+      ->condition('collection', 'state')
+      ->condition('name', 'joinup.oss_catalogue_is_disabled')
+      ->execute();
+    $this->logger()->success(dt('joinup.oss_catalogue_is_disabled state var sanitized.'));
+  }
+
 }
diff --git a/web/modules/custom/joinup_core/src/ConfigReadOnlyInterface.php b/web/modules/custom/joinup_core/src/ConfigReadOnlyInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..e74bce804dc652d0e379a98adb352faf3dc00ef1
--- /dev/null
+++ b/web/modules/custom/joinup_core/src/ConfigReadOnlyInterface.php
@@ -0,0 +1,30 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\joinup_core;
+
+/**
+ * Config read-only interface.
+ */
+interface ConfigReadOnlyInterface {
+
+  /**
+   * Checks if read-only mode is enabled.
+   *
+   * @return bool
+   *   Returns true if read-only mode is enabled, false otherwise.
+   */
+  public function isReadOnlyEnabled(): bool;
+
+  /**
+   * Disables read-only mode.
+   */
+  public function disableReadOnly(): void;
+
+  /**
+   * Enables read-only mode.
+   */
+  public function enableReadOnly(): void;
+
+}
diff --git a/web/modules/custom/joinup_core/src/FileConfigReadOnly.php b/web/modules/custom/joinup_core/src/FileConfigReadOnly.php
new file mode 100644
index 0000000000000000000000000000000000000000..7ff9241f8dc846f34d962d970bef81807b6f46a6
--- /dev/null
+++ b/web/modules/custom/joinup_core/src/FileConfigReadOnly.php
@@ -0,0 +1,56 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\joinup_core;
+
+use Drupal\Core\File\FileSystemInterface;
+
+/**
+ * Represents a file-based implementation of the ConfigReadOnlyInterface.
+ */
+class FileConfigReadOnly implements ConfigReadOnlyInterface {
+
+  /**
+   * File name of the disabled config readonly.
+   *
+   * @var string
+   */
+  protected const string FILE_NAME = 'disable-config-readonly';
+
+  public function __construct(protected FileSystemInterface $fileSystem) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isReadOnlyEnabled(): bool {
+    return !file_exists($this->pathToReadOnlyFile());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function enableReadOnly(): void {
+    if (!$this->isReadOnlyEnabled()) {
+      $this->fileSystem->unlink($this->pathToReadOnlyFile());
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function disableReadOnly(): void {
+    touch($this->pathToReadOnlyFile());
+  }
+
+  /**
+   * Returns the file path to disable the config readonly flag.
+   *
+   * @return string
+   *   The file path
+   */
+  protected function pathToReadOnlyFile(): string {
+    return DRUPAL_ROOT . '/../' . self::FILE_NAME;
+  }
+
+}
diff --git a/web/modules/custom/joinup_core/src/JoinupSwitcher.php b/web/modules/custom/joinup_core/src/JoinupSwitcher.php
deleted file mode 100644
index 40f3d87c4a121ef48814f107cf56e662948d8245..0000000000000000000000000000000000000000
--- a/web/modules/custom/joinup_core/src/JoinupSwitcher.php
+++ /dev/null
@@ -1,64 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\joinup_core;
-
-use Drupal\Core\File\FileExists;
-use Drupal\Core\File\FileSystemInterface;
-
-/**
- * Represents a file-based implementation of the ConfigReadOnlyInterface.
- */
-class JoinupSwitcher implements JoinupSwitcherInterface {
-
-  protected const string DIR = 'private://killswitch';
-
-  protected const array FEATURES = ['config-readonly', 'eu-oss-catalogue'];
-
-  public function __construct(protected FileSystemInterface $fileSystem) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isEnabled(string $feature): bool {
-    $file = $this->fileSystem->realpath($this->pathToFile($feature));
-    if ($file && file_exists($file)) {
-      return TRUE;
-    }
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function enable(string $feature): void {
-    if (!$this->isEnabled('config-readonly')) {
-      $file = $this->fileSystem->realpath($this->pathToFile($feature));
-      $this->fileSystem->unlink($file);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function disable(string $feature): void {
-    $file = $this->fileSystem->realpath($this->pathToFile($feature));
-    $this->fileSystem->saveData('', $file, FileExists::Replace);
-  }
-
-  /**
-   * Returns the file path to the kill-switch file.
-   *
-   * @param string $feature
-   *   The feature. E.g. 'config-readonly'.
-   *
-   * @return string
-   *   The file path
-   */
-  protected function pathToFile(string $feature): string {
-    assert(in_array($feature, static::FEATURES, TRUE));
-    return static::DIR . "/disable-$feature";
-  }
-
-}
diff --git a/web/modules/custom/joinup_core/src/JoinupSwitcherInterface.php b/web/modules/custom/joinup_core/src/JoinupSwitcherInterface.php
deleted file mode 100644
index 9a49e350f86b52cb538028dc9f357a120d5743a7..0000000000000000000000000000000000000000
--- a/web/modules/custom/joinup_core/src/JoinupSwitcherInterface.php
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace Drupal\joinup_core;
-
-/**
- * Switcher interface.
- */
-interface JoinupSwitcherInterface {
-
-  /**
-   * Checks if the passed functionality is enabled.
-   *
-   * @param string $feature
-   *   The feature to be checked. E.g. 'config-readonly'.
-   *
-   * @return bool
-   *   Returns true if read-only mode is enabled, false otherwise.
-   */
-  public function isEnabled(string $feature): bool;
-
-  /**
-   * Disables the feature mode.
-   *
-   * @param string $feature
-   *   The feature to be disabled. E.g. 'config-readonly'.
-   */
-  public function disable(string $feature): void;
-
-  /**
-   * Enables read-only mode.
-   *
-   * @param string $feature
-   *   The feature to be disabled. E.g. 'config-readonly'.
-   */
-  public function enable(string $feature): void;
-
-}
diff --git a/web/modules/custom/joinup_log/joinup_log.install b/web/modules/custom/joinup_log/joinup_log.install
deleted file mode 100644
index 5066d9fb68a784c7033a1da7bdd119d807c6c8d8..0000000000000000000000000000000000000000
--- a/web/modules/custom/joinup_log/joinup_log.install
+++ /dev/null
@@ -1,39 +0,0 @@
-<?php
-
-/**
- * @file
- * Install and update hooks.
- */
-
-declare(strict_types=1);
-
-use Drupal\Core\Field\BaseFieldDefinition;
-use Drupal\Core\StringTranslation\TranslatableMarkup;
-
-/**
- * Add the `variables` field.
- */
-function joinup_log_update_111200(): TranslatableMarkup {
-  $definition_update_manager = \Drupal::entityDefinitionUpdateManager();
-
-  $field = BaseFieldDefinition::create('map')
-    ->setLabel(new TranslatableMarkup('Variables'))
-    ->setDefaultValue(serialize([]))
-    ->setDescription(new TranslatableMarkup('Serialized array of variables that match the message string and that is passed into the t() function.'));
-  $definition_update_manager->installFieldStorageDefinition('variables', 'joinup_log', 'joinup_log', $field);
-
-  return t('The variables fields have been added to Joinup log.');
-}
-
-/**
- * Set the `variables` field.
- */
-function joinup_log_update_111201(): TranslatableMarkup {
-  $query = \Drupal::database()->update('joinup_log')
-    ->fields([
-      'variables' => serialize([]),
-    ]);
-  $query->execute();
-
-  return t('Updated Joinup log entities.');
-}
diff --git a/web/modules/custom/joinup_user/joinup_user.module b/web/modules/custom/joinup_user/joinup_user.module
index 4097ae0944693a05d77a04f68f0a6ed7f6af7ac4..b721c4bad5429cc5a1dfcef253ef8671d53fa7c3 100644
--- a/web/modules/custom/joinup_user/joinup_user.module
+++ b/web/modules/custom/joinup_user/joinup_user.module
@@ -686,24 +686,6 @@ function joinup_user_module_implements_alter(array &$implementations, string $ho
   }
 }
 
-/**
- * Implements hook_user_logout().
- */
-function joinup_user_user_logout(AccountInterface $account): void {
-  /** @var \Drupal\joinup_core\JoinupSwitcherInterface $switcher */
-  $switcher = \Drupal::service('joinup_core.switcher');
-  /** @var \Drupal\Core\Cache\CacheTagsInvalidatorInterface $cacheTagsInvalidator */
-  $cacheTagsInvalidator = \Drupal::service('cache_tags.invalidator');
-  $logger = \Drupal::logger('joinup_user');
-
-  if ($account->hasPermission('enable/disable config readonly') &&
-    !$switcher->isEnabled('config-readonly')) {
-    $switcher->enable('config-readonly');
-    $logger->info('Config read-only mode has been restored/enabled.');
-    $cacheTagsInvalidator->invalidateTags(['joinup_user:read_only_config']);
-  }
-}
-
 /**
  * Implements hook_entity_base_field_info().
  */
diff --git a/web/modules/custom/joinup_user/joinup_user.permissions.yml b/web/modules/custom/joinup_user/joinup_user.permissions.yml
deleted file mode 100644
index 491ef3dd1d7f95799e7889eb8615c97bbbab8543..0000000000000000000000000000000000000000
--- a/web/modules/custom/joinup_user/joinup_user.permissions.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-enable/disable config readonly:
-  title: 'Enable/disable config readonly'
diff --git a/web/modules/custom/joinup_user/src/Plugin/Block/WarningMessageBlock.php b/web/modules/custom/joinup_user/src/Plugin/Block/WarningMessageBlock.php
index fbff730abb1410298bcc3c221be7f18af319615f..eb54e480d4b82cbacf08db98ca397c8c9ed8ed12 100644
--- a/web/modules/custom/joinup_user/src/Plugin/Block/WarningMessageBlock.php
+++ b/web/modules/custom/joinup_user/src/Plugin/Block/WarningMessageBlock.php
@@ -11,7 +11,7 @@
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
-use Drupal\joinup_core\JoinupSwitcherInterface;
+use Drupal\joinup_core\ConfigReadOnlyInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -28,7 +28,7 @@ public function __construct(
     array $configuration,
     string $pluginId,
     mixed $pluginDefinition,
-    protected JoinupSwitcherInterface $fileConfigReadOnly,
+    protected ConfigReadOnlyInterface $fileConfigReadOnly,
   ) {
     parent::__construct($configuration, $pluginId, $pluginDefinition);
   }
@@ -41,7 +41,7 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('joinup_core.switcher')
+      $container->get('joinup_core.file_config_read_only')
     );
   }
 
@@ -53,17 +53,12 @@ public function build(): array {
       $this->t('You are working on production. Please, be extra cautious!'),
     ];
 
-    if (!$this->fileConfigReadOnly->isEnabled('config-readonly')) {
-      $warnings[] = $this->t('Config readonly is disabled!');
-    }
-
     $build['content'] = [
       '#theme' => 'status_messages',
       '#message_list' => [
         'warning' => $warnings,
       ],
     ];
-    $build['#cache']['tags'][] = 'joinup_user:read_only_config';
 
     return $build;
   }