diff --git a/includes/include.drupalci.main.yml b/includes/include.drupalci.main.yml
index 30a7b7189db1fb04c80f2ddc3ddd2c21fa2edd3a..953ba7340d6f4e155b33b76e107be81d2bffe349 100644
--- a/includes/include.drupalci.main.yml
+++ b/includes/include.drupalci.main.yml
@@ -42,6 +42,14 @@
       echo -e "\e[0Ksection_end:`date +%s`:show_env_vars\r\e[0K"
     fi
 
+.add-composer-drupal-lenient: &add-composer-drupal-lenient
+  # Separately install and configure lenient plugin, if required.
+  - |
+    if [ "$LENIENT_ALLOW_LIST" != "0" ]; then 
+      composer global config --no-plugins allow-plugins.mglaman/composer-drupal-lenient true
+      composer global require mglaman/composer-drupal-lenient
+    fi
+
 .simpletest-db: &simpletest-db
   - |
     [[ $_TARGET_DB_TYPE == "sqlite" ]] && export SIMPLETEST_DB=sqlite://localhost/sites/default/files/db.sqlite
@@ -164,6 +172,7 @@ stages:
       - .
   script:
     - *show-environment-variables
+    - *add-composer-drupal-lenient
     # Expand the composer.json from the module with defaults to bring the Drupal project.
     - curl -OL https://git.drupalcode.org/$_GITLAB_TEMPLATES_REPO/-/raw/$_GITLAB_TEMPLATES_REF/scripts/expand_composer_json.php
     - php expand_composer_json.php
diff --git a/includes/include.drupalci.variables.yml b/includes/include.drupalci.variables.yml
index f0694de20b2fb874db5936dac1f9749ca18fda2e..597788c5c1c88d65b9757e9ebe8c69dd1ba73977 100644
--- a/includes/include.drupalci.variables.yml
+++ b/includes/include.drupalci.variables.yml
@@ -76,12 +76,12 @@ variables:
         value: "0"
         description: "Set to 1 to require the drupal/composer package that will make `drush composer` available. This variable only affects Drupal 7."
 
-################
-# Skip variables
-#
-# These variables allow you to skip specific jobs within the pipeline
-#
-################
+    ################
+    # Skip variables
+    #
+    # These variables allow you to skip specific jobs within the pipeline
+    #
+    ################
 
     SKIP_COMPOSER:
         value: "0"
@@ -142,6 +142,28 @@ variables:
         value: "0"
         description: "Set to 1 to opt in testing against the maximum/latest supported version of PHP for the current stable version of Drupal."
 
+    ################
+    # Lenient Variables
+    #
+    # These variables allow you to enable and configure support for the lenient plugin.
+    #
+    ################
+
+    LENIENT_ALLOW_LIST:
+        value: "0"
+        description: "Set to a comma-separated list of module names, that the lenient plugin should allow."
+
+    ################
+    # Composer Patch File
+    #
+    # These variables allow you to enable composer patches.
+    #
+    ################
+
+    COMPOSER_PATCHES_FILE:
+      value: "0"
+      description: 'Set the file name of the composer patches file that should be applied. That file must be a local file in the project, preferably located in the recommended "./.gitlab-ci/" subdirectory. The path should be relative to the module root or the recommended folder.'
+
     ################
     # We do not recommend overriding the following variables:
     #
diff --git a/scripts/expand_composer_json.php b/scripts/expand_composer_json.php
index 3b75887ec2655be13156052d70633c3f127e92a6..304a4f1d820f35746002bd87c6bef40632080343 100755
--- a/scripts/expand_composer_json.php
+++ b/scripts/expand_composer_json.php
@@ -48,6 +48,35 @@ $json_rich = merge_deep($json_default, $json_project);
 // module's values first, if defined.
 $json_rich['repositories'] = merge_deep($json_project['repositories'] ?? [], $json_default['repositories'] ?? []);
 
+// Add allowed modules for the lenient plugin if defined.
+$lenient_allow_list = getenv('LENIENT_ALLOW_LIST');
+if ($lenient_allow_list) {
+  if (!isset($json_rich['extra']['drupal-lenient']['allowed-list'])) {
+    $json_rich['extra']['drupal-lenient']['allowed-list'] = [];
+  }
+  foreach (explode(',', $lenient_allow_list) as $module_name) {
+    $json_rich['extra']['drupal-lenient']['allowed-list'][] = 'drupal/' . trim($module_name);
+  }
+}
+
+// Add a composer patch file if defined.
+$composer_patches_file = getenv('COMPOSER_PATCHES_FILE');
+if ($composer_patches_file) {
+  if (is_file($composer_patches_file) && file_exists($composer_patches_file)) {
+    $json_rich['extra']['patches-file'] = $composer_patches_file;
+  }
+  elseif (is_file('./.gitlab-ci/' . $composer_patches_file) && file_exists('./.gitlab-ci/' . $composer_patches_file)) {
+    $json_rich['extra']['patches-file'] = './.gitlab-ci/' . $composer_patches_file;
+  }
+  elseif (parse_url($composer_patches_file, PHP_URL_SCHEME)) {
+    $json_rich['extra']['patches-file'] = $composer_patches_file;
+  }
+  else {
+    print "Patch file is not valid!";
+    exit(1);
+  }
+}
+
 // Remove empty top-level items.
 $json_rich = array_filter($json_rich);
 file_put_contents(empty(getenv('COMPOSER')) ? $path : getenv('COMPOSER'), json_encode($json_rich, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT));