Using the Key Module to Store Secrets Outside of Drupal
Security is a paramount feature of any modern CMS. Drupal has a well defined authentication and RBAC (role based access control) system limiting the scope of what users can or cannot do. Soon we will even have PBAC (policy based access control) in Drupal core. But what about securing other things, like API tokens, SSL certificates or secrets that are used to authenticate with external services that enable features that require authorization?
Out of the box, all configuration data is exported to configuration files. Drupal is not aware by default what values are sensitive or secure by nature – what that means are that with add-on modules that collect API keys or authorization, those values could find their way into your configuration/database and code repository which poses a security risk of them leaking, potentially. You are only as secure as your weakest link, but fortunately this is easily solved in Drupal with the Key module.
The Key Module
The Key module for Drupal helps developers and site builders store their API tokens and sensitive keys in a more secure manner than storing in the default configuration metadata of Drupal. It also provides a simple UI to create and edit Key definitions in the admin which makes auditing or changing them a breeze without touching implementation code.
Some examples of where you would encounter this are:
- Secure certificates for SSO (single sign on) providers
- API tokens for third party service integration like Salesforce
- Credentials for SMTP mail servers
- Secure certificates that may be required in API requests with an HTTP client
- Proprietary in-house services that require authorization to use
The Key module easily meets these needs and offers four different ways of referencing secrets:
- Configuration – the default method, which exports raw values to configuration. Keys are tracked, but not secure. In lieu of anything else, this method is not advised, but still exists so you can manage your Keys in the admin.
- File – This method lets you store a secret in a file located on the web server outside of the web root where it cannot be publicly accessed. The file path is the only thing stored in the Key, and the Key module is responsible for retrieving the value behind the scenes when you need it.
- Environment variable – This method lets you assign an environment variable as having the secret value. Like the File method, the Key module is responsible for retrieving the value behind the scenes when you need it.
- External – This method allows you to reference secrets in third party providers via an API. Some examples of these types of services are Bitwarden, 1Password, Lockr, or similar. This method is considered the most secure, due to the layers of security those storage services provide.
Using the Key module
Using the key module is straightforward. Enabling the module adds a new section in the administrative section where you can create new Keys.
Most of the basic needs for Key types are covered out of the box, as indicated in the below image:
These serve most of the common use cases for types of Keys, but in the event where you need something different you can extend the Key module and create your own provider type to present additional options.
Here, I am setting the Key to be File based, and indicating the path on the server where it is located:
In that example, I am making use of the nobackup hidden directory available on Acquia hosting. Other providers may offer something similar. This location is not readable or discoverable by public means. The file above contains the raw value which is retrieved by the Key module when used.
Once I have created a Key, I can now reference it in modules who have integration with the Key:
Integrating your custom code with the Key module is easy. You may have code that collects an API token as a textfield, for example. The Key module provides a ‘key_select’ form element type that takes care of a lot of boilerplate which is simple to use:
$form['example_key'] = [ '#title' => $this->t('Stripe Development Account Key'), '#description' => $this->t('The account key to use for Stripe calls on the development instance.'), '#type' => 'key_select', '#key_filters' => ['type_group' => 'authentication'], '#empty_option' => $this->t('- Select -'), '#required' => TRUE, ];
The key_select form element automatically sets it as a select list with verbiage on where to create a new key if one is not listed. Additionally, we can use the key_filters parameter to limit what types of keys can be selected here for additional guardrails. In this example, I am only allowing ‘authentication’ type keys to limit options and prevent mistakes, like someone accidentally selecting an SSL certificate type.
This creates a really simple pattern to reuse throughout custom code to leverage all that the Key module has to offer.
If you have a secret that does not fit any of the predefined examples, there are plenty of add-ons to extend the Key module to support them. For example, the Key AWS module and the Asymmetric Key module add a way of storing AWS credentials or public/private key pairs, respectively. Like those modules, you can create your own provider to capture the data and requirements that you need.
Security is a difficult and ever-changing landscape to keep up with. Fortunately, the Key module can help alleviate some of those concerns and prevent secrets and tokens from proliferating throughout a codebase and mistakenly leaking, causing a security breach. Take advantage of the Key module today for Drupal.
Meet Me at Acquia Engage Boston 2023
If you’re attending Acquia Engage Boston on November 14 and 15th, don't miss Dries Buytaert's opening keynote on 11/14 at 1:30 where I will be on stage to talk about the OpenAI module built for Drupal. I'll also be at the Velir booth each day to discuss all things OpenAI, Drupal, or any other questions you may have!
Get the Drupal 10 Development Cookbook
The "Drupal 10 Development Cookbook" is co-authored by Matt Glaman and Kevin Quillen. They cover a wide variety of topics with hands-on examples so you can get up and running with Drupal 10 in no time. These topics include running Drupal locally with Docker-based tools, content modeling, creating custom modules, how to do automated testing, and migrating data into Drupal from various data sources. The book will help you understand how to develop and build modules just like the ones we talk about often at Velir.
You can pick up the book on Amazon as a physical copy or for Kindle.
Want to know more about how features like AI, ChatGPT, Recipes, and lightning-fast search can transform your Drupal site-building experience? Reach out.