Encryption
Zuul supports storing encrypted data directly in the git repositories of projects it operates on. If you have a job which requires private information in order to run (e.g., credentials to interact with a third-party service) those credentials can be stored along with the job definition.
Each project in Zuul has its own automatically generated RSA keypair
which can be used by anyone to encrypt a secret and only Zuul is able
to decrypt it. Zuul serves each project’s public key using its
build-in webserver. They can be fetched at the path
/api/tenant/<tenant>/key/<project>.pub
where <project>
is the
canonical name of a project and <tenant>
is the name of a tenant
with that project.
Zuul currently supports one encryption scheme, PKCS#1 with OAEP, which can not store secrets longer than the 3760 bits (derived from the key length of 4096 bits minus 336 bits of overhead). The padding used by this scheme ensures that someone examining the encrypted data can not determine the length of the plaintext version of the data, except to know that it is not longer than 3760 bits (or some multiple thereof).
In the config files themselves, Zuul uses an extensible method of
specifying the encryption scheme used for a secret so that other
schemes may be added later. To specify a secret, use the
!encrypted/pkcs1-oaep
YAML tag along with the base64 encoded
value. For example:
- secret:
name: test_secret
data:
password: !encrypted/pkcs1-oaep |
BFhtdnm8uXx7kn79RFL/zJywmzLkT1GY78P3bOtp4WghUFWobkifSu7ZpaV4NeO0s71YUsi
...
To support secrets longer than 3760 bits, the value after the encryption tag may be a list rather than a scalar. For example:
- secret:
name: long_secret
data:
password: !encrypted/pkcs1-oaep
- er1UXNOD3OqtsRJaP0Wvaqiqx0ZY2zzRt6V9vqIsRaz1R5C4/AEtIad/DERZHwk3Nk+KV
...
- HdWDS9lCBaBJnhMsm/O9tpzCq+GKRELpRzUwVgU5k822uBwhZemeSrUOLQ8hQ7q/vVHln
...
The zuul-client utility provides a simple way to encrypt secrets for a Zuul project:
usage: zuul-client encrypt [-h] [--public-key /path/to/pubkey]
[--tenant TENANT] [--project PROJECT] [--no-strip]
[--secret-name SECRET_NAME]
[--field-name FIELD_NAME] [--infile INFILE]
[--outfile OUTFILE]
optional arguments:
-h, --help show this help message and exit
--public-key /path/to/pubkey
path to project public key (bypass API call)
--tenant TENANT tenant name
--project PROJECT project name
--no-strip Do not strip whitespace from beginning or end of
input.
--secret-name SECRET_NAME
How the secret should be named. If not supplied, a
placeholder will be used.
--field-name FIELD_NAME
How the name of the secret variable. If not supplied,
a placeholder will be used.
--infile INFILE A filename whose contents will be encrypted. If not
supplied, the value will be read from standard input.
If entering the secret manually, press Ctrl+d when
finished to process the secret.
--outfile OUTFILE A filename to which the encrypted value will be
written. If not supplied, the value will be written to
standard output.