# README
OpenTofu key providers
[!WARNING] This file is not an end-user documentation, it is intended for developers. Please follow the user documentation on the OpenTofu website unless you want to work on the encryption code.
This folder contains the interface that key providers must implement in order to work with OpenTofu. Please read this document carefully if you intend to work on a key provider.
What are key providers?
Key providers in OpenTofu are responsible for integrating various key-management systems or key derivation (passphrase) functions. They consist of 3 components:
- The descriptor provides a unique ID and a struct with HCL tags to read the configuration into.
- The configuration is a struct OpenTofu parses the user-supplied configuration into. The
Build
function on this struct creates the key provider itself. - The key provider is responsible for creating one encryption key and one decryption key. It receives stored metadata and must return similar metadata in the result.
What is metadata?
Some key providers need to store data alongside the encrypted data, such as the salt, the hashing function name, the key length, etc. The key provider can use this metadata to recreate the exact same key for decryption as it used for encryption. However, the key provider could also provide a different key for each encryption and decryption, allowing for a quick rotation of encryption parameters.
[!WARNING] The metadata is bound to the key provider name. In order words, if you change the key provider name, OpenTofu will be unable to decrypt old data.
Implementing a key provider
When you implement a key provider, take a look at the static key provider as a template. You should never use this provider in production because it exposes users to certain weaknesses in some encryption methods, but it is a simple example for the structure.
Testing your provider (do this first!)
Before you even go about writing a key provider, please set up the compliance tests. You can create a single test case that calls compliancetest.ComplianceTest
. This test suite will run your key provider through all important compliance tests and will make sure that you are not missing anything during the implementation.
Implementing the descriptor
The descriptor is very simple, you need to implement the Descriptor
interface in a type. (It does not have to be a struct.) However, make sure that the ConfigStruct
always returns a struct with hcl
tags on it. For more information on the hcl
tags, see the gohcl documentation.
The config struct
Next, you need to create a config structure. This structure should hold all the fields you expect a user to fill out. This must be a struct, and you must add hcl
tags to each field you expect the user to fill out.
Additionally, you must implement the Build
function described in the Config
interface. You can take a look at static/config.go for an example on implementing this.
The metadata
The metadata can be anything as long as it's JSON-serializable, but we recommend using a struct for future extensibility. If you do not need metadata, simply use nil
.
Think about what data you will need to decrypt data. For example, the user may change the key length in a key derivation function, but you still need the old key length to decrypt. Hence, it needs to be part of the metadata.
[!WARNING] The metadata is stored unencrypted and unauthenticated. Do not use it to store sensitive details and treat it as untrusted as it may contain malicious data.
The key provider
The heart of your key provider is... well, your key provider. It has two functions: to create a decryption key and to create an encryption key. If your key doesn't change, these two keys can be the same. However, if you generate new keys every time, you should provide the old key as the decryption key and the new key as the encryption key. If you need to pass along data to help with recreating the decryption key, you can use the metadata for that.
The output
Your key provider must emit the keyprovider.Output
struct with the keys.