drupal key management guide
drupal/key Management Guide
Overview
The Key module provides Drupal site administrators with a comprehensive system for managing sensitive credentials like API keys, encryption keys, and authentication tokens. It improves security by enabling flexible storage backends and preventing sensitive data from being hardcoded in configuration files or stored insecurely in the database.
Core Capabilities
- Flexible Storage: Store keys in configuration, files, environment variables, or external key management systems
- Central Management: Admin UI for defining and managing all API keys and credentials
- Type System: Specialized key types for different use cases (API keys, authentication tokens, encryption keys)
- Configuration Overrides: Replace any Drupal configuration value with a secure key
- Provider Integration: Support for external providers like Lockr, AWS Secrets Manager, and HashiCorp Vault
- Drupal Version Support: Works with Drupal 7, 8, 9, 10, and 11 with ongoing security updates
Key Module Architecture
The Key module uses a plugin-based architecture with three main plugin types working together:
1. Key Types
Key Types classify keys by purpose and handle validation, generation, and input methods.
Standard Key Types:
- API Key - For external API authentication (OpenAI, Anthropic, AWS, etc.)
- Authentication - For service authentication tokens
- Encryption - For symmetric encryption (AES, etc.)
- SSH Key - For SSH key pairs and certificates
- Database - For database connection credentials
Key Type Responsibilities:
- Validate key values
- Define input mechanisms (text field, textarea, file upload, or auto-generation)
- Filter keys by provider/storage backend
- Handle value formatting and encoding (Base64 for encryption keys)
2. Key Providers
Key Providers manage how and where keys are stored and retrieved.
Built-in Providers:
| Provider | Storage | Use Case | Security Level |
|---|---|---|---|
| Configuration | Drupal database | Development only | Low |
| File | External files (outside webroot) | Production | Medium |
| Environment | Environment variables (.env, Docker, DDEV) | Production | High |
| External | Dedicated key management services | Enterprise | Very High |
External Provider Support:
- Lockr (Supported) - Commercial managed key service for Drupal
- AWS Secrets Manager (Unstable) - AWS managed secrets with IAM integration
- HashiCorp Vault (Unstable) - Open-source secrets management tool
- AWS Dynamic Key Provider - Provisions temporary AWS IAM credentials via Vault
3. Key Inputs
Key Inputs define the user interface for submitting key values.
Input Types:
- Text Field - Single-line input (for short API keys)
- Textarea - Multi-line input (for certificates, SSH keys)
- File Upload - Upload key from file
- Generate - Auto-generate keys (for encryption keys)
- Base64 - Encode values as Base64 (for encryption keys)
AI Provider Key Management
The drupal/ai module requires the Key module for managing API credentials for AI providers. The AI module supports 48+ providers including:
OpenAI Integration
Setup Steps:
-
Create Key in UI:
- Navigate to: Admin Configuration Key Management Keys
- Click "Add Key"
- Key ID:
openai_api_key - Key Label:
OpenAI API Key - Key Type: API Key
- Key Provider: Environment (recommended for production)
- Provider Settings:
OPENAI_API_KEY
-
Environment Variable Setup:
# .env file OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxx # Docker compose environment: OPENAI_API_KEY: ${OPENAI_API_KEY} # DDEV ddev config --environment=OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxx -
drupal/ai Configuration:
// In settings.php or via UI $config['ai.settings']['openai_api_key'] = 'openai_api_key';
Anthropic (Claude) Integration
Setup Steps:
-
Create Key in UI:
- Navigate to: Admin Configuration Key Management Keys
- Click "Add Key"
- Key ID:
anthropic_api_key - Key Label:
Anthropic Claude API Key - Key Type: API Key
- Key Provider: Environment
- Provider Settings:
ANTHROPIC_API_KEY
-
Environment Variable Setup:
# .env file ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxx # Docker compose environment: ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY} # DDEV ddev config --environment=ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxx -
Configuration:
// In settings.php $config['ai.settings']['anthropic_api_key'] = 'anthropic_api_key';
Google Gemini Integration
Setup Steps:
-
Create Key:
- Key ID:
google_gemini_api_key - Key Label:
Google Gemini API Key - Key Type: API Key
- Key Provider: Environment
- Provider Settings:
GOOGLE_GEMINI_API_KEY
- Key ID:
-
Configuration:
$config['ai.settings']['google_gemini_api_key'] = 'google_gemini_api_key';
Supported AI Providers with Key Module
The following AI providers work with the Key module:
- Anthropic (Claude)
- AWS Bedrock
- Azure OpenAI
- Google Gemini
- Google Vertex AI
- Hugging Face
- OpenAI
- Amazee.io
- LangChain (multiple providers)
- Apple Intelligence
Storage Backends
Configuration Backend (Development)
Stores keys directly in Drupal configuration (database).
Advantages:
- Easy to set up
- No external files required
- Works in local development
Disadvantages:
- Keys visible in database exports
- Keys in version control if exported
- Not suitable for sensitive credentials
Usage:
// Retrieve key value $key = \Drupal::service('key.repository')->getKey('openai_api_key'); $value = $key->getKeyValue();
File Backend (Production)
Stores keys in files outside the webroot.
Advantages:
- Keys not in database
- Better separation of code and secrets
- File permissions control access
- Suitable for production
Disadvantages:
- File system access required
- Must ensure files outside webroot
- Backup/restore complexity
Setup:
# Create secure directory outside webroot mkdir -p /var/www/keys chmod 700 /var/www/keys # File permissions # Only webserver user can read chown www-data:www-data /var/www/keys chmod 600 /var/www/keys/*
Configuration:
// In Key UI: // Key Provider: File // Provider Settings: // - File location: /var/www/keys/openai.key // - File encoding: Plain text or Base64
Retrieve File Key:
$key = \Drupal::service('key.repository')->getKey('openai_api_key'); $value = $key->getKeyValue();
Environment Variables Backend (Recommended for Production)
Uses environment variables from .env, Docker, DDEV, or Lando.
Advantages:
- Keys not stored in files/database
- Cloud-native (Docker, Kubernetes)
- CI/CD friendly
- Secrets management integration
- DDEV/Lando support
- No file system writes
Disadvantages:
- Requires environment variable setup
- Child processes inherit variables
Setup in Different Environments:
Local Development (.env file):
# .env file at project root OPENAI_API_KEY=sk-proj-xxxxxxxxxxxxxxxxxxxxx ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxxxxxxxxxxx GOOGLE_GEMINI_API_KEY=xxxxxxxxxxxxxxxxxxx
DDEV Setup:
# .ddev/config.yaml environment_variables: web: OPENAI_API_KEY: sk-proj-xxxxxxxxxxxxxxxxxxxxx ANTHROPIC_API_KEY: sk-ant-xxxxxxxxxxxxxxxxxxxxx
Docker Compose:
services: web: environment: OPENAI_API_KEY: ${OPENAI_API_KEY} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
Lando Setup:
# .lando.yml services: web: overrides: environment: OPENAI_API_KEY: ${OPENAI_API_KEY} ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
Key Configuration in Drupal UI:
- Key ID:
openai_api_key - Key Type: API Key
- Key Provider: Environment
- Provider Settings:
OPENAI_API_KEY
Retrieve Environment Key:
$key = \Drupal::service('key.repository')->getKey('openai_api_key'); $value = $key->getKeyValue(); // Reads from $_ENV['OPENAI_API_KEY']
External Key Management (Enterprise)
Integrates with dedicated key management services.
Lockr (Commercial, Supported)
- Managed key service for Drupal
- Compliance-ready (SOC 2, HIPAA, PCI)
- Automatic key rotation
- Audit logging
Installation:
composer require drupal/lockr
Configuration:
// Enable Lockr provider $config['key.provider.lockr']['api_key'] = 'your-lockr-api-key';
AWS Secrets Manager (Commercial, Unstable)
- AWS managed secrets service
- IAM integration for access control
- Automatic rotation
- CloudWatch monitoring
Setup:
# Install AWS Secrets Manager provider composer require drupal/aws_secretsmanager
HashiCorp Vault (Open Source, Unstable)
- Enterprise secrets management
- Dynamic secrets generation
- Automatic credential rotation
- Multi-cloud support
Setup:
composer require drupal/vault
Configuration:
$config['key.provider.vault']['url'] = 'https://vault.example.com:8200'; $config['key.provider.vault']['token'] = 'hvs.xxxxxxxxxxxxxxxxxxxxx'; $config['key.provider.vault']['auth_method'] = 'token';
Security Best Practices
1. Key Rotation
Manual Rotation:
- Regularly rotate API keys (quarterly recommended)
- Use external provider for automatic rotation
- Update all dependent services simultaneously
Rotation Process:
- Create new key in Key Management
- Update environment variables or external service
- Update dependent configuration
- Test functionality
- Remove old key
2. Access Control and Permissions
Drupal Permissions:
// Key Management permissions 'administer keys' // Create, edit, delete keys 'view key values' // See actual key values in UI 'use key values' // Retrieve keys via API (automatically granted)
Restrict to trusted roles:
// In admin UI or code: // Only Site Administrators can create/edit keys // Developers cannot view actual key values // Modules access keys via service, not directly
File System Permissions:
# Key files should only be readable by web server chmod 600 /var/www/keys/* chown www-data:www-data /var/www/keys/* # Directory should not be world-readable chmod 700 /var/www/keys
3. Key Storage Strategy by Environment
| Environment | Provider | Method | Tool |
|---|---|---|---|
| Local Dev | Configuration or File | Database or Files | Settings.php |
| DDEV | Environment | .ddev/config.yaml | DDEV |
| Docker | Environment | docker-compose.yml | Docker Secrets |
| CI/CD | Environment | CI Variables | GitLab CI Secrets |
| Production | External | Managed Service | Lockr/Vault/AWS |
4. Preventing Key Exposure
Do NOT:
- Commit .env files to Git
- Store keys in code
- Log key values
- Expose keys in error messages
- Use insecure file permissions
- Share keys via unencrypted channels
Do:
- Use environment variables
- Use external key management
- Implement RBAC for key access
- Audit key access
- Use version-pinned dependencies
- Enable Secret Detection in CI/CD
Git Security:
# .gitignore entries .env .env.local .env.*.local /keys/* !/.env.example
5. Encryption Key Best Practices
For Encryption Keys:
// Use Base64 encoding in Key UI // Key Type: Encryption // Input Type: Generate (auto-generate with openssl_random_pseudo_bytes) // Encoding: Base64 // Store in file or environment // Never in configuration/database
Key Format:
// Generated key should be binary and Base64 encoded // Example: HFYu9IKIuaqEaLXEZdR8KNvjWq8sLhCxJ3qPj7sKiLs= // Drupal encryption expects: // - 256-bit keys for AES-256 // - 128-bit keys for AES-128 // - Base64 encoded format
6. Configuration Overrides
Use Key module to override sensitive configuration values:
// Instead of storing in database $config['some_module.settings']['api_key'] = 'sk-xxx'; // Override with Key module $config['some_module.settings']['api_key'] = 'key:openai_api_key'; // Drupal automatically retrieves the key value // Keys prefixed with 'key:' are resolved before use
Configuration Override Example:
// In settings.php $config['ai.settings']['openai_api_key'] = 'key:openai_api_key'; $config['ai.settings']['anthropic_api_key'] = 'key:anthropic_api_key'; // Drupal automatically resolves: // 'key:openai_api_key' -> actual API key from Key storage
Integration with drupal/ai
The AI module requires the Key module and uses it for storing provider API keys.
Setup Flow
-
Install dependencies:
composer require drupal/ai drupal/key -
Create keys for each AI provider:
Admin Configuration Key Management Keys -
Configure AI module settings:
Admin Configuration AI AI Providers -
Select keys in provider configuration:
- Each provider shows available keys
- Select appropriate key for each service
- Test connectivity
AI Provider Configuration Example
Settings for OpenAI:
// In AI module configuration $config['ai.settings']['providers']['openai'] = [ 'enabled' => TRUE, 'api_key' => 'openai_api_key', // Key ID from Key module 'model' => 'gpt-4', 'temperature' => 0.7, ];
Settings for Anthropic:
$config['ai.settings']['providers']['anthropic'] = [ 'enabled' => TRUE, 'api_key' => 'anthropic_api_key', 'model' => 'claude-3-sonnet-20240229', 'temperature' => 0.7, ];
Settings for Google Gemini:
$config['ai.settings']['providers']['google_gemini'] = [ 'enabled' => TRUE, 'api_key' => 'google_gemini_api_key', 'model' => 'gemini-pro', ];
Retrieval in AI Module Code
// AI module internally retrieves keys $key_manager = \Drupal::service('key.repository'); $key = $key_manager->getKey('openai_api_key'); $api_key = $key->getKeyValue(); // Used for API calls $client = new OpenAI\Client(['api_key' => $api_key]);
Vector Database Key Management
For AI Search with vector databases:
// Vector DB keys are also managed via Key module $config['ai.settings']['vector_db'] = [ 'provider' => 'pinecone', 'api_key' => 'pinecone_api_key', // Key module reference ]; // Supported vector databases: // - Milvus // - Pinecone // - Postgres (pgvector) // - Azure AI Search // - SQLite (local)
Code Examples
Retrieving Keys in Custom Code
Basic Key Retrieval:
<?php namespace Drupal\my_module\Service; use Drupal\key\KeyRepositoryInterface; class MyAiService { protected $keyRepository; public function __construct(KeyRepositoryInterface $key_repository) { $this->keyRepository = $key_repository; } public function getOpenAiKey() { $key = $this->keyRepository->getKey('openai_api_key'); if ($key) { return $key->getKeyValue(); } return NULL; } } ?>
Service Definition:
# my_module.services.yml services: my_module.ai_service: class: Drupal\my_module\Service\MyAiService arguments: - '@key.repository'
Using in a Form:
<?php namespace Drupal\my_module\Form; use Drupal\Core\Form\ConfigFormBase; use Drupal\Core\Form\FormStateInterface; class MyAiConfigForm extends ConfigFormBase { public function buildForm(array $form, FormStateInterface $form_state) { $form['api_provider'] = [ '#type' => 'select', '#title' => $this->t('API Provider'), '#options' => [ 'openai' => 'OpenAI', 'anthropic' => 'Anthropic', 'google' => 'Google Gemini', ], ]; $form['api_key'] = [ '#type' => 'key_select', '#title' => $this->t('API Key'), '#key_filters' => ['type' => 'api_key'], ]; return parent::buildForm($form, $form_state); } } ?>
Multivalue Keys:
<?php // For keys with multiple values (username, password, etc.) $key = $this->keyRepository->getKey('database_credentials'); $values = $key->getKeyValues(); $username = $values['username'] ?? NULL; $password = $values['password'] ?? NULL; ?>
Key Existence Check:
<?php // Check if key exists before using $key = $this->keyRepository->getKey('openai_api_key'); if ($key && !empty($key->getKeyValue())) { // Safe to use key $api_key = $key->getKeyValue(); } else { // Handle missing key \Drupal::logger('my_module')->warning('OpenAI API key not configured'); } ?>
Creating Keys Programmatically
Create a new key:
<?php use Drupal\key\Entity\Key; // Create key entity $key = Key::create([ 'id' => 'my_api_key', 'label' => 'My API Key', 'description' => 'API key for external service', 'key_type' => 'api_key', 'key_provider' => 'environment', 'key_input' => 'text_field', 'key_provider_settings' => [ 'envrionment_variable' => 'MY_API_KEY', ], ]); $key->save(); ?>
Store key value in file provider:
<?php $key = Key::create([ 'id' => 'my_encryption_key', 'label' => 'Encryption Key', 'key_type' => 'encryption', 'key_provider' => 'file', 'key_input' => 'generate', 'key_provider_settings' => [ 'file_location' => '/var/keys/encryption.key', ], ]); $key->save(); ?>
Handling Multiple Providers
Use different providers per environment:
<?php // In settings.php or settings.environment.php // Production: Use external service if ($_ENV['ENVIRONMENT'] === 'production') { $config['key.provider.lockr']['api_key'] = 'xxx'; } // Development: Use environment variables elseif ($_ENV['ENVIRONMENT'] === 'development') { // Keys come from .env file } // Local: Use configuration else { // Keys in database for local testing } ?>
Troubleshooting
Key Not Found
Issue: "Key 'my_key' not found" error
Solution:
- Navigate to Admin Configuration Key Management Keys
- Verify key exists and ID matches
- Check key status (enabled/disabled)
- Verify provider credentials (for external providers)
Environment Variable Not Read
Issue: Key module not reading environment variables
Solution:
# Verify variable is set echo $OPENAI_API_KEY # Check PHP environment php -r "echo getenv('OPENAI_API_KEY');" # For DDEV ddev ssh "echo \$OPENAI_API_KEY" # Check key configuration # Admin Configuration Key Management Keys Edit # Verify provider is "Environment" # Verify variable name matches
File Provider Permission Error
Issue: "Permission denied" reading key file
Solution:
# Check file exists ls -la /var/keys/ # Fix permissions chmod 600 /var/keys/* chown www-data:www-data /var/keys/* # Verify web server user ps aux | grep 'apache\|nginx\|php' | head -1 # Test read sudo -u www-data cat /var/keys/openai.key
Lockr Connection Error
Issue: Cannot connect to Lockr service
Solution:
- Verify Lockr API key in settings
- Check firewall/network access to Lockr
- Test API endpoint
- Check Lockr account status
Additional Resources
Drupal.org Documentation
- Key Module Project Page
- Key Module Documentation
- Key Concepts and Terminology
- Key Developer Guide
- Supported Modules
AI Module Integration
- Drupal AI Module
- AI Provider Integration Guides
- Vector Database Configuration
Related Modules
- Encrypt Module - Uses keys for field-level encryption
- Lockr - Commercial key management service
- AWS Secrets Manager - AWS secrets integration
- Vault - HashiCorp Vault integration
External Tools
- DDEV - Local development with environment variables
- Docker Compose - Container secret management
- GitLab CI - Protected CI/CD variables
- Lando - Local development environment
Summary
The drupal/key module is essential for secure API key management in Drupal projects using AI providers. Key points:
- Three-part architecture: Key Types, Providers, and Inputs
- Multiple storage options: Configuration (dev), File, Environment (prod), External (enterprise)
- AI provider integration: OpenAI, Anthropic, Google Gemini, and 45+ others
- Security first: File permissions, RBAC, rotation strategies, no hardcoding
- Development-friendly: DDEV, Docker, and .env support
- Enterprise-ready: Lockr, AWS Secrets Manager, and Vault integration
Use the Environment Provider for most production cases, and External Providers (Lockr/Vault) for enterprise deployments requiring compliance and automatic rotation.