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 stored?
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 stored?
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, Mac or Linux:
git config --global credential.helper manager-core
# Git 2.39+
git config --global credential.helper manager
(manager-core is being replaced by/renamed as manager for Git 2.39+, Q4 2022)
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 (in 2021, it would need a DBus session and libsecret
), but in 2021, GCM-Core covers those use cases.
The idea remains: store the PAT in an encrypted credentials store.
As mentioned above, the more modern solution (Q4 2020) is Microsoft Git-Credential-Manager-Core, or, Q4 2022, Microsoft Git-Credential-Manager
git config --global credential.helper manager-core
# Git 2.39+:
git config --global credential.helper manager
Before Git 2.39 (Q4 2022), for Linux:
You need for that to install git-credential-manager-core
, downloading its latest release, like gcmcore-linux_amd64.2.0.474.41365.deb
sudo dpkg -i <path-to-package>
git-credential-manager-core configure
Although, with GCM (Git-Credential-Manager-Core) on Linux, as noted by Mekky Mayata in the comments, you need to define a git config --global credential.credentialStore
first.
See "Credential stores on Linux":
There are four options for storing credentials that Git Credential Manager (GCM) manages on Linux platforms:
- freedesktop.org Secret Service API
- GPG/
pass
compatible files- Git's built-in credential cache
- Plaintext files
By default, GCM comes not configured.
You can select which credential store to use by setting theGCM_CREDENTIAL_STORE
environment variable, or thecredential.credentialStore
Git configuration setting.
As noted by agent18 in the comments, using git-credential-libsecret
after installing libsecret-1-0
and libsecret-1-dev
is a good first step.
But, again, that should be now wrapped by credential-manager-core
(before Git 2.39).
git push
: /var/tmp/.net/user/git-credential-manager-core/unqypyc0.awl/git-credential-manager-core get: 1: /var/tmp/.net/user/git-credential-manager-core/unqypyc0.awl/git-credential-manager-core: not found
–
Footlights git-credential-manager-core
? Is it in your $PATH
? –
Arlie $ dpkg -l | grep gcm
gives me ii gcmcore 2.0.318.44100 amd64
–
Footlights git-credential-manager-core
anywhere on your system? –
Arlie /var/tmp/.net/user/git-credential-manager-core/unqypyc0.awl/git-credential-manager-core.dll
–
Footlights wget
to download and dpkg -i
to install. –
Footlights git config -e --global
and adding a credentialStore value (plaintext, gpg, secretservice) to it. thanks @Arlie –
Illuminometer credential.credentialStore
), I don't think the default timeout would apply though. I need to test that. –
Arlie git config --global credential.helper manager-core
, with, on Linux, an additional credential.credentialStore
configured. It does work well and is a cross-platform credential helper. –
Arlie manager-core
is being deprecated and replaced with manager
. –
Arlie .yml
file? –
Hormuz GITHUB_TOKEN
secret. –
Arlie 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
Note that you will be prompted to introduce your credentials again the next time you use git before the credential manager saves them.
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, Mac or Linux:
git config --global credential.helper manager-core
# Git 2.39+
git config --global credential.helper manager
(manager-core is being replaced by/renamed as manager for Git 2.39+, Q4 2022)
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 (in 2021, it would need a DBus session and libsecret
), but in 2021, GCM-Core covers those use cases.
The idea remains: store the PAT in an encrypted credentials store.
As mentioned above, the more modern solution (Q4 2020) is Microsoft Git-Credential-Manager-Core, or, Q4 2022, Microsoft Git-Credential-Manager
git config --global credential.helper manager-core
# Git 2.39+:
git config --global credential.helper manager
Before Git 2.39 (Q4 2022), for Linux:
You need for that to install git-credential-manager-core
, downloading its latest release, like gcmcore-linux_amd64.2.0.474.41365.deb
sudo dpkg -i <path-to-package>
git-credential-manager-core configure
Although, with GCM (Git-Credential-Manager-Core) on Linux, as noted by Mekky Mayata in the comments, you need to define a git config --global credential.credentialStore
first.
See "Credential stores on Linux":
There are four options for storing credentials that Git Credential Manager (GCM) manages on Linux platforms:
- freedesktop.org Secret Service API
- GPG/
pass
compatible files- Git's built-in credential cache
- Plaintext files
By default, GCM comes not configured.
You can select which credential store to use by setting theGCM_CREDENTIAL_STORE
environment variable, or thecredential.credentialStore
Git configuration setting.
As noted by agent18 in the comments, using git-credential-libsecret
after installing libsecret-1-0
and libsecret-1-dev
is a good first step.
But, again, that should be now wrapped by credential-manager-core
(before Git 2.39).
git push
: /var/tmp/.net/user/git-credential-manager-core/unqypyc0.awl/git-credential-manager-core get: 1: /var/tmp/.net/user/git-credential-manager-core/unqypyc0.awl/git-credential-manager-core: not found
–
Footlights git-credential-manager-core
? Is it in your $PATH
? –
Arlie $ dpkg -l | grep gcm
gives me ii gcmcore 2.0.318.44100 amd64
–
Footlights git-credential-manager-core
anywhere on your system? –
Arlie /var/tmp/.net/user/git-credential-manager-core/unqypyc0.awl/git-credential-manager-core.dll
–
Footlights wget
to download and dpkg -i
to install. –
Footlights git config -e --global
and adding a credentialStore value (plaintext, gpg, secretservice) to it. thanks @Arlie –
Illuminometer credential.credentialStore
), I don't think the default timeout would apply though. I need to test that. –
Arlie git config --global credential.helper manager-core
, with, on Linux, an additional credential.credentialStore
configured. It does work well and is a cross-platform credential helper. –
Arlie manager-core
is being deprecated and replaced with manager
. –
Arlie .yml
file? –
Hormuz GITHUB_TOKEN
secret. –
Arlie Alternatively, you can create a ~/.netrc
file in home directory and save your login credentials to it.
cat ~/.netrc
machine github.com login <login-id> password <token-password>
.netrc
and have the contents as shown in the answer. If you are using windows then please try this stackoverflow.com/questions/6031214/… –
Slumberous .netrc
. The syntax is well documented. But one does not use it because its a flat file that even with 0600
perms sits on the filesystem with passwords in clear text that every process ran as that user can abutraily read. –
Crossbow ~/.netrc
, which is just as good as the answer above which stores credentials in ~/.git-credentials
. Use at your own risk, but that can be handy nonetheless. –
Elan To store your credentials in cache and avoid logging in every time you perform a git action, follow these steps:
git config --global --replace-all credential.helper cache
git push
or git pull
.git push
or any git action and you'll find that it doesn't ask for login credentials from now on.Tested on Ubuntu 20.04, almost fresh install, with Git 2.25.1 and unity 7.5.
Authentication basics
Github needs an authentication key (with certain rights tied to said authentication key). A particular auth key has certain rights, (read private repos, read write public repos etc...) and "acts as a password" coupled with rights which can be revoked whenever the user wants.
Personal Access Token
git push
the repo and type the generated token(very long password) as password when asked.Storing the password in different ways
xclip
to bring it back to clipboard and paste it everytime (Screw this)git config credential.helper cache <time-limit-of-cache>
. But you still have to somehow clipboard the password after the timelimit.git config credential.helper store
(don't use --global). This is NOT ENCRYPTED. You can open the file and read it. (e.g., If someone gets access to your laptop they can pretty much read the Password using a bootable USB (assuming your whole system is not encrypted)).sudo apt-get install libsecret-1-0 libsecret-1-dev
sudo make --directory=/usr/share/doc/git/contrib/credential/libsecret
git config credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret
This allows to store the password/personal access token in an encrypted format. The git config
file can be found in the .git/config
file in your loca repo as shown here, if you ever need it.
P.S. There are many places that suggest the use of Gnome-keyring but that is apparently deprecated.
Storing passwords/PATs for more than one account
This becomes tricky and it appears as @VonC suggests that we need a Git-Credential-Manager core
(GCM core). This answer is enhanced based on my findings in this answer.
First install GCM core
sudo dpkg -i <path-to-package>
git-credential-manager-core configure
git config --global credential.credentialStore secretservice
as we use libsecret
Get latest git
In my case I had git 2.25 and got error error: unknown option 'show-scope'
. It appears that GCM core is using higher git
(atleast 2.26).
So install the latest and greatest git
as per here:
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
apt list git # shows the latest git currently 2.31
sudo apt-get install git #or sudo apt-get upgrade
Update git remote path with username built in
GCM core needs this to identify the different accounts.:(
git remote set-url origin https://[email protected]/user1/myRepo1.git
git remote set-url origin https://[email protected]/user1/myRepo1.git
^^^^^
Your ~/.gitconfig
file will thus have the following :
[credential]
helper = /usr/bin/git-credential-manager-core
credentialStore = secretservice
[credential "https://dev.azure.com"]
useHttpPath = true
git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret erase
before and then save the new token. I was already using libsecret –
Blighter git remote set-url origin https://username:[email protected]/username/repo.git
–
Perspiration 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
my-encrypted-vars.ssh
in .git
to avoid checking it in into source –
Rabbitry try enabling this to help with persisting across push / pulls
git config credential.helper store
For ongoing cloning of repo / for macOS users / install iTerm2 https://iterm2.com/
Enable Toolbelt
Just click the snippet whenever you need it. P.S. you are using oh-my-zsh, aren't you? https://github.com/ohmyzsh/ohmyzsh
Use git insteadOf. Basically replace every https://github call with your access tokens + https://
git config --global url."https://<username>:<github-token>@github.com/".insteadOf "https://github.com/
Now every call to github will automatically be appended with your credentials.
I found this great answer in here. Some more info about git insteadOf.
You can cache your credentials for a defined time using:
git config --global credential.helper cache
The default cache period is 900 sec (15 min) but can be changed with:
git config --global credential.helper 'cache --timeout=3600'
See the following Github page:
https://docs.github.com/en/github/using-git/caching-your-github-credentials-in-git
This is not a permanent store and as per other comments credentials should not be stored in plain text, which is a security risk. I use a password manager (https://bitwarden.com/) to store the PAT (Personal Access Token) then copy it in for the first use, where it is then cached. A PAT is required if you enable 2FA on your Github account.
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 controlenvironment-variables.bat.sample
instead, which contains the same, but a fake token/password.So 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 use case, I store the PAT in a password manager, e.g. LastPass, KeePass, 1Password. When I need it in a Linux environment ( e.g. Docker ), I save the PAT in an environment variable and then use git's credential helper setting. For example:
git config --global credential.helper 'cache --timeout 600'
<< eof tr -d ' ' | git credential-cache store
protocol=https
host=github.com
username=nonce
password=${GITHUB_PAT}
eof
With a PAT the username can be anything except blank. Here's a gist that elaborates:
https://gist.github.com/rwcitek/da862e9e27cc28d3e96e62a2ca4b2b64
You can store the github https token using pass.
Two alternatives to map a git host to a pass entry:
pass
entry:#!/usr/bin/env bash
# assuming "get" action from git and a config like this
# git config --global credential.helper $XDG_BIN_HOME'/git_credentials_from_pass $@'
while IFS= read -r line
do
echo "$line"
if [[ "$line" =~ host=.*github.com.* ]]; then
echo "username=your_user_name"
echo "password=$(pass show token_github.com/your_username)"
#else ...
fi
done
Change your_username
and token_github.com
the way you set it up with pass insert
.
This adds the token to pass
without typing or pasting twice:
echo your_github_token | sed p | pass add token_github.com/your_username
git config --global credential.helper '!pass-git-helper $@'
pass-git-helper
needs an ini-file to map between the git
request and the pass
entry.
${XDG_CONFIG_HOME}/pass-git-helper/git-pass-mapping.ini
example:
[DEFAULT]
username_extractor=entry_name
[github.com*]
target=token_${host}/your_github_username
curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null
sudo apt update
sudo apt install gh
gh auth login
it will ask to enter the protocol and token
Then I clones the repo again . Its not asking for token
For Storing PAT you can use gh library
Installation
conda install -c conda-forge gh -y
Once the installation is complete, type this command:
gh auth login
Use the arrow and enter keys to navigate a series of prompts.
What account do you want to log into?
> Github.com
GitHub Enterprise Server
What is your preferred protocol for Git operations?
> HTTPS
SSH
Authenticate Git with your GitHub credentials? (Y/n)
How would you like to authenticate GitHub CLI?
Login with a web browser
> Paste an authentication token
Now you’ve added your token — this will make pulling and pushing code a lot easier!
Install Git Credential Manager! https://github.com/GitCredentialManager/git-credential-manager . GCM supports caching as well as a variety of platform-specific credential stores that persist between sessions.
Even better: GCM supports user-friendly secure authentication to GitHub and GitLab via web browser with OAuth. This means you no longer even need to create personal access tokens. When you git push, simply follow a link to GitHub and authorize the app. Subsequent authentications require no interaction.
OAuth is more secure than personal access tokens, because the tokens have short expiry, refreshed when required using longer-lived refresh tokens.
I resort to an unorthodox solution.
I have saved it in my Telegram Saved Messages
. Every time one expires, I create a new one and edit the message. I feel It's secure, as long as I don't lose access to my Telegram.
The easiest way on windows is to:
That's an extremely simple way to get git/windows to remember your GitHub personal access token!
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
© 2022 - 2024 — McMap. All rights reserved.
sudo apt-get install libsecret-1-0 libsecret-1-dev
;cd /usr/share/doc/git/contrib/credential/libsecret
;sudo make
;git config --global credential.helper /usr/share/doc/git/contrib/credential/libsecret/git-credential-libsecret
; Have a look here: https://mcmap.net/q/13472/-how-to-use-git-with-gnome-keyring-integration – Lawlorgit push
and now enforces using a token instead. So now we have to store the token in plain text or use a credential helper to store it for you. In any case, a person accessing your computer now has write access to your repo. - Back when I could just use a password that I have to enter every time, this particular security risk did not exist. And let's not forget that someone who knows my password could easily use that to create their own tokens. So in terms of security we don't gain anything, unless GitHub also decides to enforce 2FA. – Nonego