Secrets

Learn about internal Vela secrets.

This page will primarily focus on internal secrets. If you would like to learn more about external secrets, check out the external secrets examples page. For a broader view of secrets and how to use internal or external secrets in your pipeline, check out the secrets tour page.

Internal Secrets

Internal secrets are generally managed via the UI or the CLI. They can also be managed via the API.

A full pipeline example is available here

Example pipeline yaml block for internal secrets

secrets:
  - name: foo1
    key: github/ocotocat/foo
    engine: native
    type: repo

Name

The name of your secret.

Key

The key is autogenerated based on the other secret components, following this convention (see Type).

  • Repository: <org>/<repo>/<name>
  • Organization: <org>/<name>
  • Shared: <org>/<team>/<name>

Engine

The native secret engine is designed to store secrets in the database. This component exists for configuration future-proofing; allowing easier expansion for additional options in the future.

Type

There are three types of internal secrets, with equivalent example paths for the UI:

  • Repository - https://vela.example.com/-/secrets/native/repo/<org>/<repo>
  • Organization - https://vela.example.com/-/secrets/native/org/<org>
  • Shared - https://vela.example.com/-/secrets/native/shared/<org>/<team>

Repository

Repository secrets are scoped to only a single repository. In order to create/modify these secrets you must be a repository admin within the source code manager.

Example yaml block for repository secret type

secrets:
  - name: foo1
    key: github/ocotocat/foo1
    engine: native
    type: repo

Organization

Organization secrets are scoped to any repository in the organization. In order to create/modify these secrets you must be an organization admin within the source code manager.

Example yaml block for organization secret type

secrets:
  - name: foo
    key: github/foo
    engine: native
    type: org

Shared

Shared secrets are scoped to any repository in the source code manager (SCM). Shared secrets are unique in the case they require a team to exist in your SCM org. In order to create/modify these secrets you must be a member of the SCM team.

Example yaml block for shared secret type

secrets:
  - name: foo
    key: github/ocotokitties/foo
    engine: native
    type: shared

Protecting Secrets

Learn the best practices for keeping your Vela secrets safe.

Log Exposure

Vela implements a masking routine that obfuscates any printing of an internal secret value in step / service logs. For example:

secrets:
  - name: foo1
    key: github/ocotocat/foo
    engine: native
    type: repo

steps:
  - name: example
    image: alpine
    secrets: foo1
    commands:
      - echo $FOO1  # will print ***

Pull Request Event + Build Approval

Secrets by default do not have the pull request event enabled, as this event can be triggered by users without write access to the repository. Therefore, if users do require secrets for pull request events, it is best practice to adopt a build approval policy, which will allow repository admins to validate the safety of the pipeline.

Other Secret Settings

Defaults for various secret types

SettingRepoOrgShared
Allow CommandYesYesNo
Allow SubstitutionYesYesNo
ImagesAnyAnyAny
Allow EventsPush, Tag, DeploymentPush, Tag, DeploymentPush, Tag, Deployment

Allow Command:

This setting prevents secrets from being injected into the container environment whenever a commands block or custom entrypoint is specified. For example:

secrets:
  - name: no_commands # 'allow command' set to false
    key: vela/no_commands
    type: org
    engine: native
  
  - name: yes_commands # 'allow command' set to true
    key: vela/yes_commands
    type: org
    engine: native
    
steps:
  - name: print secret mask
    image: alpine:latest
    secrets: [ no_commands, yes_commands ]
    commands:
      - echo $NO_COMMANDS # will print nothing (not injected)
      - echo $YES_COMMANDS # will print secret mask ***

Allow Substitution:

This setting prevents secrets from being substituted in the pipeline configuration by referencing its key in ${KEY} format. This setting, in tandem with disallowing commands, prevents users from attempting to bypass Vela’s secret masking in logs. Example:

secrets:
  - name: no_substitution # 'allow substitution' set to false
    key: vela/no_substitution
    type: org
    engine: native
  
  - name: yes_substitution # 'allow substitution' set to true
    key: vela/yes_substitution
    type: org
    engine: native
    
steps:
  - name: docker build
    image: target/vela-kaniko
    secrets: [ no_substitution, yes_substitution ]
    parameters:
      build_args:
        - FOO=${NO_SUBSTITUTION}  # FOO will be empty
        - BAR=${YES_SUBSTITUTION} # BAR will be the value of YES_SUBSTITUTION

  - name: command substitution
    image: alpine
    secrets: [ no_substitution, yes_substitution ]
    commands:
      # As a caveat to this setting, both the following commands will in fact pull in the secret values.
      # This is because Vela converts all commands to a shell script, and these ${KEY} substitutions are
      # actually shell environment substitutions rather than Vela runtime substitutions.
      - wget --header="X-Auth-Token: ${NO_SUBSTITUTION}" https://www.example.com
      - wget --header="X-Auth-Token: ${YES_SUBSTITUTION}" https://www.example.com

Images:

You can further protect a secret by limiting its usage to certain images. This ensures that every time a secret is injected into a container environment, it will be used in an expected way.

You can specify tag-specific images or base images.

secrets:
  - name: any_image # `images` set to "any"
    key: vela/any_image
    type: org
    engine: native
  
  - name: kaniko_only # `images` set to "target/vela-kaniko"
    key: vela/kaniko_only
    type: org
    engine: native
    
steps:
  - name: docker build
    image: target/vela-kaniko
    secrets:
      - source: any_image
        target: KANIKO_USERNAME  # injected as KANIKO_USERNAME
      - source: kaniko_only
        target: KANIKO_PASSWORD  # injected as KANIKO_PASSWORD
    parameters:
      registry: docker.company.com
      repo: docker.company.com/some/repo
      tags:
        - ${VELA_BUILD_COMMIT:0:8}

  - name: alpine use
    image: alpine:latest
    secrets: [ any_image, kaniko_only ]
    commands:
      - echo $ANY_IMAGE    # will print ***, signaling its injection to the environment
      - echo $KANIKO_ONLY  # will print nothing, not injected

Allow Events:

Secrets can be restricted to only be injected into container environments on certain webhook events. This can be useful to limiting potential exposure opportunities and only using a secret when necessary.