- State
- State and Plan Encryption
State and Plan Encryption
OpenTofu supports encrypting state and plan files at rest, both for local storage and when using a backend. In addition, you can also use encryption with the terraform_remote_state
data source. This page explains how to set up encryption and what encryption method is suitable for which use case.
General guidance and pitfalls (please read)
When you enable encryption, your state and plan files become unrecoverable without the appropriate encryption key. Please make sure you read this section carefully before enabling encryption.
What does encryption protect against?
When you enable encryption, OpenTofu will encrypt state data at rest. If an attacker were to gain access to your state file, they should not be able to read it and use the sensitive values (e.g. access keys) contained in the state file.
However, encryption does not protect against data loss (your state file getting damaged) and it also does not protect against replay attack (an attacker using an older state or plan file and tricking you into running it). Additionally, OpenTofu does not and cannot protect the sensitive values in the state file from the person running the tofu
command.
What precautions do I need to take?
When you enable encryption, consider who needs access to your state file directly. If you have more than a very small number of people with access needs, you may want to consider running your production plan
and apply
runs from a continuous integration system to protect both the encryption key and the sensitive values in your state.
You will also need to decide what kind of key you would like to use based on your security requirements. You can either opt for a static passphrase or you can choose a key management system. If you opt for a key management system, it is imperative to configure automatic key rotation for some encryption methods. This is particularly crucial if the encryption algorithm you choose has the potential to reach a point of 'key saturation', where the maximum safe usage limit of the key is approached, such as AES-GCM. You can find more information about this in the encryption methods section below.
Finally, before enabling encryption, please exercise your disaster recovery plan and make a temporary backup of your unencrypted state file. You should also have backups of your keys. Once you enable encryption, OpenTofu cannot read your state file without the correct key.
Migrating from an unencrypted state/plan
If you are migrating from an unencrypted state or plan file to an encrypted one, you may be surprised to find OpenTofu refusing to read your old data. This is a protection mechanism to prevent OpenTofu from reading manipulated, unencrypted data. Please see the initial setup section below for details.
Configuration
You can configure encryption in OpenTofu either by specifying the configuration in the OpenTofu code, or using the TF_ENCRYPTION
environment variable. Both solutions are equivalent and if you use both, OpenTofu will merge the two configurations, overriding any code-based settings with the environment ones.
The basic configuration structure looks as follows:
- Code
- Environment (Linux/UNIX shell)
- Environment (Powershell)
Once your data is encrypted, you should not rename key providers and methods in your configuration! The encrypted data stored in the backend contains metadata related to their specific names. Instead you should use a fallback block to handled changes to key providers.
You can use the JSON configuration syntax instead of HCL for encryption configuration.
If you use environment configuration, you can include the following code configuration to prevent unencrypted data from being written in the absence of an environment variable:
Key providers
PBKDF2
The PBKDF2 key provider allows you to use a long passphrase as to generate a key for an encryption method such as AES-GCM. You can configure it as follows:
Option | Description | Min. | Default |
---|---|---|---|
passphrase (required) | Enter a long and complex passphrase. | 16 chars. | - |
key_length | Number of bytes to generate as a key. | 1 | 32 |
iterations | Number of iterations. See this document for recommendations. | 200.000 | 600.000 |
salt_length | Length of the salt for the key derivation. | 1 | 32 |
hash_function | Specify either sha256 or sha512 to use as a hash function. sha1 is not supported. | N/A | sha512 |
AWS KMS
This key provider uses the Amazon Web Servers Key Management Service to generate keys. The authentication options are identical to the S3 backend excluding any deprecated options. In addition, please provide the following options:
Option | Description | Min. | Default |
---|---|---|---|
kms_key_id | Key ID for AWS KMS. | 1 | - |
key_spec | Key spec for AWS KMS. Adapt this to your encryption method (e.g. AES_256 ). | 1 | - |
The following example illustrates a minimal example:
Methods
AES-GCM
The only currently supported encryption method is AES-GCM. You can configure it in the following way:
The AES-GCM method needs 16, 24, or 32-byte keys. Please configure your key provider to supply keys with this exact length.
AES-GCM is a secure, industry-standard encryption algorithm, but suffers from "key saturation". In order to configure a secure setup, you should either use a key-derivation key provider (such as PBKDF2) with a long and complex passphrase, or use a key management system that automatically rotates keys regularly. Using short, static keys will degrade your encryption.
Key and method rollover
In some cases, you may want to change your encryption configuration. This can include renaming a key provider or method, changing a passphrase for a key provider, or switching key-management systems. OpenTofu supports an automatic rollover of your encryption configuration if you provide your old configuration in a fallback
block:
If OpenTofu fails to read your state or plan file with the new method, it will automatically try the fallback method. When OpenTofu saves your state or plan file, it will always use the new method and not the fallback.
Initial setup
When you first configure encryption, your state and plan files are unencrypted. OpenTofu, by default, refuses to read them because they could have been manipulated. To enable reading unencrypted data, you will have to specify an empty fallback block:
Rolling back encryption
Similar to the initial setup above, migrating to unencrypted state and plan files is also possible in a similar manner. You simply have to specify no method in the target block as follows:
Remote state data sources
You can also configure an encryption setup for projects using the terraform_remote_state
data source. This can be the same encryption setup as your main configuration, but you can also define a separate set of keys and methods. The configuration syntax looks as follows:
For specific remote states, you can use the following syntax:
myname
to target a data source in the main project with the given name.mymodule.myname
to target a data source in the specified module with the given name.mymodule.myname[0]
to target the first data source in the specified module with the given name.