Using private git submodules in GitHub CI
Do you need to use submodules in your project? Do you use GitHub CI to build your project in the Cloud automatically?
If so then this article will help you to do this safely and without creating additional users or adding Tokens with a wide permission set. The idea is to use deploy keys that have read-only permissions.
The quick rundown for all you experts:
- create SSH keypair on your computer
- add public part as deploy key to private submodule
- add private key as secret in repo where action is triggered. E.g SSH_KEY
- add Secret to env with
env:
SSH_KEY: ${{secrets.SSH_KEY}}
do the following before pulling the submodules in the run configuration
mkdir $HOME/.ssh && echo "$SSH_KEY" > $HOME/.ssh/id_rsa && chmod 600 $HOME/.ssh/id_rsa
Detailed rundown
Create SSH keypair
Run ssh-keygen
on your terminal. Choose a convenient location for the key e.g. /home/your_username/github_key
on Linux.
This will create github_key
and github_key.pub
.
Add deploy key to the submodule
In the settings page of your submodule repository on GitHub add a new deploy key. Use the content of the github_key.pub
file.
Add the private key as a secret to your project
Now head over to the GitHub settings of your project that will consum the submodule.
Add the contents of github_key
as a new repository secret. Choose a name such as SSH_KEY_FOR_SUBMODULE
Set up the CI
This is the configuration that is building this blog:
# .github/workflows/build_image.yml
jobs:
build:
runs-on: ubuntu-latest
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Trigger release build
env:
SSH_KEY_FOR_SUBMODULE: ${{secrets.SSH_KEY_FOR_SUBMODULE}}
run: |
mkdir $HOME/.ssh && echo "$SSH_KEY_FOR_SUBMODULE" > $HOME/.ssh/id_rsa && chmod 600 $HOME/.ssh/id_rsa && git submodule update --init --recursive && docker login docker.pkg.github.com -u $GITHUB_ACTOR --password $GITHUB_TOKEN && docker build . -t docker.pkg.github.com/blogname
So what is happening here?
Before git submodule update --init --recursive
is run, the private key is read from the GitHub Secrets, written into a file that is used as a standard by SSH and the correct permissions are set on the key file.
All this makes the submodule intiliaztion work without problems since the private key verifies that the runner is allowed to read from the submodule repository.
Recap
- create a keypair
- distribute the keys as deploy key and GitHub Secret
- read Secret and save the key into the standard
$HOME/.ssh/id_rsa
file
This solution guarantees that the runner can only read from the repository, but not give it any further access, which a Token based variant would do (in addition to needing a new GitHub user if done correctly).
Now go enjoy peace of mind when distributing your code all over the place. Happy hacking!
Cover Photo by Paweł Czerwiński on Unsplash