Skip to content

Commit 52c4764

Browse files
jasonrudolphgjtorikian
authored andcommitted
Sync changes from upstream repository
1 parent 6499e17 commit 52c4764

File tree

5 files changed

+208
-15
lines changed

5 files changed

+208
-15
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,8 @@ Some actions return arrays. You can modify the JSON by passing a block:
7777

7878
### Terminal blocks
7979

80-
You can specify terminal blocks with `pre.terminal` elements. (It'd be
81-
nice if Markdown could do this more cleanly.)
80+
You can specify terminal blocks with `pre.terminal` elements. (It'd be nice if
81+
Markdown could do this more cleanly.)
8282

8383
```html
8484
<pre class="terminal">
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
---
2+
kind: change
3+
title: Removing token attribute from Authorizations API responses
4+
created_at: 2014-12-08
5+
author_name: ptoomey3
6+
---
7+
8+
Since OAuth access tokens function like passwords, they should be treated with
9+
care. Today we are making it easier to more securely work with authorizations
10+
via the Authorizations API. We are deprecating the use use of the `token`
11+
attribute in the majority of the [Authorizations API](/v3/oauth_authorizations/)
12+
responses. For the [affected APIs][authorizations-token-deprecation-notice], the
13+
`token` attribute will soon return an empty string. To get ready for that
14+
change, we are giving developers a chance to
15+
[preview the updated API](#preview-period) starting today.
16+
17+
## What's changing?
18+
19+
The current [OAuth Authorizations API](/v3/oauth_authorizations/) requires GitHub to store the full value for
20+
each OAuth token on our servers. In order to increase the security for our
21+
users, we are changing our architecture to store the SHA-256 digest of OAuth
22+
tokens instead. GitHub securely hashes user passwords using bcrypt and we want
23+
to provide comparable security for OAuth tokens as well.
24+
25+
Rest assured that this change is an entirely proactive measure from GitHub and is not associated with any security incident.
26+
27+
## Who is affected?
28+
29+
This change affects any code that relies on accessing the `token` attribute from
30+
[these OAuth Authorizations API responses][authorizations-token-deprecation-notice].
31+
For example, our own [GitHub for Mac][github-for-mac] and
32+
[GitHub for Windows][github-for-windows] applications relied on reading the `token`
33+
from the [Get-or-create an authorization for a specific app][get-or-create-for-app] API, in order to support multiple installations of our desktop application for a single user.
34+
35+
## What should you do?
36+
37+
In order to reduce the impact of removing the `token` attribute, the OAuth
38+
Authorizations API has added a new request attribute (`fingerprint`), added
39+
three new response attributes (`token_last_eight`, `hashed_token`, and
40+
`fingerprint`), and added [one new API][get-or-create-for-app-fingerprint].
41+
While these new APIs and attributes do not replace the full functionality that
42+
previously existed, they can be used in place of `token` for most common use cases.
43+
44+
* `token_last_eight` returns the last eight characters of the associated OAuth
45+
token. As an example, `token_last_eight` could be used to display a list of
46+
partial token values to help a user manage their OAuth tokens.
47+
48+
* `hashed_token` is the base64 of the SHA-256 digest of the token.
49+
`hashed_token` could be used to programmatically validate that a given token
50+
matches an authorization returned by the API.
51+
52+
* `fingerprint` is a new optional request parameter that allows an OAuth
53+
application to create multiple authorizations for a single user. `fingerprint`
54+
should be a string that distinguishes the new authorization from others
55+
for the same client ID and user.
56+
57+
For example, to differentiate installations of a desktop application across
58+
multiple devices you might set `fingerprint` to
59+
`SHA256_HEXDIGEST("GitHub for Mac - MAC_ADDRESS_OF_MACHINE")`. Since
60+
`fingerprint` is not meant to be a user-facing value, you should still set
61+
the `note` attribute to help a user differentiate between authorizations on their
62+
[OAuth applications listing on GitHub][app-listing].
63+
64+
* [Get-or-create an authorization for a specific app and fingerprint][get-or-create-for-app-fingerprint]
65+
is a new API that is analagous to the
66+
[Get-or-create an authorization for a specific app][get-or-create-for-app]
67+
API, but adds support for the new `fingerprint` request parameter.
68+
69+
## Preview period
70+
71+
We are making the new Authorizations API available today for developers to
72+
preview. During this period, we may change aspects of these endpoints. If we do,
73+
we will announce the changes on the developer blog, but we will not provide any
74+
advance notice.
75+
76+
While these new APIs are in their preview period, you’ll need to provide the
77+
following custom media type in the Accept header:
78+
79+
application/vnd.github.mirage-preview+json
80+
81+
We expect the preview period to last 4-6 weeks. (Stay tuned to the developer blog for updates.) At the end of the preview period, these changes will become an official and stable part of GitHub API.
82+
83+
## Migration period
84+
85+
At the end of the preview period, we will announce the start of a migration period. Developers will have 8 weeks to update existing code to use the new APIs.
86+
87+
## Why SHA-256 over bcrypt?
88+
89+
Some users may be curious why we are not using bcrypt to hash our OAuth tokens
90+
like we do for user passwords. Bcrypt is purposefully computationally expensive
91+
in order to mitigate brute force attacks against low entropy passwords. However,
92+
OAuth tokens are highly random and are not susceptible to brute force attacks.
93+
Given that OAuth token validation occurs for each request to the API we chose
94+
SHA-256 for performance reasons.
95+
96+
If you have any questions or feedback, please [drop us a line][contact].
97+
98+
[contact]: https://github.com/contact?form[subject]=Removing+authorizations+token
99+
[app-listing]: https://github.com/settings/applications
100+
[create-a-new-authorization]: /v3/oauth_authorizations/#create-a-new-authorization
101+
[get-or-create-for-app]: /v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app
102+
[get-or-create-for-app-fingerprint]: /v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app-and-fingerprint
103+
[github-for-mac]: https://mac.github.com/
104+
[github-for-windows]: https://windows.github.com/
105+
[authorizations-token-deprecation-notice]: /v3/oauth_authorizations/#deprecation-notice

content/v3/oauth_authorizations.md

Lines changed: 89 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,51 @@ You can use this API to manage your OAuth applications. You can only access this
1111

1212
Make sure you understand how to [work with two-factor authentication](/v3/auth/#working-with-two-factor-authentication) if you or your users have two-factor authentication enabled.
1313

14+
<div class="alert">
15+
<h3 id="deprecation-notice">Deprecation Notice</h3>
16+
17+
<p>
18+
The <code>token</code> attribute is <a href="/v3/versions/#v3-deprecations">deprecated</a> in all
19+
of the following OAuth Authorizations API responses:
20+
</p>
21+
22+
<ul>
23+
<li><a href="#list-your-authorizations">List your authorizations</a></li>
24+
<li><a href="#get-a-single-authorization">Get a single authorization</a></li>
25+
<li><a href="#get-or-create-an-authorization-for-a-specific-app">Get-or-create an authorization for a specific app</a> - <code>token</code> is still returned for "create" </li>
26+
<li><a href="#get-or-create-an-authorization-for-a-specific-app-and-fingerprint">Get-or-create an authorization for a specific app and fingerprint</a> - <code>token</code> is still returned for "create" </li>
27+
<li><a href="#update-an-existing-authorization">Update an existing authorization</a></li>
28+
</ul>
29+
30+
<p>
31+
Please see <a href="/changes/2014-12-08-removing-authorizations-token/">the blog post</a> for full details.
32+
</p>
33+
34+
<p>
35+
In order to reduce the impact of removing the <code>token</code> attribute,
36+
the OAuth Authorizations API has added a new request attribute
37+
(<code>fingerprint</code>), added three new response attributes
38+
(<code>token_last_eight</code>, <code>hashed_token</code>, and
39+
<code>fingerprint</code>), and added
40+
<a href="#get-or-create-an-authorization-for-a-specific-app-and-fingerprint">one new API</a>.
41+
</p>
42+
43+
<p>
44+
To access the new API functionality during the preview period, you must
45+
provide a custom <a href="/v3/media/">media type</a> in the
46+
<code>Accept</code> header:
47+
<pre>application/vnd.github.mirage-preview+json</pre>
48+
</p>
49+
</div>
50+
1451
## List your authorizations
1552

1653
GET /authorizations
1754

1855
### Response
1956

2057
<%= headers 200, :pagination => default_pagination_rels %>
21-
<%= json(:oauth_access) { |h| [h] } %>
58+
<%= json(:oauth_access) { |h| [h.merge("token" => "")] } %>
2259

2360
## Get a single authorization
2461

@@ -27,16 +64,16 @@ Make sure you understand how to [work with two-factor authentication](/v3/auth/#
2764
### Response
2865

2966
<%= headers 200 %>
30-
<%= json :oauth_access %>
67+
<%= json(:oauth_access) { |h| h.merge("token" => "") } %>
3168

3269
## Create a new authorization
3370

3471
If you need a small number of tokens, implementing the [web flow](/v3/oauth/#web-application-flow)
35-
can be cumbersome. Instead, tokens can be created using the Authorizations API using
72+
can be cumbersome. Instead, tokens can be created using the OAuth Authorizations API using
3673
[Basic Authentication](/v3/auth#basic-authentication). To create tokens for a particular OAuth application, you
3774
must provide its client ID and secret, found on the OAuth application settings
38-
page, linked from your [OAuth applications listing on GitHub][app-listing]. OAuth tokens
39-
can also be created through the web UI via the [Application settings page](https://github.com/settings/applications).
75+
page, linked from your [OAuth applications listing on GitHub][app-listing]. If your OAuth applicaion intends to create multiple tokens for one user you should use `fingerprint` to differentiate between them. OAuth tokens
76+
can also be created through the web UI via the [Application settings page][app-listing].
4077
Read more about these tokens on the [GitHub Help page](https://help.github.com/articles/creating-an-access-token-for-command-line-use).
4178

4279
POST /authorizations
@@ -50,6 +87,7 @@ Name | Type | Description
5087
`note_url`|`string` | A URL to remind you what app the OAuth token is for.
5188
`client_id`|`string` | The 20 character OAuth app client key for which to create the token.
5289
`client_secret`|`string` | The 40 character OAuth app client secret for which to create the token.
90+
`fingerprint`|`string` | **This attribute is only available when using the [mirage-preview](#deprecation-notice) media type.** A unique string to distinguish an authorization from others created for the same client ID and user.
5391

5492

5593
<%= json :scopes => ["public_repo"], :note => 'admin script' %>
@@ -58,15 +96,15 @@ Name | Type | Description
5896

5997
<%= headers 201, :Location => "https://api.github.com/authorizations/1"
6098
%>
61-
<%= json :oauth_access %>
99+
<%= json(:oauth_access) { |h| h.merge("fingerprint" => "") } %>
62100

63101
## Get-or-create an authorization for a specific app
64102

65103
This method will create a new authorization for the specified OAuth application,
66104
only if an authorization for that application doesn't already exist for the
67-
user. (The URL includes the 20 character client ID for the OAuth app that is
68-
requesting the token.) It returns the user's token for the application if one
69-
exists. Otherwise, it creates one.
105+
user. The URL includes the 20 character client ID for the OAuth app that is
106+
requesting the token. It returns the user's existing authorization for the
107+
application if one is present. Otherwise, it creates and returns a new one.
70108

71109
PUT /authorizations/clients/:client_id
72110

@@ -78,6 +116,7 @@ Name | Type | Description
78116
`scopes`|`array` | A list of scopes that this authorization is in.
79117
`note`|`string` | A note to remind you what the OAuth token is for.
80118
`note_url`|`string` | A URL to remind you what app the OAuth token is for.
119+
`fingerprint`|`string` | **This attribute is only available when using the [mirage-preview](#deprecation-notice) media type.** A unique string to distinguish an authorization from others created for the same client and user. If provided, this API is functionally equivalent to [Get-or-create an authorization for a specific app and fingerprint](/v3/oauth_authorizations/#get-or-create-an-authorization-for-a-specific-app-and-fingerprint).
81120

82121

83122
<%= json :client_secret => "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", :scopes => ["public_repo"], :note => 'admin script' %>
@@ -86,14 +125,52 @@ Name | Type | Description
86125

87126
<%= headers 201, :Location => "https://api.github.com/authorizations/1"
88127
%>
89-
<%= json :oauth_access %>
128+
<%= json(:oauth_access) { |h| h.merge("fingerprint" => "") } %>
90129

91130
### Response if returning an existing token
92131

93132
<%= headers 200, :Location => "https://api.github.com/authorizations/1"
94133
%>
134+
<%= json(:oauth_access) { |h| h.merge("token" => "", "fingerprint" => "") } %>
135+
136+
## Get-or-create an authorization for a specific app and fingerprint
137+
138+
**This API method is only available when using the
139+
[mirage-preview](#deprecation-notice) media type.**
140+
This method will create a new authorization for the specified OAuth application,
141+
only if an authorization for that application and fingerprint do not already
142+
exist for the user. The URL includes the 20 character client ID for the OAuth
143+
app that is requesting the token. `fingerprint` is a unique string to
144+
distinguish an authorization from others created for the same client ID and
145+
user. It returns the user's existing authorization for the application if one
146+
is present. Otherwise, it creates and returns a new one.
147+
148+
PUT /authorizations/clients/:client_id/:fingerprint
149+
150+
### Parameters
151+
152+
Name | Type | Description
153+
-----|------|--------------
154+
`client_secret`|`string`| **Required**. The 40 character OAuth app client secret associated with the client ID specified in the URL.
155+
`scopes`|`array` | A list of scopes that this authorization is in.
156+
`note`|`string` | A note to remind you what the OAuth token is for.
157+
`note_url`|`string` | A URL to remind you what app the OAuth token is for.
158+
159+
160+
<%= json :client_secret => "abcdabcdabcdabcdabcdabcdabcdabcdabcdabcd", :scopes => ["public_repo"], :note => 'admin script' %>
161+
162+
### Response if returning a new token
163+
164+
<%= headers 201, :Location => "https://api.github.com/authorizations/1"
165+
%>
95166
<%= json :oauth_access %>
96167

168+
### Response if returning an existing token
169+
170+
<%= headers 200, :Location => "https://api.github.com/authorizations/1"
171+
%>
172+
<%= json(:oauth_access) { |h| h.merge("token" => "") } %>
173+
97174
## Update an existing authorization
98175

99176
PATCH /authorizations/:id
@@ -107,6 +184,7 @@ Name | Type | Description
107184
`remove_scopes`|`array` | A list of scopes to remove from this authorization.
108185
`note`|`string` | A note to remind you what the OAuth token is for.
109186
`note_url`|`string` | A URL to remind you what app the OAuth token is for.
187+
`fingerprint`|`string` | **This attribute is only available when using the [mirage-preview](#deprecation-notice) media type.** A unique string to distinguish an authorization from others created for the same client ID and user.
110188

111189

112190
You can only send one of these scope keys at a time.
@@ -116,7 +194,7 @@ You can only send one of these scope keys at a time.
116194
### Response
117195

118196
<%= headers 200 %>
119-
<%= json :oauth_access %>
197+
<%= json(:oauth_access) { |h| h.merge("token" => "") } %>
120198

121199
## Delete an authorization
122200

content/v3/versions.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,13 @@ The recommendations below will help you prepare your application for the next ma
111111
use the [standard `per_page` and `page` parameters](/v3/#pagination) for pagination, instead of `per_page`,
112112
`top`, and `sha`.
113113

114+
1. Authorization attribute: token
115+
: Recommendation: This attribute will return an empty string in the majority of
116+
the Authorizations API responses. Please see
117+
[the deprecation blog post](/changes/2014-12-08-removing-authorizations-token/)
118+
and the [Authorizations API deprecation notice](/v3/oauth_authorizations/#deprecation-notice)
119+
for full details.
120+
114121
# beta (Deprecated) {#beta}
115122

116123
The [beta API](/v3) is deprecated. Its current functionality is stable and unchangeable. Please [file a support issue][support] if you have problems.

lib/resources.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1538,7 +1538,9 @@ def fetch_content(key)
15381538
"id" => 1,
15391539
"url" => "https://api.github.com/authorizations/1",
15401540
"scopes" => ["public_repo"],
1541-
"token" => "abc123",
1541+
"token" => "abcdefgh12345678",
1542+
"token_last_eight" => "12345678",
1543+
"hashed_token" => "JflKKlx/uvSZxmW8c9Z8HIfkltqJhRMWM+4KlYGdsug=",
15421544
"app" => {
15431545
"url" => "http://my-github-app.com",
15441546
"name" => "my github app",
@@ -1547,7 +1549,8 @@ def fetch_content(key)
15471549
"note" => "optional note",
15481550
"note_url" => "http://optional/note/url",
15491551
"updated_at" => "2011-09-06T20:39:23Z",
1550-
"created_at" => "2011-09-06T17:26:27Z"
1552+
"created_at" => "2011-09-06T17:26:27Z",
1553+
"fingerprint" => "jklmnop12345678",
15511554
}
15521555

15531556
OAUTH_ACCESS_WITH_USER ||= OAUTH_ACCESS.merge(:user => USER)

0 commit comments

Comments
 (0)