As you work with variables in Octopus, there will be times when you work with applications that require configuration values that are considered sensitive information. These should be kept secret, but used as clear-text during deployment. That could be a password or an API Key to an external resource. Octopus provides support for this scenario with Sensitive variables.
Sensitive variables can be sourced from either:
- A Secret Manager/Key Vault using one of our Community step templates.
- Octopus itself, with values stored securely using AES-256 encryption.
Values from a Secret Manager/Key Vault
Storing sensitive values in Octopus solves many problems, but it’s not a two-way key vault. For this, there are a number of Secret Manager and Key Vault tools available. They also offer additional functionality such as automatic secret rotation and versioning.
Octopus supports the retrieval of sensitive values from a number of Secret Manager/Key Vaults through the use of Community step templates that extend the functionality of Octopus to integrate with them.
Each of the community step templates work by retrieving secrets from the Secret Manager/Key Vault and create sensitive output variables for use in your executing deployments and runbooks.
Octopus has the following community step templates for integrating with Secret Manager/Key Vault tools:
View working examples of all of our Secrets Management community step templates in our samples instance of Octopus. You can sign in as Guest
to view them.
Note: If you choose to use one of the community step templates, it’s important to consider who has permission to edit a project deployment or runbook process, and manage step templates to prevent unauthorized access to sensitive values stored in your Secret Manager/Key Vault.
Sensitive variables stored in Octopus
Variables, such as passwords or API keys can be marked as sensitive.
Just like non-sensitive variables they can reference other variables but be careful with any part of your sensitive variable that could unintentionally be interpreted as an attempted substitution. See also, other common mistakes.
Configuring sensitive variables
To make a variable a sensitive variable, either select Change Type when entering the value and select Sensitive, or enter the variable editor when you are creating or editing the variable.
If using the variable editor, on the variable value, click Open editor:
For variable type, select Sensitive.
How Octopus handles your sensitive variables
Learn more about security and encryption in Octopus Deploy.
When dealing with sensitive variables, Octopus encrypts these values using:
- AES-256 encryption when they are stored in the Octopus database in versions 2024.4 and newer.
- AES-128 encryption when they are stored in the Octopus database in versions prior to 2024.4.
- AES-128 encryption any time they are in transmission, or when they are stored on a deployment target as part of a deployment.
You can use these sensitive values in your deployment process just like normal variables, with two notable exceptions:
- Once the variable is saved, Octopus will never allow you to retrieve the value via the REST API or the Octopus Web Portal; and
- Whenever possible, Octopus will mask these sensitive values in logs.
Choosing which variables should be sensitive
Any value you want can be treated as a secret by Octopus. It is up to you to choose the most appropriate balance of secrecy and usability. As a rule of thumb, any individual value which should be encrypted, or masked in logs, should be made sensitive in Octopus.
The most straightforward example is a password or key. Make the password or key sensitive and it will be encrypted into the database and masked in the Octopus task logs.
Another common example is building a composite value using the variable substitution syntax, like a database connection string. Imagine a variable called DB.ConnectionString
with the value:
Server=#{DB.Server};Database=#{DB.Database};User=#{DB.Username};Password#{DB.Password};
In this case you should at least make the DB.Password
variable sensitive so it will be encrypted in the database and masked from any Octopus task log messages like this:
Server=db01.my-company.com;Database=my-database;User=my-user;Password=*****
.
You could also make DB.Username
or any of the other components of this template sensitive.
Avoiding common mistakes
Here are some common pitfalls to avoid:
- Avoid logging your sensitive values: you won’t really get any benefit from logging your sensitive variables since they will be masked by Octopus. The masking is provided in case a downstream system logs the sensitive value, inadvertently logging it to the Octopus deployment logs.
- Avoid short values: only sensitive variables with length greater than 3 characters will be masked. This is done to prevent false positives causing excessive obfuscation of the logs. Consider 8-30 characters depending on the requirements of your deployment.
- Avoid common language: see the example below of “broke”, use a password generator with high entropy like this one.
- Avoid sequences that are interpreted by your scripting language of choice: For example, certain escape sequences like
$^
will be misinterpreted by PowerShell potentially logging out your sensitive variable in clear-text. - Sensitivity is not transitive/infectious: For example, imagine you have a sensitive variable called
DB.Password
and another variable calledDB.ConnectionString
with the valueServer=#{DB.Server};...;Password=#{DB.Password}
; theDB.ConnectionString
does not become sensitive just becauseDB.Password
is sensitive. However, if you happen to write the database connection string to the task log, the password component will be masked like thisServer=db01.my-company.com;...;Password=*****
which is probably the desired outcome. - Avoid mixing binding expressions and sensitivity: For example, if you have a variable called
Service.Credential
with the valuePassword=#{Service.Password}
and make that variable sensitive, Octopus treats the literal valuePassword=#{Service.Password}
as sensitive instead of treating the evaluated value as sensitive, which might be different to what you would expect. Instead, you should make the variable calledService.Password
sensitive so the password itself will be encrypted in the database, and subsequently masked in any logs like thisPassword=*****
. - Avoid treating entire files as sensitive: Imagine you’re consuming a YAML file from a variable, and that YAML file contains a secret. Rather than treating the whole YAML file as sensitive, you should create two variables: one sensitive variable containing just the secret, and one non-sensitive variable for the YAML file which uses variable substitution to substitute in the sensitive variable. This gives Octopus a much tighter scope when looking for sensitive variables to mask.
- Avoid sequences that are part of the variable substitution syntax: For example, the sequence
##{
will be replaced by#{
by logic that’s part of referencing variables so you would need to escape it by modifying it to be###{
which will result in##{
, see also variable substitution syntax. - Octopus is not a 2-way key vault: use a Secret Manager/Key Vault instead.
Logging
Avoid logging sensitive values! Whilst Octopus will attempt to mask sensitive values, it is better there is no value to mask in the first place!
Octopus/Tentacle will do its best to prevent sensitive values from inadvertently appearing in any logs. For example, if a custom PowerShell script accidentally did this:
Write-Output "Hello, the password is $Password"
Octopus would mask the value from the deployment log, leaving:
Hello, the password is *****
Note that this method isn’t 100% foolproof. Here are a couple of scenarios that you should be extra-careful about if logging sensitive variables:
Common language in secrets
If your top secret password is “broke”, and someone happened to deploy with a PowerShell script with:
Write-Output "Or watch the things you gave your life to, broken"
Then the password might be given away when Octopus prints:
Or watch the things you gave your life to, *******en
The obvious solution is, don’t use passwords that are likely to occur in normal logging/language, and avoid writing the values of your secure variables to logs anyway.
echo
on Unix-based systems
It’s very easy to unintentionally modify a variable when using echo
, particularly if the variable contains new-lines or other escape characters.
In particular, you should always use double-quotes around what you echo
, to prevent unintended processing of variable contents.
For example, you should prefer this:
echo "$(get_octopusvariable 'SecretVariable')"
over this:
echo $(get_octopusvariable 'SecretVariable')
The second approach could trigger evaluation or stripping of special characters within the variable, and result in a log message sufficiently different to the sensitive variable’s value that we are unable to match and mask it.
Of course, the best protection is not to echo
potentially sensitive variables at all.
Learn more
Help us continuously improve
Please let us know if you have any feedback about this page.
Page updated on Friday, October 4, 2024