Skip to content

Instantly share code, notes, and snippets.

@zoellner
Last active December 13, 2023 22:25
Show Gist options
  • Star 16 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zoellner/940fa8845e1331a841d9aef3e5c361aa to your computer and use it in GitHub Desktop.
Save zoellner/940fa8845e1331a841d9aef3e5c361aa to your computer and use it in GitHub Desktop.
Extract Github token for Docker build with private repo

Note: There are better ways to do this by now. Check https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information for details

In order to access packages in private github repositories a Dockerfile might contain statements like this:

RUN git config --global url."https://${GITHUB_TOKEN}@github.com/".insteadOf "https://github.com/"
RUN npm install --ignore-scripts --quiet && npm cache clean --force
RUN git config --global --unset url."https://${GITHUB_TOKEN}@github.com/".insteadOf

On the CI instance this is done with docker build --build-arg GITHUB_TOKEN=${GITHUB_TOKEN} where GITHUB_TOKEN is set as environment variable.

In order for the build command to succeed on a local developer machine (aka Macbook) the GITHUB_TOKEN needs to be passed into the build command through the --build-arg command line parameter.

In order to automate this process (assuming that the github credentials are stored in the mac keychain) without having them to be stored in a permanent place the following build command can be used:

docker build --build-arg GITHUB_TOKEN=`printf 'host=github.com\\nprotocol=https\\n\\n' | git credential-osxkeychain get | tr '\\n' ' ' | sed -E 's/password=(\\w*)\\susername=(\\w*)/\\2:\\1/g'` .

What this comes down to is using the following shell command to extract the credentials from the OSX key chain and massage it into the username:password format that we need

printf 'host=github.com\\nprotocol=https\\n\\n' | git credential-osxkeychain get | tr '\\n' ' ' | sed -E 's/password=(\\w*)\\susername=(\\w*)/\\2:\\1/g'

What this does is to execute git credential-osxkeychain get, feed it with the two lines

host=github.com
protocol=https

then convert the line break from the result (the password and username from the key chain) into a space tr '\\n' ' ' (that's just because multiline sed is a pain), then extract the password and username pieces of that string and reformat it.

@orinokai
Copy link

If the image will always be private then this is fine, but otherwise it's worth mentioning that using this method will leave your GitHub token in the Docker image history, accessible with the docker history command.

@shahsyed-pcln
Copy link

If the image will always be private then this is fine, but otherwise it's worth mentioning that using this method will leave your GitHub token in the Docker image history, accessible with the docker history command.

Thanks for the tip!

@zoellner
Copy link
Author

zoellner commented Sep 5, 2020

Added a note on top that there are better ways to do this by now: https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information

@Abhijeet94
Copy link

For some (regex matching) reason, this works for me

GITHUB_TOKEN=`printf 'host=github.com\\nprotocol=https\\n\\n' | git credential-osxkeychain get | tr '\\n' ' ' | sed -E 's/password=([^[:space:]]+)[[:space:]]username=([^[:space:]]+)/\\2:\\1/g'`

instead of

GITHUB_TOKEN=`printf 'host=github.com\\nprotocol=https\\n\\n' | git credential-osxkeychain get | tr '\\n' ' ' | sed -E 's/password=(\\w*)\\susername=(\\w*)/\\2:\\1/g'`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment