Secret¶
A Secret is a collection of private data for use by one or more jobs. In order to maintain the security of the data, the values are usually encrypted, however, data which are not sensitive may be provided unencrypted as well for convenience.
A Secret may only be used by jobs defined within the same project. Note that they can be used by any branch of that project, so if a project’s branches have different access controls, consider whether all branches of that project are equally trusted before using secrets.
To use a secret, a Job must specify the secret in job.secrets. With one exception, secrets are bound to the playbooks associated with the specific job definition where they were declared. Additional pre or post playbooks which appear in child jobs will not have access to the secrets, nor will playbooks which override the main playbook (if any) of the job which declared the secret. This protects against jobs in other repositories declaring a job with a secret as a parent and then exposing that secret.
The exception to the above is if the job.secrets.pass-to-parent attribute is set to true. In that case, the secret is made available not only to the playbooks in the current job definition, but to all playbooks in all parent jobs as well. This allows for jobs which are designed to work with secrets while leaving it up to child jobs to actually supply the secret. Use this option with care, as it may allow the authors of parent jobs to accidentially or intentionally expose secrets. If a secret with pass-to-parent set in a child job has the same name as a secret available to a parent job’s playbook, the secret in the child job will not override the parent, instead it will simply not be available to that playbook (but will remain available to others).
It is possible to use secrets for jobs defined in config
projects as well as untrusted projects, however their use differs slightly. Because
playbooks in a config project which use secrets run in the
trusted execution context where proposed changes are not used
in executing jobs, it is safe for those secrets to be used in all
types of pipelines. However, because playbooks defined in an
untrusted project are run in the untrusted execution context
where proposed changes are used in job execution, it is dangerous to
allow those secrets to be used in pipelines which are used to execute
proposed but unreviewed changes. By default, pipelines are considered
pre-review and will refuse to run jobs which have playbooks that use
secrets in the untrusted execution context (including those subject to
job.secrets.pass-to-parent secrets) in order to protect
against someone proposing a change which exposes a secret. To permit
this (for instance, in a pipeline which only runs after code review),
the pipeline.post-review attribute may be explicitly set to
true
.
In some cases, it may be desirable to prevent a job which is defined
in a config project from running in a pre-review pipeline (e.g., a job
used to publish an artifact). In these cases, the
job.post-review attribute may be explicitly set to true
to
indicate the job should only run in post-review pipelines.
If a job with secrets is unsafe to be used by other projects, the job.allowed-projects attribute can be used to restrict the projects which can invoke that job. If a job with secrets is defined in an untrusted-project, allowed-projects is automatically set to that project only, and can not be overridden (though a config-project may still add the job to any project’s pipeline regardless of this setting; do so with caution as other projects may expose the source project’s secrets).
Secrets, like most configuration items, are unique within a tenant, though a secret may be defined on multiple branches of the same project as long as the contents are the same. This is to aid in branch maintenance, so that creating a new branch based on an existing branch will not immediately produce a configuration error.
When the values of secrets are passed to Ansible, the !unsafe
YAML
tag is added which prevents them from being evaluated as Jinja
expressions. This is to avoid a situation where a child job might
expose a parent job’s secrets via template expansion.
However, if it is known that a given secret value can be trusted, then this limitation can be worked around by using the following construct in a playbook:
- set_fact:
unsafe_var_eval: "{{ hostvars['localhost'].secretname.var }}"
This will force an explicit template evaluation of the var attribute on the secretname secret. The results will be stored in unsafe_var_eval.
-
secret¶
The following attributes must appear on a secret:
-
secret.data (required)¶
A dictionary which will be added to the Ansible variables available to the job. The values can be any of the normal YAML data types (strings, integers, dictionaries or lists) or encrypted strings. See Encryption for more information.
-
secret.data (required)¶