Using Secret Credentials When Building Containers¶
There are many cases when building a container that sensitive credentials may be required. Examples include:
- Downloading a package from a private NPM registry
- Grabbing a file via scp
Each scenario requires a slightly different approach in the Dockerfile. However, the general approach to getting these secrets securely into your container’s build context is the same.
Note
There are several insecure ways that should be avoid in order to do this correctly. The proper approach is what’s described here based on new functionality in Docker’s BuildKit.
Quick Background On CI Secrets¶
The Factory’s CI System, JobServ, has a mechanism to configure secrets for
a Project (the factory’s LmP build in this case). These secrets are placed
under /secrets/
when a CI Run is executed. For example a Factory might
have secrets:
- secret_1=A Secret Value
- secret_2=Could even\nbe multi-line
Each Run performed during a Build will have the files:
- /secrets/secret_1
- /secrets/secret_2
So the magic required here is getting these accessible to the Dockerfile’s build context.
Defining Factory Secrets¶
The fioctl tool includes support for managing secrets for a factory:
# List secrets defined in the factory:
fioctl secrets list
# Add/Update secrets defined in the factory:
# NOTE: quotes are needed for arguments with spaces or multi-line files
fioctl secrets update secret_1=blah secret_2="$(cat $HOME/.ssh/id_rsa)"
# Remove secrets defined in the factory:
fioctl secrets update secret_1= secret_2=
Passing Secrets to Docker’s Build Context¶
First update factory-config.yml file ci-scripts.git to instruct the container build scripts to pass the factory secrets to docker with:
containers:
docker_build_secrets: true
Now that CI system knows the factory wants secrets passed into the build context, its time to update the Dockerfile for the container with something like:
# syntax=docker/dockerfile:1.0.0-experimental
# NOTE: - the first line must be this "syntax=" to enable this feature.
FROM alpine
# Docker places secrets under /run/secrets/<id>
RUN --mount=type=secret,id=secret_1 echo "secret_1 is here:" && cat /run/secrets/secret_1
RUN --mount=type=secret,id=secret_2 echo "secret_2 is here:" && cat /run/secrets/secret_2