28

I'm wondering whether there are best practices on how to inject credentials into a Docker container during a docker build. In my Dockerfile I need to fetch resources webservers which require basic authentication and I'm thinking about a proper way on how to bring the credentials into the container without hardcoding them.

What about a .netrc file and using it with curl --netrc ...? But what about security? I do no like the idea of having credentials being saved in a source repository together with my Dockerfile.

Is there for example any way to inject credentials using parameters or environment variables?

Any ideas?

roehrijn
  • 1,387
  • 1
  • 11
  • 20
  • see https://stackoverflow.com/questions/32664729/how-can-i-pass-secret-data-to-a-container – user2915097 May 31 '16 at 18:49
  • 2
    I think this question here is about passing in credentials for the _build_ only, such as credentials to fetch a release zip from some URL to be unpacked during the build, _not_ credentials for the app when the container runs (what the above linked question is about). `ARG` would fit, but it's not safe for credentials as the values are kept in the image metadata and visible with `docker history` to anyone who has the image file. – Alexander Klimetschek Oct 31 '17 at 00:36

1 Answers1

20

A few new Docker features make this more elegant and secure than it was in the past. The new multi-phase builds let us implement the builder pattern with one Dockerfile. This method puts our credentials into a temporary "builder" container, and then that container builds a fresh container that doesn't hold any secrets.

You have choices for how you get your credentials into your builder container. For example:

  • Use an environment variable: ENV creds=user:pass and curl https://$creds@host.com
  • Use a build-arg to pass credentials
  • Copy an ssh key into the container: COPY key /root/.ssh/id_rsa
  • Use your operating system's own secure credentials using Credential Helpers

Multi-phase Dockerfile with multiple FROMs:

## Builder
FROM alpine:latest as builder
#
# -- insert credentials here using a method above --
#
RUN apk add --no-cache git
RUN git clone https://github.com/some/website.git /html

## Webserver without credentials
FROM nginx:stable
COPY --from=builder /html /usr/share/nginx/html
Ben Cox
  • 1,393
  • 10
  • 28
xer0x
  • 12,970
  • 5
  • 32
  • 29
  • 11
    Never use COPY with ssh keys. https://medium.com/@activenode/docker-build-with-private-credentials-the-issue-with-intermediate-layer-secrets-7cdb370c726a – ZigZagT Mar 18 '19 at 09:29
  • 1
    @ZigZagT that Medium article isn't using multi-phase builds, it's correct that for single-phase build it's an insecure technique, but with multi-phase builds the problem is avoided as `xer0x` shows. – Ken Williams Nov 30 '21 at 18:42
  • 1
    @KenWilliams Yes, you're right. But please keep in mind this comment is almost 4yr old. single-stage build pattern was still dominant back then since multi-stage build was too new to be widely adopted. It wasn't rare to find ssh keys in a public image on docker hub. – ZigZagT Dec 02 '21 at 00:58
  • I agree that people putting credentials in images has been way too widespread a phenomenon, but the answer here is correct and the admonition to never use `COPY` is incorrect in this context, just as it was 4 years ago. – Ken Williams Dec 03 '21 at 03:19