Is it necessary to store the personal access token somewhere locally on the machine after generating it in GitHub?
If yes, is there any preferred way where it could be
Well, you have to save the token somewhere, when you don't want to type it each time your app asks for it :-)
A good solution is using environment variables, as already suggested in one comment.
But you still have to set the environment variable somewhere.
On Windows (which I'm using), you could use the dialog box in the system settings (I don't know if other operating systems have something similar).
I don't do this, I prefer a script in my project.
In a private project, you may commit this to source control, but this is a matter of preference.
In one of my personal projects, I'm calling the GitHub API as well, using a personal access token.
It's a command line app and the end user will save the token in a config file (which is OK).
But I need the token for development as well, because the project has integration tests where I'm calling the GitHub API.
And that project is public on GitHub, so I couldn't save the token in source control.
What I did is this:
environment-variables.bat
which sets all required environment variables including the access tokenenvironment-variables.bat
is ignored in source controlSo I can just rename this file to environment-variables.bat
, replace the fake password by the real one, and everything works.
This is not the perfect solution for all cases, though.
In my project, I have the problem that I need to use more tokens/passwords for more APIs in the future.
So the number of tokens in my environment-variables.bat
will increase, making it difficult for potential contributors to actually execute all integration tests. And I still don't know how to deal with that.
In my case, in Ubuntu, the accepted solution didn't work with a message like
git: 'credential-manager' is not a git command
but store
instead of manager
worked well:
git config --global credential.helper store
Half the point of passwords is that (ideally) you memorize them and the system hashes them, so therefore they're never stored anywhere in plain text.
Yet GitHub's personal access token system seems to basically force you to store the token in plain text?
First, a PAT (Personal Access Token) is not a simple password, but an equivalent that:
That differs from your password, which is unique to your account, and cannot be easily changed without having to also modify it everywhere you happen to use it.
Since a PAT can be used in place of a password when performing Git operations over HTTPS with Git on the command line or the API, you can use a git credential helper to cache it securely.
On Windows, for instance, that would use the Windows Credential Manager, through the GCM -- Git Credential Manager -- for Windows:
git config --global credential.helper manager
The first time you are pushing to a repo, a popup will ask for your credentials: username and your PAT.
The next time, it won't ask, and reuse directly that PAT, which remains stored securely in your Credential Manager.
A similar idea applies for Mac with the OSX keychain, and Linux with the GNOME Keyring.
The idea remains: store the PAT in an encrypted credentials store.
The more modern soution (Q4 2020) is microsoft Git-Credential-Manager-Core
git config --global credential.helper manager-core
You need for that to install git-credential-manager-core
, downloading gcmcore-linux_amd64.2.0.252.766.deb
sudo dpkg -i <path-to-package>
git-credential-manager-core configure
Linux support is not fully implemented yet, but it will be soon.
Basically I did this on my machine:
https://gist.github.com/bsara/5c4d90db3016814a3d2fe38d314f9c23
My profile script is slightly different than described:
env=~/.ssh/agent.env
agent_load_env () { test -f "$env" && . "$env" >| /dev/null ; }
agent_start () {
(umask 077; ssh-agent >| "$env")
. "$env" >| /dev/null ;
}
agent_load_env
# agent_run_state: 0=agent running w/ key; 1=agent w/o key; 2= agent not running
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)
if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
agent_start
ssh-add
elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
ssh-add
fi
unset env
I like to keep them encrypted within the repository and load them using .envrc
(https://direnv.net/)
For doing this I use ssh-vault to encrypt the data using my ssh keys that GitHub already is exposing, for example:
echo MY_TOKEN="secret" | ssh-vault -u <github-user> create > my-encypted-vars.ssh
Then the content of .envrc
looks something like this:
echo "Enter ssh key password"
context=$(ssh-vault view $HOME/projects/my-encrypted.ssh | tail -n +2)
export ${context}
This will decrypt the data in my-encrypted-vars.ssh
file and set MY_TOKEN
into my environment variables every time I cd
into the project dir.
By doing this tokens/variables are stored "safely" and always ready to use as environment variables