Skip to content

Commit 3b5e52f

Browse files
committed
feat(docs): document build secrets
1 parent d3310b9 commit 3b5e52f

File tree

1 file changed

+82
-0
lines changed

1 file changed

+82
-0
lines changed

docs/build-secrets.md

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
# Build Secrets
2+
3+
Envbuilder supports [build secrets](https://docs.docker.com/reference/dockerfile/#run---mounttypesecret). For envbuilder, build secrets are useful when you need to use sensitive information during the image build process and:
4+
* the secrets should not be present in the built image.
5+
* the secrets should not be accessible in the container after its built has concluded.
6+
7+
If your Dockerfile contains directives of the form `RUN --mount=type=secret,...`, Envbuilder will attempt to mount build secrets as specified. Envbuilder does need to find these secrets. Unlike the `docker build` command, Envbuilder does not support the `--secret` flag. Instead, Envbuilder collects build secrets from environment variables prefixed with `ENVBUILDER_BUILD_SECRET_`.
8+
These build secrets will not be present in any cached layers or images that are pushed to an image repository. Nor will they be available at run time.
9+
10+
## Example
11+
12+
To illustrate build secrets in envbuilder, let's build, push and run a container locally. These concepts will transfer to Kubernetes or other containerised environments. Note that this example is for illustrative purposes only and is not fit for production use. Production considerations are discussed in the next section.
13+
14+
First, start a local docker registry, so that we can push and inspect the built image:
15+
```bash
16+
docker run -d -p 5000:5000 --name envbuilder-registry --volume $(PWD)/.registry-cache:/var/lib/registry registry:2;
17+
```
18+
19+
Then, build an image based on this Dockerfile:
20+
21+
```Dockerfile
22+
FROM alpine:latest
23+
24+
RUN --mount=type=secret,id=FOO,env cat $FOO > /foo_secret.txt
25+
RUN --mount=type=secret,id=BAR,dst=/tmp/bar.secret cat /tmp/bar.secret > /bar_secret.txt
26+
```
27+
using this command:
28+
```bash
29+
docker run -it --rm \
30+
# Set build secrets:
31+
-e ENVBUILDER_SECRET_FOO='foo' \
32+
-e ENVBUILDER_SECRET_BAR='bar' \
33+
# Cache image layers in a local registry
34+
-e CACHE_REPO='localhost:5000'\
35+
# Push the image that envbuilder builds
36+
-e PUSH_IMAGE='1' \
37+
# Configure the envbuilder workspace
38+
-e ENVBUILDER_INIT_SCRIPT='/bin/sh' \
39+
-e ENVBUILDER_WORKSPACE_FOLDER=/workspace \
40+
-v $PWD:/workspace \
41+
-v /var/run/docker.sock:/var/run/docker.sock \
42+
ghcr.io/coder/envbuilder:latest
43+
```
44+
45+
This will result in a shell session inside the built container.
46+
You can now verify two things:
47+
* The secrets provided to build are not available once the container is running.
48+
* The secrets were still useful during the build:
49+
```bash
50+
cat /foo_secret.txt
51+
cat /bar_secret.txt
52+
```
53+
54+
Once done, exit the container and proceed to the next step.
55+
56+
We have verified that build secrets do not persist into the runtime container environment. Let's now verify that they also do not persist into the built image. To do this, pull the image and save it as a .tar file. Then, extract it
57+
and inspect its manifests and layers.
58+
59+
```bash
60+
# Determine the image name and tag
61+
curl ...
62+
# Pull and save to disk
63+
docker pull localhost:5000/
64+
docker save -o image.tar localhost:5000/
65+
# Inspect the contents
66+
67+
```
68+
69+
## Security and Production Use
70+
The example above ignores various security concerns for the sake of simple illustration. To use build secrets securely, consider these factors:
71+
72+
### Who should be able to access build secrets, when and where?
73+
The secure way to use build secrets with envbuilder is to deny users access to the platform that hosts envbuilder. Only grant access to the envbuilder container once it has concluded its build, using a trusted non-platform channel like ssh or the coder agent running inside the container. Once control has been handed to such a runtime container process, envbuilder will have cleared all secrets that it set from the container.
74+
75+
Anyone with sufficient access to attach directly to the container (eg. using `kubectl`), will be able to read build secrets if they attach to the container before it has concluded its build. Anyone with sufficient access to the platform that hosts the envbuilder container will also be able to read these build secrets from where the platform stores them. This is true for other build systems, and software in general.
76+
77+
If secrets should be accessible at runtime, do not use build secrets. Rather, mount the secret data using a volume or environment variable. Envbuilder will not include mounted volumes in the image that it pushes to any cache repositories, but they will still be available to users that connect to the container.
78+
79+
### Container Management beyond Envbuilder's control
80+
Container orchestration systems mount certain artifacts into containers for various reasons. It is possible that some of these might grant indirect access to build secrets. Consider kubernetes. It will mount a service account token into running containers. Depending on the access granted to this service account token, it may be possible to read build secrets and other sensitive data using the kubernetes API. This should not be possible by default, but envbuilder cannot provide such a guarantee.
81+
82+
When building a system that uses envbuilder, ensure that your platform does not expose unintended secret information to the container.

0 commit comments

Comments
 (0)