Secret engines configuration section
OPTIONAL, but recommended!
Zentral can be configured to encrypt some DB fields that are considered secrets. This can prevent an attacker with a copy of the DB from using those secrets. By default, the noop
secret engine is configured. It is not a secure secret engine.
Multiple secret engines can be configured, but only one can be the default
one, i.e. the one used to encrypt new secret field values. Secret field values encrypted by another secret engine can still be decrypted, as long as it is still configured. This enables secret-engine migration (for example, from the noop
default engine to a more secure one).
The rewrap_secrets
Django management command is provided to loop over all the secret fields in the DB, and rewrap their encrypted values. It can be used to update the secrets after the default secret engine backend has been updated (AWS KMS key rotation, Fernet password rotation, …). It can also be used to migrate from one secret engine to a new one.
To define a secret engine, a backend configuration needs to be added to the base.json secret_engines
optional dictionary. The noop
secret engine is always configured, with the cleartext
backend, to allow operating without a secret_engines
configuration. A unique identifier is used as the key, and the configuration is a dictionary. For example:
{
…
"secret_engines": {
"my-preferred-engine-slug": {
"backend": "zentral.core.secret_engines.backends.aws_kms"
…
}
}
}
WARNING Before removing a secret engine, you must configure a new default one, and run the rewrap_secrets
command to update the secrets in the DB.
Common backend options
backend
MANDATORY
The python module implementing the secret engine, as a string. Currently available:
zentral.core.secret_engines.backends.aws_pki
zentral.core.secret_engines.backends.cleartext
zentral.core.secret_engines.backends.fernet
zentral.core.secret_engines.backends.gcp_pki
The cleartext
backend should not be used. It was only implemented for the noop
secret engine, to provide a fallback secret engine if no other one is configured.
default
OPTIONAL
A boolean indicating if the secret engine is the default secret engine to be used for all encryption operations. Only one engine can be set as the default
one.
AWS KMS backend
This backend uses an AWS KMS symmetric key.
The default authentication mechanisms are used. If no default credentials are available, you must provide at least a region_name
, aws_access_key_id
and aws_secret_access_key
.
The role or user must be allowed to perform the kms:Encrypt
, kms:Decrypt
, and kms:DescribeKey
actions on the key.
aws_access_key_id
OPTIONAL
The AWS access key ID. You must provide it if the other default authentication mechanisms are not available (AWS EC2 instance role, environment variables, …).
aws_secret_access_key
OPTIONAL
The AWS secret access key. You must provide it if the other default authentication mechanisms are not available (AWS EC2 instance role, environment variables, …).
aws_session_token
OPTIONAL
The AWS session token. You must provide it if the other default authentication mechanisms are not available and if you are using temporary tokens.
aws_endpoint_url
OPTIONAL
The AWS KMS API endpoint URL, if you have configured a VPC private access point, without a private DNS name.
key_id
MANDATORY
The AWS KMS symmetric key ID to use for the kms:Encrypt
/kms:Decrypt
calls.
region_name
MANDATORY
The AWS region where to operate.
Example
{
"backend": "zentral.core.stores.backends.aws_kms",
"region_name": "us-east-1",
"key_id": "our-key-id",
"default": true
}
Fernet backend
This backend uses the python Cryptography Fernet module for symmetric encryption. Keys are derived from passwords
provided in the secret engine configuration, and salted with the Django SECRET_KEY
.
To rotate the keys, insert a new password as the first one in the passwords
list without deleting the current one, and run the rewrap_secrets
management command.
You should keep a copy of the passwords
and the Django SECRET_KEY
in a safe place, in order to be able to read the secrets from the DB during disaster recovery.
passwords
MANDATORY
A list of passwords. The first one is used to encrypt new secrets. All passwords are used to decrypt current secrets. This is used for key rotation. Fernet keys are derived from these passwords, using the Django SECRET_KEY
as the salt value. You can use the standard Zentral configuration variable substitution mechanisms to load the passwords from environment variables or a cloud provider secrets management service.
Full example
{
"backend": "zentral.core.stores.backends.fernet",
"passwords": [
"{{ env:FERNET_PASSWORD_20211001 }}",
"{{ env:FERNET_PASSWORD_20210901 }}"
],
"default": true
}
Google Cloud Key Management
This backend uses a Google Cloud symmetric key.
The default authentication mechanisms are used. If no default credentials are available, you must provide a service account credentials file.
The roles/cloudkms.cryptoKeyEncrypterDecrypter
role can be used to grant the necessary permissions to the service account, at the CryptoKey resource level.
credentials
OPTIONAL
The path to a service account JSON key file. To be used if no other default authentication mechanism is available.
project_id
MANDATORY
The ID of the project where the symmetric key resides.
location_id
MANDATORY
The Google Cloud region where the symmetric key resides.
key_ring_id
MANDATORY
The symmetric key key ring ID.
key_id
MANDATORY
The ID of the symmetric key.
Full example
{
"backend": "zentral.core.secret_engines.backends.gcp_kms",
"credentials": "/path/to/credentials.json",
"project_id": "first-day-of-winter",
"location_id": "europe-west3",
"key_ring_id": "our-keyring",
"key_id": "our-key"
}