PHP Authentication Shield
Creates a simple HTTP basic authentication shield to protect Drupal sites from unauthorized access, treating the site as a "walled garden".
shield
Install
composer require 'drupal/shield:8.x-1.8'
composer require 'drupal/shield:8.x-1.6'
Overview
Shield is a PHP authentication module that creates a simple HTTP basic authentication shield for Drupal sites. It protects your website by requiring visitors to enter a username and password before they can access any content. This is particularly useful for protecting development, staging, or pre-launch sites from public access while still allowing authorized team members to work on the site.
The module intercepts all incoming HTTP requests through a middleware layer that runs before Drupal's page caching, ensuring that even cached pages cannot be accessed without proper authentication. Shield supports multiple credential storage methods including built-in configuration, integration with the Key module for secure password storage, and multi-value key support for storing both username and password in a single secure key.
Shield provides extensive exception handling capabilities allowing administrators to bypass authentication based on various criteria including command-line access (Drush, cron), specific IP addresses or ranges, HTTP request methods (useful for CORS), domain names (allowing front-office access while protecting back-office), and specific paths (with both include and exclude modes). A debug header feature helps administrators troubleshoot why authentication is or isn't being prompted in specific scenarios.
Features
- HTTP basic authentication protection for entire Drupal site with configurable username and password
- Multiple credential provider options: built-in Shield storage, Key module integration, or multi-value Key module for enhanced security
- Command-line interface (CLI) exception to allow Drush, cron, and other command-line operations without authentication
- IP-based allowlist supporting individual IP addresses, IPv6 addresses, and CIDR network ranges for bypassing authentication
- HTTP method allowlist to exclude specific request methods (GET, POST, OPTIONS, etc.) from authentication - useful for CORS preflight requests
- Domain-based exceptions to allow specific hostnames to bypass authentication - ideal for multi-domain setups where front-office should be public
- Path-based filtering with exclude mode (protect all except listed paths) or include mode (protect only listed paths) using pattern matching
- Debug header (X-Shield-Status) providing detailed status information including: pending, authenticated, disabled, skipped (cli), skipped (ip), skipped (http method), skipped (subrequest), skipped (domain), skipped (path)
- Customizable authentication message displayed in the browser's login dialog with support for [user] and [pass] tokens
- Integration with Drupal's Basic Auth module with automatic header cleanup to prevent authentication conflicts
- Configuration override support via settings.php for environment-specific settings (enable shield on staging, disable on production)
- Migration support from Drupal 7 Shield module with automatic configuration transformation
- High-priority HTTP middleware (priority 250) ensuring shield runs before page caching to prevent cached pages from being served to unauthenticated users
- Cache tag integration ensuring proper cache invalidation when Shield configuration changes
- Path alias support ensuring path-based exceptions work with both internal paths and URL aliases
- Multi-language support with automatic language prefix stripping for path matching
Use Cases
Protecting a Development or Staging Site
Shield is commonly used to protect development and staging environments from public access and search engine indexing. Enable Shield on these environments with a shared username and password that the development team knows. Use settings.php configuration overrides to automatically disable Shield on production while keeping it enabled on other environments. For example: $config['shield.settings']['shield_enable'] = (getenv('ENVIRONMENT') !== 'production');
Multi-Domain Setup with Protected Back-Office
For sites with separate front-office (public) and back-office (admin) domains, use Shield's domain allowlist to keep the public-facing domain accessible while protecting the administrative domain. Add your public domain (e.g., www.example.com) to the Allowlist Domains field, and all requests to admin.example.com will require authentication.
API Endpoints That Require CORS Support
When your Drupal site serves as a backend API with CORS requirements, browsers send OPTIONS preflight requests before actual API calls. Add 'OPTIONS' to the HTTP method allowlist to allow these preflight requests to pass without authentication, while still protecting actual data requests.
Protecting Specific Paths Only
Use Include mode with specific paths to protect only certain areas of your site. For example, protect only /admin/* paths by setting Path Method to 'Include' and adding /admin/* to the Paths field. All other pages will be publicly accessible.
Allowing Automated Services
Configure IP allowlist with your CI/CD server IPs, monitoring service IPs, or CDN edge server IPs to allow automated access without credentials. For example, add your Jenkins server IP to allow automated deployments without authentication prompts.
Secure Credential Storage with Key Module
For organizations with strict security requirements, use Shield with the Key module to store credentials securely. Configure a file-based or environment-variable-based key to store credentials outside of the database, ensuring that database dumps don't expose Shield passwords.
Tips
- Use settings.php configuration overrides ($config['shield.settings']['shield_enable'] = FALSE;) to disable Shield on production while keeping it enabled on staging environments.
- When using Shield with Varnish or other reverse proxy caching, avoid using IP allowlists as cached responses may be served to non-allowed IPs.
- The [user] and [pass] tokens in the authentication message are no longer displayed by most modern browsers for security reasons, so don't rely on them for communicating credentials.
- For CI/CD pipelines, configure the CI server's IP in the allowlist or use CLI exception to allow automated deployments without authentication.
- Regularly rotate Shield credentials, especially when team members leave the project or the credentials may have been shared beyond the intended audience.
- Use the Key module with environment variables or secure file storage to keep credentials out of the database and configuration exports.
- Test path patterns using the debug header to confirm which paths are protected before deploying to production.
Technical Details
Admin Pages 1
/admin/config/system/shield
Configure HTTP basic authentication protection for your Drupal site. This page allows administrators to enable/disable Shield protection, set up authentication credentials, and configure various exception rules to control when authentication should be bypassed.
Permissions 1
Hooks 1
hook_help
Implements hook_help to provide help text for the Shield module on the help page.
Troubleshooting 5
Enable the debug header option and check the X-Shield-Status response header. Common causes include: IP being in the allowlist, CLI exception being active, path being excluded, HTTP method being allowed, or domain being in the allowlist. The header will show exactly why Shield was skipped.
This occurs when basic_auth module is enabled and Shield credentials match a pattern that basic_auth tries to validate. Ensure 'Unset basic auth headers' is checked in Shield settings to prevent basic_auth from interfering with Shield authentication.
Shield automatically resolves path aliases to their internal paths for matching. Ensure your path patterns use the actual URL paths as they appear to visitors, not the internal node/X paths.
IP allowlisting may cause issues with reverse proxies as responses could be cached and served to non-allowed IPs. Avoid using IP allowlists when using reverse proxy caching. Configure your CDN to forward the X-Forwarded-For header and ensure Drupal is configured to trust your proxy.
Verify the credential provider setting matches where your credentials are stored. If using Key module, ensure the key entity exists and contains valid credentials. Check for typos in username/password.
Security Notes 7
- HTTP basic authentication credentials are transmitted in base64 encoding (not encryption). Always use HTTPS when Shield is enabled to protect credentials in transit.
- Shield credentials are stored in plain text in Drupal configuration by default. For enhanced security, use the Key module integration to store credentials outside the database.
- The IP allowlist feature can be bypassed if an attacker can spoof the client IP address. This is more likely in environments without proper proxy configuration.
- Shield is not a substitute for proper access control. It provides a simple barrier but should not be used to protect truly sensitive data.
- Avoid using the same credentials for Shield that are used for other services or user accounts.
- When exporting configuration, be aware that Shield credentials in the 'shield' provider mode will be included in the export. Use the Key module for sensitive environments.
- The authentication message may leak the username and password if [user] and [pass] tokens are used, though modern browsers typically don't display this message.