Skip to main content

Add and reference file secrets

You can store encrypted files and reference them in your Harness resources, such as pipelines, steps, and connectors.

This topic assumes you have created a Harness project.

Create an encrypted file secret

You can add an encrypted file secrets at the project, organization, and account scopes.

  1. Depending on the scope where you want to create the secret, go to Project Setup, Organization, or Account Resources.

  2. Select Secrets.

  3. Select Secret, and then select File.

  4. Select the Secrets Manager that you want to use to store the secret.

  5. Enter a name for the secret.

    You can use this name to reference the encrypted file secret in pipelines, steps, connectors, and so on.

    An ID is created based on the name, and you can also use the ID to reference the encrypted file secret.

  6. Select Browse and locate the file you want to store as a secret.

  7. Optionally, you can enter a Description and Tags.

  8. Select Save.

Reference an encrypted file secret

You can reference a encrypted file secret in any resource that allows files, such as SSH key files for SSH credentials, authentication keys for connectors, and steps in pipelines that ingest files.

Reference by name

When populating a UI field, you can search and select secrets by the Secret Name.

SSH credential settings, including an SSH key file field.

Reference by ID

To reference encrypted file secrets in YAML or in fields that require expressions, you must use the ID in a Harness expression.

  1. Locate the ID, next to the Secret Name, in the secret's settings.

    You can edit a secret's display name, but you can't change the ID.

  2. Reference the secret using the appropriate expression format:

    • Secret created at the project scope, use: <+secrets.getValue("FILE_SECRET_ID")>
    • Secret created at the organization scope: <+secrets.getValue("org.FILE_SECRET_ID")>
    • Secret created at the account scope: <+secrets.getValue("account.FILE_SECRET_ID")>

Secrets in outputs

When a secret is displayed in an output, Harness substitutes the secret value with asterisks so that the secret value is masked. Harness replaces each character in the name with an asterisk (*).

Secret values referenced in a Shell Script step are replaced with asterisks.

If you accidentally use a very common value in your secret, like whitespace, the * substitution might appear in multiple places in the output. If you see an output like this, review your secret and fix the error.

Masking only applies if Harness knows the value is a secret. For example, if you use cat to handle line breaks and shell-interpreted characters in decoded secrets, Harness doesn't know that the content of the cat was a secret, and, therefore, it isn't masked.

Additionally, if an output variable from a step in a build (CI) stage contains a secret, be aware that the secret will be visible in the build details. Such secrets are visible on the Output tab of the step where the output variable originates and in the build logs for any later steps that reference that variable.

Sanitization

Log and output sanitization only look for an exact match of what is stored. For example, if you stored a base64-encoded value, then only the base64-encoded value is sanitized.

For example, assume you have the following multi-line secret:

line 1
line 2
line 3

When this value is base64-encoded, it results in an output like bGluZSAxCmxpbmUgMgpsaW5lIDM=. You could add this value to a Harness secret named linebreaks, and then decode the secret with a command such as echo <+secrets.getValue("linebreaks")> | base64 -d.

When the pipeline runs, the resulting decoded output is not sanitized because it doesn't match the stored base64-encoded value.

Line breaks and shell-interpreted characters

You can reference secrets in scripts, but text secrets with line breaks or other special characters might interfere with script execution.

To address this, you can decode and write the secret to a file. For example, the following command decodes a secret from base64 and writes it to a file:

echo <+secrets.getValue("my_secret")> | base64 -d > /path/to/file.txt

For secrets that are not in base64, such as PEM files, you can convert and encode them in base64, and then store them as Harness file secrets before decoding them in your pipelines. For example, this command decodes a secret called my_secret and stores the decoded secret at /harness/secrets.json:

echo <+secrets.getValue("my_secret")> | base64 -d > /harness/secrets.json

You can also write secrets to files without base64, for example:

echo '<+secrets.getValue("long_secret")>' > /tmp/secretvalue.txt

However, if your secret contains line breaks or you don't use base64 and the secret's value contains any shell-interpreted characters, the script might not execute as expected. In this case, you can cat the secret in a special-purpose code block, for example:

cat > /harness/secret_exporter/values.txt << 'EOF'
MySecret:<+secrets.getValue("test")>
EOF

Decoded secrets in cat aren't masked in outputs, because Harness no longer recognizes the contents as a secret.

Here's an example of a secret decoded in a CI Run step:

              - step:
type: Run
name: Run_1
identifier: Run_1
spec:
shell: Sh
command: |
echo $SECRET | base64 --decode > decoded.txt
envVariables:
SECRET: <+secrets.getValue("secretfile")>