Reputation: 20329
Inside a script I am trying to clone a GitHub repository with an OAuth token.
According to this tutorial:
https://github.com/blog/1270-easier-builds-and-deployments-using-git-over-https-and-oauth
I should be able to build a command for it like this:
git clone https://<token>@github.com/owner/repo.git
If I try this manually with a proper access token, it still asks for my password.
If I try it on the commandline I am simply getting a repository not found
error.
The article is from 2012 and I cannot find any API documentation for this. So I am wondering if this still works.
Upvotes: 285
Views: 708198
Reputation: 1
The command-line to clone repo is as in below format
git clone https://oauth2:<your-token>@<github-clone-path-without-https-and-slash>
For example, you want to clone github : https://github.com/nimeshgit/myrepo.git and you have a token : AABBCD-XXYY-ZZ
then you can clone repo with below command line:
git clone https://oauth2:[email protected]/nimeshgit/myrepo.git
Upvotes: -1
Reputation: 457
Go to this link: https://github.com/settings/tokens
then copy the token and prepare following command and run it into bash
git clone https://<username>:<token>/<username>/<reponame>.git
Upvotes: 0
Reputation: 1328122
That should be better supported with Git 2.41 (Q2 2023), the credential subsystem learns to help OAuth framework.
See commit a5c7656 (21 Apr 2023) by M Hickford (hickford
).
(Merged by Junio C Hamano -- gitster
-- in commit 2ca91d1, 10 May 2023)
credential
: new attributeoauth_refresh_token
Signed-off-by: M Hickford
Git authentication with OAuth access token is supported by every popular Git host including GitHub, GitLab and BitBucket.
Credential helpers Git Credential Manager (GCM) andgit-credential-oauth
generate OAuth credentials.
Following RFC 6749, the application prints a link for the user to authorize access in browser.
A loopback redirect communicates the response including access token to the application.For security, RFC 6749 recommends that OAuth response also includes expiry date and refresh token.
After expiry, applications can use the refresh token to generate a new access token without user reauthorization in browser.
GitLab and BitBucket set the expiry at two hours.
(GitHub doesn't populate expiry or refresh token.)However the Git credential protocol has no attribute to store the OAuth refresh token (unrecognised attributes are silently discarded).
This means that the user has to regularly reauthorize the helper in browser.
On a browserless system, this is particularly intrusive, requiring a second device.Introduce a new attribute
oauth_refresh_token
.
This is especially useful when a storage helper and a read-only OAuth helper are configured together.
Recall thatcredential fill
calls each helper until it has a non-expired password.helper = storage # eg. cache or osxkeychain helper = oauth
The OAuth helper can use the stored refresh token forwarded by
credential fill
to generate a fresh access token without opening the browser.
See https://github.com/hickford/git-credential-oauth/pull/3/files for an implementation tested with this patch.Add support for the new attribute to credential-cache.
Eventually, I hope to see support in other popular storage helpers.Alternatives considered: ask helpers to store all unrecognised attributes.
This seems excessively complex for no obvious gain.
Helpers would also need extra information to distinguish between confidential and non-confidential attributes.Workarounds: GCM abuses the helper get/store/erase contract to store the refresh token during credential get as the password for a fictitious host (I wrote this hack).
This workaround is only feasible for a monolithic helper with its own storage.
git credential
now includes in its man page:
oauth_refresh_token
An OAuth refresh token may accompany a password that is an OAuth access token. Helpers must treat this attribute as confidential like the password attribute. Git itself has no special behaviour for this attribute.
With Git 2.43 (Q4 2023), the way authentication related data other than passwords (e.g. oath token and password expiration data) are stored in libsecret keyrings has been rethought.
See commit 0ce02e2 (16 Jun 2023) by M Hickford (hickford
).
(Merged by Junio C Hamano -- gitster
-- in commit e839608, 28 Aug 2023)
credential/libsecret
: store new attributesSigned-off-by: M Hickford
d208bfd (
credential
: new attributepassword_expiry_utc
, 2023-02-18, Git v2.40.0-rc1 -- merge) and a5c7656 (credential
: new attributeoauth_refresh_token
, 2023-04-21, Git v2.41.0-rc0 -- merge listed in batch #18) introduced new credential attributes.libsecret assumes attribute values are non-confidential and unchanging, so we encode the new attributes in the secret, separated by newline:
hunter2 password_expiry_utc=1684189401 oauth_refresh_token=xyzzy
This is extensible and backwards compatible.
The credential protocol already assumes that attribute values do not contain newlines.Alternatives considered: store
password_expiry_utc
in a libsecret attribute.
This has the problem that libsecret creates new items rather than overwrites when attribute values change.
With Git 2.43 (Q4 2023), the way authentication related data other than passwords (e.g. oath token and password expiration data) are stored in libsecret keyrings has been rethought.
See commit 0ce02e2 (16 Jun 2023) by M Hickford (hickford
).
(Merged by Junio C Hamano -- gitster
-- in commit e839608, 28 Aug 2023)
credential/libsecret
: store new attributesSigned-off-by: M Hickford
d208bfd (
credential
: new attribute password_expiry_utc, 2023-02-18, Git v2.40.0-rc1 -- merge) (credential: new attributepassword_expiry_utc,
2023-02-18) and a5c7656 (credential
: new attribute oauth_refresh_token, 2023-04-21, Git v2.41.0-rc0 -- merge listed in batch #18) (credential: new attributeoauth_refresh_token)
introduced new credential attributes.libsecret assumes attribute values are non-confidential and unchanging, so we encode the new attributes in the secret, separated by newline:
hunter2 password_expiry_utc=1684189401 oauth_refresh_token=xyzzy
This is extensible and backwards compatible.
The credential protocol already assumes that attribute values do not contain newlines.Alternatives considered: store
password_expiry_utc
in a libsecret attribute.
This has the problem that libsecret creates new items rather than overwrites when attribute values change.
With Git 2.44 (Q1 2024), batch 15, the wincred credential backend has been taught to support OAuth refresh token the same way as credential-cache and credential-libsecret backends.
See commit f061959 (28 Jan 2024) by M Hickford (hickford
).
(Merged by Junio C Hamano -- gitster
-- in commit bec9160, 08 Feb 2024)
credential/wincred
: storeoauth_refresh_token
Signed-off-by: M Hickford
a5c7656 ("
credential
: new attributeoauth_refresh_token)
introduced a new confidential credential attribute and added support to credential-cache.
Later 0ce02e2f (credential/libsecret: store new attributes", 2023-06-16, Git v2.41.0-rc0 -- merge listed in batch #18) added support in credential-libsecret.To add support in credential-wincred, we encode the new attribute in the
CredentialBlob
, separated by newline:hunter2 oauth_refresh_token=xyzzy
This is extensible and backwards compatible.
The credential protocol already assumes that attribute values do not contain newlines.This fixes test "helper (wincred) gets
oauth_refresh_token"
whent0303-credential-external.sh
is run withGIT_TEST_CREDENTIAL_HELPER=wincred
.
This test was added in a5c7656 (credential: new attributeoauth_refresh_token,
2023-04-21).Alternatives considered: store
oauth_refresh_token
in a wincred attribute.
This would be insecure because wincred assumes attribute values to be non-confidential.
With Git 2.45 (Q2 2024), batch 2, credential helper based on libsecret
(in contrib/
) has been updated to handle an empty password correctly.
See commit 8f1f202 (19 Feb 2024) by M Hickford (hickford
).
(Merged by Junio C Hamano -- gitster
-- in commit 70dadd5, 27 Feb 2024)
libsecret
: retrieve empty passwordSigned-off-by: M Hickford
Since 0ce02e2 ("
credential/libsecret
: store new attributes", 2023-06-16, Git v2.43.0-rc0 -- merge) a test that stores empty username and password fails whent0303-credential-external.sh
is run withGIT_TEST_CREDENTIAL_HELPER=libsecret
.Retrieve empty password carefully.
This fixes test:ok 14 - helper (libsecret) can store empty username
Upvotes: 1
Reputation: 5420
Just use the HTTPS address to clone with the key as the user, so:
git clone https://oauth2:[email protected]/username/repo.git
or
git clone https://username:[email protected]/username/repo.git
Upvotes: 376
Reputation: 2372
For lazy folks like future me:
Generate your "Personal access tokens (classic)" from https://github.com/settings/tokens and copy it. (This will behave like password in next steps.)
Run the following git command. It signals git to store the credentials (which will come in step 3)
git config --global credential.helper manager-core
git config --global credential.helper store
In your first clone you will be asked username and password provide your password coming from item 1 above:
git clone https://[email protected]/GithubUserName/repo-to-clone.git
For next git commands you should not be asked for credentials.
Upvotes: 10
Reputation: 137722
You need to include a username before the token. GitHub accepts any username. oauth2
works for both GitHub and GitLab.
git clone https://oauth2:[email protected]/owner/repo.git
However including credentials in https Git URL is considered bad practice because it risks inadvert credential exposure from config files and command history.
Also, it will break when the token expires. This is as short as two hours for hosts such as GitLab and BitBucket.
More secure and more reliable is to use a credential-generating helper such as Git Credential Manager (included in Git for Windows) or git-credential-oauth (included in several Linux distributions).
The first time you authenticate, the helper opens a browser window to the host. Subsequent authentication is non interactive.
These helpers refresh expired OAuth tokens as necessary.
Upvotes: 2
Reputation: 22553
As of Spring 2023, if you have your access token scopes set correctly, this is a one liner for cloning a repo (no need for any further interaction):
git clone https://ghp_foo_etc:[email protected]/bar/baz-phoenix.git
Where ghp_foo_etc is your access token. That's it! This is similar to how npm accesses code in private repos. Theres' no need to provide a user name.
I'm pretty certain its' always been so!
Upvotes: 4
Reputation: 5012
Just for those who still have problem "cloning a private repository with a readonly FG token: "remote: Write access to repository not granted."
The error message is a bit misleading. In my case the issue was with the configuration:
oauth2
)With all of the above, I managed to clone a private repository with a readonly token (and no, there was no write access 🙂)
Upvotes: 3
Reputation: 1763
For me none of the answers above worked. It turns out I had set an expiration of one month on my token so I had to recreate the token using the instructions here: https://www.shanebart.com/clone-repo-using-token/
Upvotes: 2
Reputation: 669
go to https://github.com/settings/tokens and generate a new token, remember to enable access to the repo, after that, you can do the following to clone the repo.
git clone https://<token>@github.com/owner/repo.git
Note: owner is your username if it's your repository else keep username of repository owner(one with all the rights of repo).
Upvotes: 27
Reputation: 1729
Please try this.
git clone `https://oauth2:[email protected]/username/repo.git`
For example, git clone https://oauth2:[email protected]/gituser/testrepo.git
Upvotes: 48
Reputation: 1193
Just clone the repository with HTTP like so:
git clone https://github.com/myuser/myrepo.git
When prompted for Username, fill your username.
When prompted for Password, fill the token instead.
Upvotes: 73
Reputation: 21
In .net core you can do in this way when dealing with Azure DevOps Repo:
public void CloneRepository()
{
var _gitURL = "URLofGitRemoteRepository";
var _userName = "PersonalAccessToken";
var _pswd = ""; //Keep it blank
var co = new CloneOptions();
co.CredentialsProvider = (_url, _user, _cred) => new UsernamePasswordCredentials { Username = _userName, Password = _pswd };
Repository.Clone(_gitURL, filePath, co);
}
Upvotes: 2
Reputation: 1042
Do whatever works for you from these two choices
In your terminal
$ git clone your_repo_url
Username:your_token
Password:
... there is no password
In your git client app
i.e. Sourcetree, GitKraken, and the GitHub client.
Enter your repo_url (obvsiously without the '$ git clone part')
Username:your_token
Password:
... there is no password
OR i.e. in Sourcetree, open preferences and then go to advanced, enter the hostname (i.e. www.x.com) and userName (i.e. your_token)
👍
Upvotes: 32
Reputation: 20329
I turned out to be a scope issue. I of course needed full repo
scope since I was trying to clone a private
repository.
It's a shame Github does not have some clearer error messages for these kind of things, but security wise I understand why.
For anyone trying to figure out what is wrong when trying out something like this, I would suggest to create a personal access token with full access to everything:
settings > developer settings > personal access tokens > generate new token
This way you can easily test if it is a scope issue by comparing your token with a personal access token that has access rights for everything.
Thanks for anyone who still took the time to read this.
Upvotes: 129