294

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.

3
  • 1
    What is the difference between "If I try this manually" and "If I try it on the commandline"? Commented Jun 28, 2019 at 11:12
  • Please correct the URI-token syntax, see stackoverflow.com/a/29570677/287948 Commented Jan 6, 2021 at 22:47
  • @PeterKrauss Linking to an unrelated thread seems a bit uncalled for, especially if it's a "closed" topic Commented Mar 11, 2021 at 14:50

15 Answers 15

396

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
Sign up to request clarification or add additional context in comments.

7 Comments

You can also use github Personal Access Token with this command in place of OAuth Key.
It used to work fine for me with classical personal access token, but as of 18th of October, GitHub released also fine-grained personal access token and it looks like for them, you have to use git clone https://oauth2:<oauth-key-goes-here>@github.com/username/repo.git
Wow. I wonder how the heck this is supposed to work with package managers like composer where the repository info is configured in plain-text JSON. I can't believe that Github doesn't provide a way to pass the key discreetly i.e. through the COMPOSER_AUTH environment variable...kind of defeats the purpose of an organization service user use case.
The way with …username:token… worked for Gitlab as well!
I can still use fine-grained PAT without oauth2:
|
130

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.

3 Comments

Mind that if you simply try to access the repo page through a browser you'll still face a 404-not found page. But cloning worked fine regardless in my case.
I provided a scope of user repo to the authorization request, and when requesting an access token it always returns with scope= (empty scope). Why is that?
It may seem that there is no way to avoid write access using a Github security token, which is kind of a security limitation for scripts and other integrations where just cloning a private repo is required :(
73

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.

6 Comments

It is not the answer, the problem is about use the token, see stackoverflow.com/a/29570677/287948
you can use the token in the URL as [email protected]/username/repo.git
well....worked for github too... Guess it is supposed to be used.. like more of a appPassword with every URL Thanks Anyway
Worth to say you can use your personal token in place of password for any git command line action, not only clone
found a error => remote : repository not found
|
49

Please try this.

git clone `https://oauth2:[email protected]/username/repo.git`

For example, git clone https://oauth2:[email protected]/gituser/testrepo.git

5 Comments

it's working. please check the url carefully. @github.com/gituser/testrepo.git
This is way better than manually writing the username and password! I can save a github access token variable and user a script with git clone https://oauth:[email protected]/user/repo.git or just add the token itself to a script. Underrated answer here.
I get ` remote: Invalid username or password` when using an organization repo :( git clone https://oauth2:[email protected]/MyOrg/repo.git
@AKingscote, please check if your key is correct and not expired.
token starting with ghp seems not be a new fine grained token, ghp is for classic token, which is easy to use but some orga disable it for security concern. The new fine grained token starts with github_pat_ where I have pain to use it even for git clone
32

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)

enter image description here

👍

2 Comments

Using token as username worked for me on windows
I had to use my real username as username and token as a password, not username as of now, maybe I had initially some redundant space in it, or it takes a little while, while the token activation takes places
28

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).

3 Comments

remote : repository not found
this works for me. i had a dialog for it and after closing it the only way was putting the token in the url. thanks
It used to work fine for me with classical personal access token, but as of 18th of October, GitHub released also fine-grained personal access token and it looks like for them, you have to use git clone https://oauth2:<token>@github.com/owner/repo.git
10

For lazy folks like future me:

  1. Generate your "Personal access tokens (classic)" from https://github.com/settings/tokens and copy it. (This will behave like password in next steps.)

  2. 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
    
  3. 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.

5 Comments

Note that manager-core should be, from Git 2.39+, manager (no longer manager-core). And your second git config --global credential.helper command would override your first command anyway.
I can not thank enough to past me. This answer was useful 4 times within the last one month only. (I set up 4 different cloud machines, and each time I came here to do this stuff. Thank you past me, I love you!)
Hey past me! You are the man. I mean it; YOU ARE THE MAN! 👍
Hey past me, somehow this answer is having upvotes more frequently, possibly it is being referenced by LLMs. Hey future me; if you learn anything, please inform us.
you saved me again today
4

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!

1 Comment

Why there's so many ways to do this? Optional oauth2:, and now token first. Is there any docs for this?
3

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:

  1. Create a readonly token (content: readonly)
  2. Make sure the resource owner is properly set.
  3. For organizations, you have to complete "personal-access-tokens-onboarding".
  4. Clone the repository using https://oauth2:[email protected]/myuser/myrepo.git (note the username, as suggested by others, it's oauth2)

With all of the above, I managed to clone a private repository with a readonly token (and no, there was no write access 🙂)

1 Comment

what d you mean by complete "personal-access-tokens-onboarding" (i am using an organization)?
3

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.

Comments

2

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);
        }

Comments

2

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/

Comments

2

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 attribute oauth_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) and git-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 that credential 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 attributes

Signed-off-by: M Hickford

d208bfd (credential: new attribute password_expiry_utc, 2023-02-18, Git v2.40.0-rc1 -- merge) and a5c7656 (credential: new attribute oauth_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 attributes

Signed-off-by: M Hickford

d208bfd (credential: new attribute password_expiry_utc, 2023-02-18, Git v2.40.0-rc1 -- merge) (credential: new attribute password_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 attribute oauth_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: store oauth_refresh_token

Signed-off-by: M Hickford

a5c7656 ("credential: new attribute oauth_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" when t0303-credential-external.sh is run with GIT_TEST_CREDENTIAL_HELPER=wincred.
This test was added in a5c7656 (credential: new attribute oauth_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 password

Signed-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 when t0303-credential-external.sh is run with GIT_TEST_CREDENTIAL_HELPER=libsecret.

Retrieve empty password carefully.
This fixes test:

ok 14 - helper (libsecret) can store empty username

Comments

0

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

Comments

-1

for Bit Bucket use this:

git clone https://x-token-auth:<TOKEN>@bitbucket.org/<USER-NAME>/<REPO>.git

make sure you enter all the detail correctly and have proper repo permissions

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.