Skip to main content

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:

ProviderStorageUse CaseSecurity Level
ConfigurationDrupal databaseDevelopment onlyLow
FileExternal files (outside webroot)ProductionMedium
EnvironmentEnvironment variables (.env, Docker, DDEV)ProductionHigh
ExternalDedicated key management servicesEnterpriseVery 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:

  1. 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
  2. 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
  3. drupal/ai Configuration:

    // In settings.php or via UI $config['ai.settings']['openai_api_key'] = 'openai_api_key';

Anthropic (Claude) Integration

Setup Steps:

  1. 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
  2. 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
  3. Configuration:

    // In settings.php $config['ai.settings']['anthropic_api_key'] = 'anthropic_api_key';

Google Gemini Integration

Setup Steps:

  1. 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
  2. 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();

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:

  1. Create new key in Key Management
  2. Update environment variables or external service
  3. Update dependent configuration
  4. Test functionality
  5. 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

EnvironmentProviderMethodTool
Local DevConfiguration or FileDatabase or FilesSettings.php
DDEVEnvironment.ddev/config.yamlDDEV
DockerEnvironmentdocker-compose.ymlDocker Secrets
CI/CDEnvironmentCI VariablesGitLab CI Secrets
ProductionExternalManaged ServiceLockr/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

  1. Install dependencies:

    composer require drupal/ai drupal/key
  2. Create keys for each AI provider:

    Admin  Configuration  Key Management  Keys
    
  3. Configure AI module settings:

    Admin  Configuration  AI  AI Providers
    
  4. 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:

  1. Navigate to Admin Configuration Key Management Keys
  2. Verify key exists and ID matches
  3. Check key status (enabled/disabled)
  4. 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:

  1. Verify Lockr API key in settings
  2. Check firewall/network access to Lockr
  3. Test API endpoint
  4. Check Lockr account status

Additional Resources

Drupal.org Documentation

AI Module Integration

  • 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:

  1. Three-part architecture: Key Types, Providers, and Inputs
  2. Multiple storage options: Configuration (dev), File, Environment (prod), External (enterprise)
  3. AI provider integration: OpenAI, Anthropic, Google Gemini, and 45+ others
  4. Security first: File permissions, RBAC, rotation strategies, no hardcoding
  5. Development-friendly: DDEV, Docker, and .env support
  6. 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.