Skip to content

Commit 2ebca75

Browse files
committed
feat(envbuilder.go): document build secrets
1 parent 6fdad17 commit 2ebca75

File tree

2 files changed

+20
-30
lines changed

2 files changed

+20
-30
lines changed

docs/build-secrets.md

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,62 +13,46 @@ To illustrate build secrets in envbuilder, let's build, push and run a container
1313

1414
First, start a local docker registry, so that we can push and inspect the built image:
1515
```bash
16-
docker run -d -p 5000:5000 --name envbuilder-registry --volume $(PWD)/.registry-cache:/var/lib/registry registry:2;
16+
docker run --rm -d -p 5000:5000 --name envbuilder-registry registry:2
1717
```
1818

1919
Then, build an image based on this Dockerfile:
2020

2121
```Dockerfile
2222
FROM alpine:latest
2323

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
24+
RUN --mount=type=secret,id=FOO,env cat $FOO > /foo_secret_hash.txt
25+
RUN --mount=type=secret,id=BAR,dst=/tmp/bar.secret cat /tmp/bar.secret > /bar_secret_hash.txt
2626
```
2727
using this command:
2828
```bash
2929
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
30+
-e ENVBUILDER_BUILD_SECRET_FOO='envbuilder-test-secret-foo' \
31+
-e ENVBUILDER_BUILD_SECRET_BAR='envbuilder-test-secret-bar' \
3832
-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 \
33+
-e ENVBUILDER_CACHE_REPO=$(docker inspect envbuilder-registry | jq -r '.[].NetworkSettings.IPAddress'):5000/test-container \
34+
-e ENVBUILDER_PUSH_IMAGE=0 \
35+
-v $PWD:/workspaces/empty \
4236
ghcr.io/coder/envbuilder:latest
4337
```
4438

4539
This will result in a shell session inside the built container.
4640
You can now verify two things:
47-
* The secrets provided to build are not available once the container is running.
41+
* The secrets provided to build are not available once the container is running. They are no longer on disk, nor are they in the process environment, or in `/proc/self/environ`.
4842
* The secrets were still useful during the build:
4943
```bash
5044
cat /foo_secret.txt
5145
cat /bar_secret.txt
5246
```
5347

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-
6948
## Security and Production Use
7049
The example above ignores various security concerns for the sake of simple illustration. To use build secrets securely, consider these factors:
7150

51+
### Build Secret Purpose and Management
52+
Build secrets are meant for use cases where the secret should not be accessible from the built image, nor from the running container. If you need the secret at runtime, use a volume instead. Volumes that are mounted into a container will not be included in the final image, but still be available at runtime.
53+
54+
Build secrets are only protected if they are not copied or moved from their location as designated in the `RUN` directive. If a build secret is used, care should be taken to ensure that it is not copied or otherwise persisted into an image layer beyond the control of Envbuilder.
55+
7256
### Who should be able to access build secrets, when and where?
7357
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.
7458

envbuilder.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,11 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
12671267
if opts.CacheRepo != "" {
12681268
destinations = append(destinations, opts.CacheRepo)
12691269
}
1270+
1271+
buildSecrets := options.GetBuildSecrets(os.Environ())
1272+
// Ensure that build secrets do not make it into the runtime environment or the setup script:
1273+
options.ClearBuildSecretsFromProcessEnvironment()
1274+
12701275
kOpts := &config.KanikoOptions{
12711276
// Boilerplate!
12721277
CustomPlatform: platforms.Format(platforms.Normalize(platforms.DefaultSpec())),
@@ -1291,6 +1296,7 @@ func RunCacheProbe(ctx context.Context, opts options.Options) (v1.Image, error)
12911296
},
12921297
ForceUnpack: true,
12931298
BuildArgs: buildParams.BuildArgs,
1299+
BuildSecrets: buildSecrets,
12941300
CacheRepo: opts.CacheRepo,
12951301
Cache: opts.CacheRepo != "" || opts.BaseImageCacheDir != "",
12961302
DockerfilePath: buildParams.DockerfilePath,

0 commit comments

Comments
 (0)