Secrets Handling
Using Your Credhub
Credhub can be used to store secure properties that you don't want committed into a config file. Within your pipeline, the config file can then reference that Credhub value for runtime evaluation.
An example workflow would be storing an SSH key.
- Authenticate with your credhub instance.
- Generate an ssh key:
credhub generate --name="/private-foundation/opsman_ssh_key" --type=ssh
- Create an Ops Manager configuration file that references the name of the property.
1 2 3 |
|
- Configure your pipeline to use the credhub-interpolate task.
It takes an input
files
, which should contain your configuration file from (3).
The declaration within a pipeline might look like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
|
Notice the PREFIX
has been set to /private-foundation
, the path prefix defined for your cred in (2).
This allows the config file to have values scoped, for example, per foundation.
params
should be filled in by the credhub created with your Concourse instance.
Info
You can set the param SKIP_MISSING:false
to enforce strict checking of
your vars files during intrpolation. This is true by default to support
credential management from multiple sources. For more information, see the
Multiple Sources section.
This task will reach out to the deployed credhub and fill in your entry references and return an output
named interpolated-files
that can then be read as an input to any following tasks.
Our configuration will now look like
1 2 3 |
|
Info
If using this you need to ensure the concourse worker can talk to credhub so depending on how you deployed credhub and/or worker this may or may not be possible. This inverts control that now workers need to access credhub vs default is atc injects secrets and passes them to the worker.
Defining Multiline Certificates and Keys in Config Files
There are three ways to include certificates in the yaml files that are used by Platform Automation tasks.
-
Direct inclusion in yaml file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
# An incomplete base.yml response from om staged-config product-name: cf product-properties: .uaa.service_provider_key_credentials: value: cert_pem: | -----BEGIN CERTIFICATE----- ...<Some Cert>... -----END CERTIFICATE----- private_key_pem: | -----BEGIN RSA PRIVATE KEY----- ...<Some Private Key>... -----END RSA PRIVATE KEY----- .properties.networking_poe_ssl_certs: value: - certificate: cert_pem: | -----BEGIN CERTIFICATE----- ...<Some Cert>... -----END CERTIFICATE----- private_key_pem: | -----BEGIN RSA PRIVATE KEY----- ...<Some Private Key>... -----END RSA PRIVATE KEY-----
-
Secrets Manager reference in yaml file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# An incomplete base.yml product-name: cf product-properties: .uaa.service_provider_key_credentials: value: cert_pem: ((uaa_service_provider_key_credentials.certificate)) private_key_pem: ((uaa_service_provider_key_credentials.private_key)) .properties.networking_poe_ssl_certs: value: - certificate: cert_pem: ((networking_poe_ssl_certs.certificate)) private_key_pem: ((networking_poe_ssl_certs.private_key))
This example assumes the use of Credhub.
Credhub supports a
--type=certificate
credential type which allows you to store a certificate and private key pair under a single name. The cert and key can be stored temporarily in local files or can be passed directly on the command line.An example of the file storage method:
1 2 3 4
credhub set --type=certificate \ --name=uaa_service_provider_key_credentials \ --certificate=./cert.pem \ --private=./private.key
-
Using vars files
Vars files are a mix of the two previous methods. The cert/key is defined inline in the vars file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
#vars.yml uaa_service_provider_key_credentials_cert_pem: | -----BEGIN CERTIFICATE----- ...<Some Cert>... -----END CERTIFICATE----- uaa_service_provider_key_credentials_private_key: | -----BEGIN RSA PRIVATE KEY----- ...<Some Private Key>... -----END RSA PRIVATE KEY----- networking_poe_ssl_certs_cert_pem: | -----BEGIN CERTIFICATE----- ...<Some Cert>... -----END CERTIFICATE----- networking_poe_ssl_certs_private_key: | -----BEGIN RSA PRIVATE KEY----- ...<Some Private Key>... -----END RSA PRIVATE KEY-----
and referenced as a
((parameter))
in thebase.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
# An incomplete base.yml product-name: cf product-properties: .uaa.service_provider_key_credentials: value: cert_pem: ((uaa_service_provider_key_credentials_cert_pem)) private_key_pem: ((uaa_service_provider_key_credentials_private_key)) .properties.networking_poe_ssl_certs: value: - certificate: cert_pem: ((networking_poe_ssl_certs_cert_pem)) private_key_pem: ((networking_poe_ssl_certs_private_key))
Storing values for Multi-foundation
Credhub
In the example above, bosh int
did not replace the ((placeholder_credential)): ((cloud_controller_encrypt_key.secret))
.
For security, values such as secrets and keys should not be saved off in static files (such as an ops file). In order to
rectify this, you can use a secret management tool, such as Credhub, to sub in the necessary values to the deployment
manifest.
Let's assume basic knowledge and understanding of the
credhub-interpolate
task described in the Secrets Handling section
of the documentation.
For multiple foundations, credhub-interpolate
will work the same, but PREFIX
param will
differ per foundation. This will allow you to keep your base.yml
the same for each foundation with the same
((placeholder_credential)) reference. Each foundation will require a separate credhub-interpolate
task call with a unique prefix to fill out the missing pieces of the template.
Vars Files
Vars files can be used for your Secrets Handling.
Take the example below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
In our first foundation, we have the following vars.yml
, optional for the configure-product
task.
1 2 3 |
|
The vars.yml
could then be passed to configure-product
with base.yml
as the config file.
The task will then sub the ((cloud_controller_encrypt_key.secret))
and ((cloud_controller_apps_domain))
specified in vars.yml
and configure the product as normal.
An example of how this might look in a pipeline(resources not listed):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
Multiple Sources
Both vars files and credhub may be used to interpolate variables into base.yml
.
Using the same example from above:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
We have one parametrized variable that is secret and might not want to have stored in
a plain text vars file, ((cloud_controller_encrypt_key.secret))
, but ((cloud_controller_apps_domain))
is fine in a vars file. In order to support a base.yml
with credentials from multiple sources (i.e.
credhub and vars files), you will need to SKIP_MISSING: true
in the credhub-interpolate
task.
This is enabled by default by the credhub-interpolate
task.
The workflow would be the same as Credhub, but when passing the interpolated base.yml
as a config into the
next task, you would add in a Vars File to fill in the missing variables.
An example of how this might look in a pipeline (resources not listed), assuming:
- The
((base.yml))
above ((cloud_controller_encrypt_key.secret))
is stored in credhub((cloud_controller_apps_domain))
is stored indirector-vars.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
|
Multiple Key Lookups in a Single Task
When using Credhub in a single foundation or multi-foundation manner, we want to avoid duplicating identical credentials (duplication makes credential rotation harder).
In order to have Credhub read in credentials from multiple paths
(not relative to your PREFIX
),
you must provide the absolute path to any credentials
not in your relative path.
For example, using an alternative base.yml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Let's say in our job
, we define the prefix as "foundation1".
The parameterized values in the example above will be interpolated as follows:
((cloud_controller_apps_domain))
uses a relative path for Credhub.
When running credhub-interpolate
, the task will prepend the PREFIX
.
This value is stored in Credhub as /foundation1/cloud_controller_apps_domain
.
((/alternate_prefix/cloud_controller_encrypt_key.secret))
(note the leading slash)
uses an absolute path for Credhub.
When running credhub-interpolate
, the task will not prepend the prefix.
This value is stored in Credhub at it's absolute path /alternate_prefix/cloud_controller_encrypt_key.secret
.
Any value with a leading /
slash will never use the PREFIX
to look up values in Credhub.
Therefore, you can have multiple key lookups in a single interpolate task.