For more information about this repository, visit the project page at https://www.drupal.org/project/key
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Jakob Perry f1ed8f44dc fix: #3576207 Fall back to $_ENV in the Environment key provider
Tools such as symfony/dotenv populate $_ENV without calling putenv() by
default, so getenv() in the Environment key provider does not see those
variables and keys that rely on them have no value.

Read the variable with getenv() first and fall back to $_ENV when getenv()
finds nothing. $_SERVER is not consulted, because it also carries
client-supplied request headers. A missing variable still yields NULL, so
config overrides that use the key are skipped rather than blanked.

Add a kernel test covering the fallback, getenv() taking precedence, form
validation, and the override being skipped when the variable is missing.
It carries #[Group] and #[RunTestsInSeparateProcesses] alongside @group,
and the PHPStan baseline lists the two attribute classes as missing on
Drupal 10 for it.
2026-11-02 22:02:29 -08:00
config/schema Issue #3564322 by mxr576, rajeshreeputra, alorenc: Config schema error: 'state_key' is not a supported key 2026-01-20 14:52:58 +00:00
src fix: #3576207 Fall back to $_ENV in the Environment key provider 2026-11-02 22:02:29 -08:00
tests fix: #3576207 Fall back to $_ENV in the Environment key provider 2026-11-02 22:02:29 -08:00
.deprecation-ignore.txt task: #3632542 Drupal 12 Compatibility. 2026-11-02 21:12:27 +00:00
.gitlab-ci.yml task: #3632542 Drupal 12 Compatibility. 2026-11-02 21:12:27 +00:00
.markdownlint.jsonc Issue #3332290 by jay jangid, rajeshreeputra, tyler36, tanuja bohra: Update README.md as per README.md format 2025-04-29 18:13:11 +00:00
composer.json Issue #3133528 by rlhawk, heddn, davisben: Add test for Drush commands 2024-06-25 23:32:08 +00:00
drush.services.yml Issue #3520663 by rajeshreeputra, japerry, ptmkenny: Fix PHPStan warnings 2025-05-29 22:24:50 +00:00
key.api.php Issue #3085963 by rlhawk: Fix coding standards violations 2019-10-04 14:41:40 -07:00
key.info.yml task: #3632542 Drupal 12 Compatibility. 2026-11-02 21:12:27 +00:00
key.install task: #3632542 Drupal 12 Compatibility. 2026-11-02 21:12:27 +00:00
key.links.action.yml Add foundation for key configuration overrides 2017-10-12 14:17:45 -07:00
key.links.menu.yml Issue #2635170 by rlhawk: Code cleanup and minor refactoring 2015-12-15 14:26:03 -08:00
key.links.task.yml Add foundation for key configuration overrides 2017-10-12 14:17:45 -07:00
key.module Issue #3031377 by Roman Dyn, Manuel Garcia, i-trokhanenko: Add module overview page 2019-05-25 21:55:49 -07:00
key.permissions.yml Add foundation for key configuration overrides 2017-10-12 14:17:45 -07:00
key.routing.yml fix: #3568554 Use entity access checks on all key entity routes 2026-11-02 21:36:30 -08:00
key.services.yml fix: #2985590 Invalidate the cached key value on save and delete 2026-11-02 21:43:04 -08:00
phpstan-baseline.neon fix: #3576207 Fall back to $_ENV in the Environment key provider 2026-11-02 22:02:29 -08:00
README.md docs: #3522907 Document how key configuration overrides work 2026-11-02 21:45:23 -08:00

Key

Key provides the ability to improve Drupal security by managing sensitive keys (such as API and encryption keys). It gives site administrators the ability to define how and where keys are stored, which allows the option of a high level of security and allows sites to meet regulatory or compliance requirements.

Examples of the types of keys that could be managed with Key are:

  • An API key for connecting to an external service, such as PayPal, MailChimp, Authorize.net, UPS, an SMTP mail server, or Amazon Web Services
  • A key used for encrypting data using the encrypt module

For a full description of the module, visit the project page.

Submit bug reports and feature suggestions, or track changes in the issue queue.

Table of Contents

Requirements

No additional modules or libraries are required, but other modules can extend the functionality of, or integrate with, Key.

Installation

Install as you would normally install a contributed Drupal module. For further information, see Installing Drupal Modules.

Configuration

Key provides an administration page where users with the "administer keys" permission can add, edit, and delete keys.

Key type

A key type can be selected for a key in order to indicate the purpose of the key. The following key types are included with Key:

  • Authentication: A generic key type to use for a password or API key that does not belong to any other defined key type. This is the default.
  • Encryption: Can be used for encrypting and decrypting data. This key type has a field for selecting a key size, which is used to validate the size of the key value.

Key types are native Drupal plugins, so new types can be defined easily.

Key provider

A key provider is the means by which the key value is stored and/or provided when needed. The following key providers are included with Key:

  • Configuration: Stores the key in Drupal configuration settings. The key value can be set, edited, and viewed through the administrative interface, making it useful during site development. However, for better security on production websites, keys should not be stored in configuration. Keys using the Configuration provider are not obscured when editing, making it even more important that this provider not be used in a production environment.

  • File: Stores the key in a file, which can be anywhere in the file system, as long as it's readable by the user that runs the web server. Storing the key in a file outside of the web root is generally more secure than storing it in the database.

  • Environment: Allows the key to be stored in an environmental variable. Enter only the variable's name in the key form; the value is read from the environment of the PHP process when the key is used. The variable must be visible to the PHP process that runs Drupal, so it is normally set outside of the codebase, for example:

    • Apache: SetEnv MY_API_KEY "value" in the virtual host configuration.
    • PHP-FPM: env[MY_API_KEY] = "value" in the pool configuration.
    • Hosting platforms and containers: the platform's environment variable or secrets settings, or the container's environment (for example web_environment in a DDEV project's .ddev/config.yaml for local development).

    If the key is also used from the command line (Drush, cron), the variable must be set in that environment as well. Avoid hard-coding the value with putenv() in a settings file that is committed to version control, since that stores the key alongside the code.

All three provider plugins support storing encryption keys with Base64 encoding.

Key providers are native Drupal plugins, so new providers can be defined easily.

Key input

When adding or editing a key, if the selected key provider accepts a key value, a key input is automatically selected, as defined by the key type, in order to submit a key value. The following key inputs are included with Key:

  • None: This input is used by default when the selected key provider does not accept a key value. The File key provider uses this input.
  • Text Field: This input provides a basic text field for submitting a key value. The Configuration key provider uses this input.
  • Textarea Field: This input is the same as the text field input, except it uses a textarea HTML element, so it's useful for longer keys, such as SSH keys.

The Text Field and Textarea Field input plugins support the submission of keys that are Base64-encoded.

Key inputs are native Drupal plugins, so new inputs can be defined easily.

Using a key

Creating a key will have no effect unless another module makes use of it. That integration would typically present itself to the end user in the form of a field that lists available keys and allows the user to choose one. This could appear, for instance, on the integrating module's configuration page.

Modules can add a key field to a form using the key_select API element, which behaves like a select element, but is populated with available keys as options.

$form['secret_key'] = [
  '#type' => 'key_select',
  '#title' => $this->t('Secret key'),
];

There are a couple of additional properties that can be used:

  • #key_filters An array of filters to apply to the list of keys. Filtering can be performed on any combination of key type, key provider, key type group, or storage method. Examples:

    • #key_filters = ['type' => 'mailchimp'] This would only display MailChimp keys.
    • #key_filters = ['provider' => 'file'] This would only display keys that use the File key provider.
    • #key_filters = ['type' => 'mailchimp', 'provider' => 'file'] This would only display MailChimp keys that use the File key provider.
    • #key_filters = ['type_group' => 'encryption'] This would only display keys that are of a key type that belongs to the 'encryption' group.
    • #key_filters = ['tags' => ['file', 'private']] This would only display keys whose definitions are tagged with file and private tags.
  • #key_description This is a boolean value that determines if information about keys is added to the element's description. It is TRUE by default and it prepends the description with the following text (with a link to the add key form), which can be disabled by setting #key_description to FALSE:

    Choose an available key. If the desired key is not listed, create a new key.

Modules can retrieve information about keys or a specific key value by making a call to the Key Manager service. It is best practice to inject the service into your own service, form, or controller.

The following examples assume the use of the \Drupal object for brevity, but the examples can be extrapolated to fit the use case of your module.

Get all key entities

Drupal::service('key.repository')->getKeys()

Get a single key entity

Drupal::service('key.repository')->getKey($key_id)

Get a key value

Drupal::service('key.repository')->getKey($key_id)->getKeyValue()

Get multiple values from a key

Drupal::service('key.repository')->getKey($key_id)->getKeyValues()

This will return an array of values. If the key does not support multiple values, the array will contain only one element.

Overriding configuration

Key can supply the value of any configuration item from a key, so that a secret used by another module (an API key in that module's settings, for example) does not have to be stored in configuration. This works with any module, without changes to its code.

Overrides are managed on the "Key Overrides" tab of the Configuration synchronization page (/admin/config/development/configuration/key-overrides), by users with the "administer key configuration overrides" permission. Each override names a configuration object, an item within it, and the key that provides the value.

Overrides use Drupal's configuration override system, the same mechanism as $config overrides in settings.php. With an override in place:

  • Code that reads configuration the normal way receives the key's value. The module that owns the setting does not need to know about Key:

    // Returns the value of the key, not the stored value.
    \Drupal::config('my_module.settings')->get('api_key');
    
  • The value stored in configuration is unchanged by the override. It is what configuration export, command-line tools such as config:get, and editable configuration (\Drupal::configFactory()->getEditable()) see.

When an override is created, "Clear the stored configuration value" is checked by default. It sets the stored value of the configuration item to NULL, so the secret is removed from the database and from configuration exports. The override continues to provide the key's value at runtime.

Things to be aware of:

  • Settings forms that extend ConfigFormBase load editable configuration, so an overridden field shows the stored value (empty, if it was cleared) rather than the key's value. Saving the form writes whatever is in the field back to configuration, but the override still takes precedence at runtime. Leave such fields empty, so the secret is not stored again.
  • If a key has no value (its provider returns NULL, for example because its file is missing or not readable by the web server), the override is skipped, and the stored configuration value is used. An empty string is a value, and does override the stored value.

Maintainers