Can an SSH key added and removed in the same step of a Dockerfile can be compromised?

I need to create a Docker image that could be public and to do so, I first need to get code that is found in one of my private repos.

In my Dockerfile, I have a step that clones the repo, but it being a private repo, I need to log in to GitHub using SSH. Therefore, I during the docker build process, I need to get my private SSH key, clone my repo, and delete my key so that it cannot be found in the final image.

docker build --build-arg SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)" .....

But since every line of a Dockerfile is a layer in the final image and that layers can be deep-dived in, I figured all of this has to be done in the same step, or else my key could be found in one of the layers of the image even though it won’t be in thee final image. So I setup my Dockerfile like this:

FROM python:3.10.13-slim

...

# Clone private GitHub repo
ARG SSH_PRIVATE_KEY
RUN apt-get update \
    && apt-get install -y git ssh
RUN mkdir -p ~/.ssh \
    && echo "${SSH_PRIVATE_KEY}" > ~/.ssh/id_rsa \
    && chmod 600 ~/.ssh/id_rsa \
    && touch ~/.ssh/known_hosts \
    && ssh-keyscan -H github.com >> ~/.ssh/known_hosts \
    && git clone XXXXXXXXXXXXX \
    && rm -f ~/.ssh/known_hosts \
    && rm -f ~/.ssh/id_rsa

...

As you can see, I get my key from the build-args, clone my repo and remove my key all in the same step.

Assuming my Docker image is going to be public, can my private SSH key can still be recovered from it by someone smart enough to do that?

Thank you

Build arguments still can be seen in the image history as metadata. I would recommend the SSH mount feature of buildkit:

https://docs.docker.com/engine/reference/commandline/buildx_build/#ssh

2 Likes

Thank you!
So with this, no one that has access to the image can view the SSH key that was used to build the image, right?

And what’s the difference with the Secret mount, because I can see on your link in the Mount Types section this for the Secret type:
“Allow the build container to access secure files such as private keys without baking them into the image.”

which seems exactly like what I want to do. So am I better off with SSH mount or Secret mount?

Thank you!

Yes

If you click of the blue RUN line on the page I linked, you can find the description of the SSH mount type:

https://docs.docker.com/engine/reference/builder/#run—mounttypessh

This mount type allows the build container to access SSH keys via SSH agents, with support for passphrases.

You can also specify a path to *.pem file on the host directly instead of $SSH_AUTH_SOCK . However, pem files with passphrases are not supported.

If you just mount a secret, ssh passphrase will not be supported.

1 Like

Thanks a lot for your help @rimelek ! :slight_smile: