Skip to content

hub doesn't recognize credentials in cache #1217

Open

Description

@0xmohit

I've setup a credential helper for git as specified in https://help.github.com/articles/caching-your-github-password-in-git/

Using git, it works as expected and doesn't ask the password as per the timeout settings.

However, hub prompts for the username/password:

$  hub clone myorg/somerepo
github.com username: ^C
$  hub version
git version 2.5.0
hub version 2.2.0-238-gc25e33e

Activity

  1. changed the title [-]hub doesn[/-] [+]hub doesn't recognize credentials in cache[/+] on Jul 29, 2016
  2. mislav commented on Sep 13, 2016

    @mislav
    Owner

    Sorry; I forgot to reply to your issue when I viewed this last.

    As confusing as the authentication situation is now, this is actually expected behavior right now. With git and hub, you're authenticating in two different ways: one is for the git protocol used for cloning/pushing (protocols supported: git:, ssh:, https:) and the other is for hub's API access (protocols supported: https:).

    I want to make this more user friendly, of course. Such as, if you have the password cached in credential helper like you described, we can try reusing it. The only problem is that the "password" you use in git credential cache might not be a real password, but a personal access token with clone privileges. Such token is necessary for accounts that use 2-factor authentication. This token is useless for hub because it doesn't have sufficient privileges to do all needed API operations.

  3. mislav commented on Dec 24, 2016

    @mislav
    Owner

    Cross-linking these notes here as a TODO item: how to implement the credential helper protocol #630 (comment)

    /cc @elyscape @technomancy so you follow this thread instead of the other one, which is closed

  4. technomancy commented on Dec 28, 2016

    @technomancy

    The tricky part of implementing this is going to be deciding what to do with existing credentials that might be stored for https://github.com/, but which are a Personal Access Token that someone generated for git cloning purposes only

    Can you explain in a little more detail what you mean here? Are you talking specifically about "what if this happens and it causes an error, and the user doesn't know that he needs to replace his existing limited token with one that has full access"? Or do you mean that having a limited token live side-by-side with a full hub-capable token is a legitimate use case that we need to support?

  5. elyscape commented on Dec 28, 2016

    @elyscape

    One way to deal with this would be to check for an existing token and, if one is present, check the permissions on it. Example:

    scapeless:~ elyscape$ git credential fill
    protocol=https
    host=github.com
    
    protocol=https
    host=github.com
    username=elyscape
    password=[TOKEN]
    scapeless:~ elyscape$ curl -s -I -H 'Authorization: token [TOKEN]' https://api.github.com/ | grep 'X-OAuth-Scopes:'
    X-OAuth-Scopes: repo

    When you make a request to the GitHub API, it returns a header X-OAuth-Scopes, the value of which is the list of the scopes that have been applied to the token, separated by a comma and a space. If one of the scopes is repo, the token has all the permissions we need. Otherwise, we'll need to generate a new token. As for how to store that token alongside an existing one, we could store it with a custom path:

    scapeless:~ elyscape$ git -c credential.useHttpPath=true credential approve
    protocol=https
    host=github.com
    path=.hub
    username=elyscape
    password=new-token
    
    scapeless:~ elyscape$ git -c credential.useHttpPath=true credential fill
    protocol=https
    host=github.com
    path=.hub
    
    protocol=https
    host=github.com
    path=.hub
    username=elyscape
    password=new-token

    Git by default filters out paths if the protocol is HTTP(S), so we have to force credential.useHttpPath to true on the commands to ensure that we don't override any existing tokens. We use a path that's invalid as an actual repository on GitHub to avoid overriding any tokens if there a particular repo sets credential.useHttpPath to true or the user has it set that way system-wide. Here's what happens under those conditions:

    scapeless:~ elyscape$ git credential fill
    protocol=https
    host=github.com
    path=elyscape/dotfiles.git
    
    protocol=https
    host=github.com
    username=elyscape
    password=[TOKEN]
  6. elyscape commented on Dec 28, 2016

    @elyscape

    As a side note, this is one instance where GitHub's somewhat-anemic permissions model for Personal Access Tokens helps us, as the only way to give a token access to private repositories is to give it full repo access. As such, most people that are using a personal access token for GitHub access will probably have given it repo access, allowing us to reuse it.

  7. biochimia commented on May 16, 2017

    @biochimia

    I ended up here while trying to determine if hub supported loading credentials from a ~/.netrc file.

    One way to distinguish a limited token used only for cloning from a token used for API access could be through the hostname, assuming the cloning-only token would be using github.com, while a token for API access could be more specifically tied to api.github.com.

    This would still leave the problem open for Github Enterprise installations, where API is behind an /api/v3 path, and not usually a separate api.* domain.

  8. segevfiner commented on Feb 14, 2019

    @segevfiner

    Storing the token as plain text isn't all that secure, this should really be supported.

  9. sj26 commented on Jul 27, 2019

    @sj26

    I made a reeeeeally rough version of this that works in the positive case when a GitHub personal token has already been saved in the git credential helper (I use osxkeychain):

    master...sj26:git-credentials

    I store my personal access token as my password for github.com in git credentials. But I love the idea of using api.github.com. That's a little tricky to interoperate with GitHub enterprise and api subdomains versus api paths.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions