Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add ssh-keys via GitHub's v3 API?

I'm trying to add an ssh key via GitHub's v3 API, but it doesn't seem to be working.

What I'm doing is based on the instructions given here.

More specifically, I'm using the following:

KEY=$( cat ~/.ssh/id_rsa.pub )
TITLE=${KEY/* }
# the '/* ' above deletes every character in $KEY up to and including the last
# space.

JSON=$( printf '{"title": "%s", "key": "%s"}' "$TITLE" "$KEY" )

TOKEN=$( cat /path/to/tokenfile )

curl -s -d "$JSON" "https://api.github.com/user/keys?access_token=$TOKEN"

When I run the above, the response I get is:

{
  "message": "Not Found"
}

...and, sure enough, when I check in my GitHub account, $KEY is not among the ssh-keys listed1.

 

 

What am I doing wrong?

 

 

Additional details

I get the same "message": "Not Found" response if I just run

curl -s "https://api.github.com/user/keys?access_token=$TOKEN"

If I replace the -s above with -i I see that, indeed, the returned status is 404 Not Found. And yet, the returned status for

curl -i "https://api.github.com/user/keys"

is 401 Unauthorized.


1 I know that the access token in $TOKEN is fine, and therefore it is not the reason for the "message": "Not Found" response, because

curl -s "https://api.github.com/user/repos?access_token=$TOKEN"

returns the correct information, and

curl -s "https://api.github.com/user/repos"

returns

{
  "message": "Requires authentication"
}
like image 333
kjo Avatar asked May 21 '13 14:05

kjo


2 Answers

Does your access token have "user" scope? A relevant excerpt from the docs:

Management of public keys via the API requires that you are authenticated through basic auth, or OAuth with the ‘user’ scope.

If your token does not have "user" scope, you will get a 404 response with a message of "Not Found".

To see the scopes associated with your tokens, use the "Authorizations" API:

curl -u <username> https://api.github.com/authorizations

In the example response below, the first authorization has "user" scope, but the second one does not.

enter code here
[
  {
    "id": 123,
    "url": "https://api.github.com/authorizations/123",
    "app": {
      "name": "Foo",
      "url": "https://foo.example.com/",
      "client_id": "REDACTED-ID-1"
    },
    "token": "REDACTED-TOKEN-1",
    "note": null,
    "note_url": null,
    "created_at": "2013-02-18T18:24:00Z",
    "updated_at": "2013-05-06T14:17:00Z",
    "scopes": [
      "repo",
      "user"
    ]
  },
  {
    "id": 456,
    "url": "https://api.github.com/authorizations/456",
    "app": {
      "name": "Bar",
      "url": "https://bar.example.com/",
      "client_id": "REDACTED-ID-2"
    },
    "token": "REDACTED-TOKEN-2",
    "note": "for stuff",
    "note_url": null,
    "created_at": "2013-04-16T12:20:00Z",
    "updated_at": "2013-05-13T21:28:00Z",
    "scopes": [
      "public_repo"
    ]
  }
]

If you determine that this is the source of your problem, then you can resolve it in one of two ways:

  • Create a new token that has "user" scope, or
  • Update your existing token to add the "user" scope to it: "add_scopes": [ "user" ]
like image 100
jasonrudolph Avatar answered Oct 24 '22 14:10

jasonrudolph


As of February 2014 the "user" scope no longer provides enough access to manage a user's SSH keys. The scope must be defined as:

  • read:public_key - provides read access to the user’s SSH keys
  • write:public_key - allows an app to read existing keys and create new ones
  • admin:public_key - enables an app to read, write, and delete keys
like image 29
heathsnow Avatar answered Oct 24 '22 13:10

heathsnow