Configuration Read-only mode
Locks Drupal configuration to prevent changes in the admin UI while still allowing config imports via Drush.
config_readonly
Install
composer require 'drupal/config_readonly:8.x-1.0'
Overview
The Configuration Read-only mode module provides a security layer that blocks all Drupal configuration changes through the administrative interface. When activated, any attempt to modify configuration via the UI will be blocked, and users will see a warning message explaining that the configuration is read-only.
The primary use case is for production environments where configuration should be locked and only modified through validated config imports from a testing environment using Drush. This ensures that production configuration changes are properly tested and version-controlled before deployment.
The module works by decorating Drupal's core config storage service, intercepting all write operations (write, delete, rename, deleteAll) and throwing an exception if the read-only setting is enabled. It intelligently allows config imports via Drush's ConfigImporter and database updates through update.php to proceed normally.
A flexible whitelist system allows specific configurations to remain editable even when read-only mode is active, supporting both exact matches and wildcard patterns.
Features
- Blocks all configuration write operations when read-only mode is enabled via $settings['config_readonly'] = TRUE in settings.php
- Automatically disables submit buttons on all configuration forms (ConfigFormBase, ConfigEntityListBuilder, ConfigTranslationFormBase) and displays warning messages
- Allows Drush config imports to proceed normally by detecting the ConfigImporter lock
- Allows database updates via update.php to modify configuration as needed
- Supports whitelist patterns for exempting specific configurations from read-only protection using exact matches or wildcards (e.g., 'system.performance' or 'block.block.*')
- Whitelist patterns can be defined in settings.php or via hook_config_readonly_whitelist_patterns()
- Blocks config single import form, module enable/disable forms, and user permissions form when active
- Displays status information on the Drupal status report page indicating whether read-only mode is active
- Supports conditional activation based on environment variables (e.g., only enable on production)
- Provides a custom event (ReadOnlyFormEvent) allowing other modules to customize which forms are marked read-only
Use Cases
Locking Production Configuration
The primary use case is to lock configuration on production servers. Add the following to your production settings.php to prevent any configuration changes through the admin UI while still allowing Drush config imports: $settings['config_readonly'] = TRUE;
Environment-Specific Configuration
Use environment variables to conditionally enable read-only mode only on production. Example: if (isset($_ENV['AH_SITE_ENVIRONMENT']) && $_ENV['AH_SITE_ENVIRONMENT'] === 'prod') { $settings['config_readonly'] = TRUE; } This is useful for Acquia, Platform.sh, or other hosting environments that set environment variables.
Allowing Specific Configurations
When certain configurations need to remain editable in production (e.g., performance settings or specific block placements), use whitelist patterns: $settings['config_readonly_whitelist_patterns'] = ['system.performance', 'block.block.header_*'];
UI-Only Protection
If you want to protect against UI changes but allow CLI changes (less secure but sometimes needed): if (PHP_SAPI !== 'cli') { $settings['config_readonly'] = TRUE; } Note: This is discouraged as it allows anyone with shell access to bypass protection.
File-Based Toggle
For emergency situations, you can base read-only status on a file's existence: if (!file_exists('/home/myuser/disable-readonly.txt')) { $settings['config_readonly'] = TRUE; } This allows quick disabling without code deployment by creating the toggle file.
Multi-Site Configuration
In multi-site setups, define read-only settings per site in each site's settings.php or use shared settings with site-specific overrides to control which sites have read-only configuration enabled.
Tips
- Always test your whitelist patterns on a non-production environment before deploying to production
- Use environment variables to conditionally enable read-only mode, making it easy to manage across different environments
- The module shows which configuration names would need to be whitelisted when a form is blocked - use this information to build your whitelist
- Consider using hook_config_readonly_whitelist_patterns() in a custom module instead of settings.php for more dynamic whitelist logic
- Remember that config imports and database updates are always allowed regardless of the read-only setting
- The ReadOnlyFormEvent can be used to implement custom logic for determining which forms should be read-only
- Whitelist patterns support wildcards (*) anywhere in the pattern - 'foo.*.bar' matches 'foo.baz.bar'
Technical Details
Hooks 1
hook_config_readonly_whitelist_patterns
Allows modules to provide whitelist patterns for configurations that should remain editable when read-only mode is active. Patterns support wildcards using the * character.
Troubleshooting 5
Enabling the module alone does not activate protection. You must add $settings['config_readonly'] = TRUE; to your settings.php file to activate read-only mode.
Config imports via Drush should work automatically as the module detects the ConfigImporter lock. If blocked, ensure you're using a standard config import command (drush config:import or drush cim) and not custom code that bypasses the ConfigImporter.
The module automatically allows database updates via the system.db_update route. If updates are blocked, ensure you're running updates through the standard update.php or drush updatedb methods.
Add the configuration name to the whitelist in settings.php: $settings['config_readonly_whitelist_patterns'] = ['config.name.here']; You can use wildcards like 'block.block.*' to match multiple configurations.
This warning indicates the module is installed but $settings['config_readonly'] is not set to TRUE in settings.php. Add the setting to activate protection.
Security Notes 5
- This module is covered by Drupal's security advisory policy
- The CLI-only mode (PHP_SAPI check) is discouraged as it allows anyone with shell or Drush access to modify configuration
- File-based toggles should use files outside the webroot to prevent web-based manipulation
- The module protects against UI changes but does not prevent configuration changes via custom code or direct database manipulation
- For maximum security, combine with proper file permissions on settings.php and restrict Drush/shell access to production servers