In the previous chapter we installed brew and the gh tool so that api commands could be made to github directly. Now, in order to use the gh api binary tool you will need to have brew or be able to install the gh binary thru apt, yum or pkg, or equivalent. In my case I’m using centos9 stream on my desktop and I need to use brew since the default repo does not have it.
First I will authenticate and get my token access setup with gh
[github@localhost ~]$ gh auth login
? Where do you use GitHub? GitHub.com
? What is your preferred protocol for Git operations on this host? SSH
? Upload your SSH public key to your GitHub account? Skip
? How would you like to authenticate GitHub CLI? Paste an authentication token
Tip: you can generate a Personal Access Token here https://github.com/settings/tokens
The minimum required scopes are 'repo', 'read:org'.
? Paste your authentication token: ****************************************
- gh config set -h github.com git_protocol ssh
✓ Configured git protocol
! Authentication credentials saved in plain text
✓ Logged in as meepyuser
The gh tool is pretty neat, it allows you to auth via https or ssh to get your key. In my case I already used ssh-keygen to generate my key in ~/.ssh/ and have added it manually, pretty cool though that it will do this for you. Now there is really no excuse not to use the extended gh api features this binary tool provides.
But look at this carefully, we have a problem here; “! Authentication credentials saved in plain text”. This is a serious problem and shouldn’t be ignored, especially on a product environment. If the repo is sensitive it means someone could take control of the repo if they compromise your filesystem. It’s much better to use a credentials store, such as is standard nowadays in most api and opensource software.
Lets install GCM (Git Credential Manager), because it will encrypt the github token we give it rather than storing it in a plaintext file, and even offer 2FA. That way even if the binary is taken over it is most likely the hacker wont be able to do anything with the token without 2FA authentication. This is a really strong way to protect your software repos in your organisation and you probably really shouldn’t be without it under nearly any circumstance; remember security first, functionality second.
Installing Github Credential Manager
So there are a few ways to do this, the two I think are best is either to use your standard repoistory manager (yum), and if that does not provide the package you should try tarball and compile it manually, failing that there is an automation script that github provide that will download all of the dependancies manually.
We are going to show how to do both but I prefer tarball since there is maximum flexibility, control and vision with what is happening ;
Installing GCM Automagically
curl -L https://aka.ms/gcm/linux-install-source.sh | sh
git-credential-manager configure
For more detail refer to the official github repository instructions for GCM here https://github.com/git-ecosystem/git-credential-manager/blob/release/docs/install.md
Installing GCM Manually from Tarball
[github@localhost ~]$ wget https://github.com/git-ecosystem/git-credential-manager/releases/download/v2.6.1/gcm-linux_amd64.2.6.1.tar.gz
[github@localhost ~]$ sudo tar zxvf gcm-linux_amd64.2.6.1.tar.gz -C /usr/local/bin
As above you see the flags -C declaring the local path for the gcm linux binary executable. That’s important, if your not sure use /usr/local/bin or /bin or type echo $PATH to see what path your using already, and use that. Since /usr/local/bin sits outside of the users ~dir ensure you use sudo or the files may not be written.
export GCM_CREDENTIAL_STORE=cache
You will need to add this export line to your .bashrc or .bash_profile so git knows where to store the credentials.
git config --global credential.credentialStore cache
Now we are logged in we can create a brand new public repo on the remote github site;
$ gh repo create php-prime --public --clone
✓ Created repository youruser/somerepo on GitHub
https://github.com/youruser/somerepo
I’m using –clone, so that the github tool will automatically create a local version of the repo already setup on my machine. That’s pretty neat and super convenient if you have a lot of repos to add and don’t want to have to setup each one individually.
Let’s develop our software ‘somerepo’ for ‘youruser’ where somerepo is the repo name on git and youruser is your username path. All repos are in the format of github.com/user/repo for consistency. Github is indeed, very, very easy to use compared with early tools like SVN subversion, some of us like me are going grey and are unfortunately old enough to remember.heheheh
Since the GH tool has already initialise our repo it is just a case of touching our files, writing our code, comitting it and then pushing it to the github remote repo. It’s really simple to do;
[github@localhost php-prime]$ touch mysoftware
[github@localhost php-prime]$ touch find-primes.php
[github@localhost php-prime]$ vim find-primes.php
[github@localhost php-prime]$ git add *
[github@localhost php-prime]$ git commit -m 'just adding some stuff testing gh api'
[master (root-commit) 8a34e61] just adding some stuff testing gh api
2 files changed, 30 insertions(+)
create mode 100644 find-primes.php
create mode 100644 mysoftware
[github@localhost php-prime]$ git push
fatal: The current branch master has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin master
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.
[github@localhost php-prime]$ git push --set-upstream origin master
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 32 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 533 bytes | 533.00 KiB/s, done.
Total 4 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To github.com:aziouk/php-prime.git
* [new branch] master -> master
branch 'master' set up to track 'origin/master'.
[github@localhost php-prime]$ touch somechange
[github@localhost php-prime]$ git add somechange
[github@localhost php-prime]$ git commit -m 'added a file called somechange'
[master 17e2f29] added a file called somechange
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 somechange
[github@localhost php-prime]$ git push
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Delta compression using up to 32 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (2/2), 297 bytes | 297.00 KiB/s, done.
Total 2 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To github.com:aziouk/php-prime.git
8a34e61..17e2f29 master -> master
Because gh has done the heavy lifting, we can setup a repo with a remote in one line now.
So, that summarises how to install the gh api tool, setup authentication, credentials the credit store, and so on. Remember the credit store cache by default expires tokens used after only 900 seconds. In low medum security settings, or development environments or staging users which are already well locked down, it may be sane and safe to permit greater timelimit for the upper cache expiry, this ca be done like so; either by exporting the GCM_CREDENTIAL_CACHE_OPTIONS as a shell variable; which git runs with or thru the git configuration manually. I recommend the latter. Naturally change 300 to whatever value you would desire. Importantly remembering that if the data is sensitive one has to be careful how long the token expiry is. Certainly for a busy development environment, that has repos with strict permissions already, the security is secured at the user permission level, so the length of the token expiry is irrelevant. This is good, because it means your developers don’t want to murder the administrator of the github devops account. Remember some developers commit a lot, and it is not good practice to use a github user with great scope of permissions, much better to reduce the permissions, and assume that the token indefinitely lasts, that way if it is ever compromised its never a big deal.
export GCM_CREDENTIAL_CACHE_OPTIONS="--timeout 300"
# or
git config --global credential.cacheOptions "--timeout 300"
For more detail on using 2FA with github GCM see https://docs.github.com/en/authentication/securing-your-account-with-two-factor-authentication-2fa/configuring-two-factor-authentication