{"action":"created","comment":{"url":"https://api.github.com/repos/docker/distribution/pulls/comments/40531331","id":40531331,"diff_hunk":"@@ -33,14 +33,25 @@ var (\n \t\tHTTPStatusCode: http.StatusMethodNotAllowed,\n \t})\n \n+\t// ErrorCodeUnauthenticated is returned if a request requires\n+\t// authentication.\n+\tErrorCodeUnauthenticated = Register(\"errcode\", ErrorDescriptor{\n+\t\tValue:   \"UNAUTHENTICATED\",\n+\t\tMessage: \"authentication required\",\n+\t\tDescription: `The access controller was unable to authenticate\n+\t\tthe client. Often this will be accompanied by a 401","path":"registry/api/errcode/register.go","position":10,"original_position":10,"commit_id":"237aee74bd7f992d6ba87733a730ee86046dcce0","original_commit_id":"237aee74bd7f992d6ba87733a730ee86046dcce0","user":{"login":"stevvooe","id":120601,"avatar_url":"https://avatars.githubusercontent.com/u/120601?v=3","gravatar_id":"","url":"https://api.github.com/users/stevvooe","html_url":"https://github.com/stevvooe","followers_url":"https://api.github.com/users/stevvooe/followers","following_url":"https://api.github.com/users/stevvooe/following{/other_user}","gists_url":"https://api.github.com/users/stevvooe/gists{/gist_id}","starred_url":"https://api.github.com/users/stevvooe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevvooe/subscriptions","organizations_url":"https://api.github.com/users/stevvooe/orgs","repos_url":"https://api.github.com/users/stevvooe/repos","events_url":"https://api.github.com/users/stevvooe/events{/privacy}","received_events_url":"https://api.github.com/users/stevvooe/received_events","type":"User","site_admin":false},"body":"This will always be a 401, since we defined 401 below.","created_at":"2015-09-28T09:10:18Z","updated_at":"2015-09-28T09:10:18Z","html_url":"https://github.com/docker/distribution/pull/1023#discussion_r40531331","pull_request_url":"https://api.github.com/repos/docker/distribution/pulls/1023","_links":{"self":{"href":"https://api.github.com/repos/docker/distribution/pulls/comments/40531331"},"html":{"href":"https://github.com/docker/distribution/pull/1023#discussion_r40531331"},"pull_request":{"href":"https://api.github.com/repos/docker/distribution/pulls/1023"}}},"pull_request":{"url":"https://api.github.com/repos/docker/distribution/pulls/1023","id":45948532,"html_url":"https://github.com/docker/distribution/pull/1023","diff_url":"https://github.com/docker/distribution/pull/1023.diff","patch_url":"https://github.com/docker/distribution/pull/1023.patch","issue_url":"https://api.github.com/repos/docker/distribution/issues/1023","number":1023,"state":"open","locked":false,"title":"[registry/auth] Update interface error handling","user":{"login":"jlhawn","id":1441929,"avatar_url":"https://avatars.githubusercontent.com/u/1441929?v=3","gravatar_id":"","url":"https://api.github.com/users/jlhawn","html_url":"https://github.com/jlhawn","followers_url":"https://api.github.com/users/jlhawn/followers","following_url":"https://api.github.com/users/jlhawn/following{/other_user}","gists_url":"https://api.github.com/users/jlhawn/gists{/gist_id}","starred_url":"https://api.github.com/users/jlhawn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jlhawn/subscriptions","organizations_url":"https://api.github.com/users/jlhawn/orgs","repos_url":"https://api.github.com/users/jlhawn/repos","events_url":"https://api.github.com/users/jlhawn/events{/privacy}","received_events_url":"https://api.github.com/users/jlhawn/received_events","type":"User","site_admin":false},"body":"The existing Challenge error interface is not sufficient enough to represent\r\nthe various kinds of responses and policies that an authorization mechanism\r\nmay want to have.\r\n\r\nThis patch replaces the Challenge interface with two separate interfaces:\r\n\r\n- AuthenticationError\r\n\r\n  This error type is used to indicate that the client should attempt to\r\n  authenticate or has provided invalid authentication credentials. These\r\n  errors should result in HTTP 401 Unauthorized responses with a challenge\r\n  header informing the client of how to authenticate.\r\n\r\n- AuthorizationError\r\n\r\n  This error type is used to indicate that the authenticated or anonymous\r\n  client does not have permission to access the requested resource. These\r\n  errors usually result in HTTP 403 Forbidden responses but may also indicate\r\n  that the resource should remain hidden from the client, in which case the\r\n  server should respond with 404 Not Found in order to not leak knowledge of\r\n  the existence of that resource.\r\n\r\n## Summary of Changes\r\n\r\n- **`registry/auth`**\r\n    - Updated the `AccessController` interface to accept only a single resource (multiple resources are never used; we can always change this in the future if we need to, but there's no need to expand the surface of the interface if we do not have to).\r\n    - Replaced the `Challenge` interface with the above described `AuthenticationError` and `AuthorizationError` interfaces.\r\n\r\n- **`registry/auth/silly`**\r\n    - This is only a reference basic auth implementation but it has been updated to implement the `AuthenticationError` interface. This access controller does not return `AuthorizationError`s.\r\n\r\n- **`registry/auth/htpasswd`**\r\n    - Updated to implement the `AuthenticationError` interface. This access controller does not return `AuthorizationError`s.\r\n\r\n- **`registry/auth/token`**\r\n    - Updated to implement the `AuthenticationError` and `AuthorizationError` interfaces. Requests without a token or requests with invalid tokens (e.g., expired or not yet valid, untrusted issuer/signer, unverified signature, etc) result in `AuthenticationError`s. Requests with valid tokens which do not have an appropriate access claim result in `AuthorizationError`s.\r\n\r\n- **`registry/handlers`**\r\n    - Updated the `Authorized()` method to handle `auth.AuthenticationError` and `auth.AuthorizationError`. Authorization errors which indicate that the resource should be hidden from the client will result in a `404 Not Found` response with error code `NAME_UNKNOWN`.\r\n\r\n- **`registry/api/errcode`**\r\n    - Updated `UNAUTHORIZED` error code message and status to reflect that it is *not* an authentication error and returns `403 Forbidden` responses. These errors should no longer have `Www-Authenticate` response headers.\r\n    - Added `UNAUTHENTICATED` error code message which indicates authentication errors and returns `401 Unauthorized` (read: *unauthenticated*) responses which may have `Www-Authenticate` challenge headers.\r\n\r\nFixes #749\r\nFixes #967 ","created_at":"2015-09-24T20:54:08Z","updated_at":"2015-09-28T09:10:18Z","closed_at":null,"merged_at":null,"merge_commit_sha":"1de94f9e0472841d1bc1bc529b565db337aaf9b4","assignee":{"login":"jlhawn","id":1441929,"avatar_url":"https://avatars.githubusercontent.com/u/1441929?v=3","gravatar_id":"","url":"https://api.github.com/users/jlhawn","html_url":"https://github.com/jlhawn","followers_url":"https://api.github.com/users/jlhawn/followers","following_url":"https://api.github.com/users/jlhawn/following{/other_user}","gists_url":"https://api.github.com/users/jlhawn/gists{/gist_id}","starred_url":"https://api.github.com/users/jlhawn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jlhawn/subscriptions","organizations_url":"https://api.github.com/users/jlhawn/orgs","repos_url":"https://api.github.com/users/jlhawn/repos","events_url":"https://api.github.com/users/jlhawn/events{/privacy}","received_events_url":"https://api.github.com/users/jlhawn/received_events","type":"User","site_admin":false},"milestone":{"url":"https://api.github.com/repos/docker/distribution/milestones/9","html_url":"https://github.com/docker/distribution/milestones/Registry/2.2","labels_url":"https://api.github.com/repos/docker/distribution/milestones/9/labels","id":1026605,"number":9,"title":"Registry/2.2","description":"","creator":{"login":"stevvooe","id":120601,"avatar_url":"https://avatars.githubusercontent.com/u/120601?v=3","gravatar_id":"","url":"https://api.github.com/users/stevvooe","html_url":"https://github.com/stevvooe","followers_url":"https://api.github.com/users/stevvooe/followers","following_url":"https://api.github.com/users/stevvooe/following{/other_user}","gists_url":"https://api.github.com/users/stevvooe/gists{/gist_id}","starred_url":"https://api.github.com/users/stevvooe/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/stevvooe/subscriptions","organizations_url":"https://api.github.com/users/stevvooe/orgs","repos_url":"https://api.github.com/users/stevvooe/repos","events_url":"https://api.github.com/users/stevvooe/events{/privacy}","received_events_url":"https://api.github.com/users/stevvooe/received_events","type":"User","site_admin":false},"open_issues":36,"closed_issues":53,"state":"open","created_at":"2015-03-18T04:28:58Z","updated_at":"2015-09-28T09:07:44Z","due_on":"2015-10-05T07:00:00Z","closed_at":null},"commits_url":"https://api.github.com/repos/docker/distribution/pulls/1023/commits","review_comments_url":"https://api.github.com/repos/docker/distribution/pulls/1023/comments","review_comment_url":"https://api.github.com/repos/docker/distribution/pulls/comments{/number}","comments_url":"https://api.github.com/repos/docker/distribution/issues/1023/comments","statuses_url":"https://api.github.com/repos/docker/distribution/statuses/237aee74bd7f992d6ba87733a730ee86046dcce0","head":{"label":"jlhawn:update_auth_interface","ref":"update_auth_interface","sha":"237aee74bd7f992d6ba87733a730ee86046dcce0","user":{"login":"jlhawn","id":1441929,"avatar_url":"https://avatars.githubusercontent.com/u/1441929?v=3","gravatar_id":"","url":"https://api.github.com/users/jlhawn","html_url":"https://github.com/jlhawn","followers_url":"https://api.github.com/users/jlhawn/followers","following_url":"https://api.github.com/users/jlhawn/following{/other_user}","gists_url":"https://api.github.com/users/jlhawn/gists{/gist_id}","starred_url":"https://api.github.com/users/jlhawn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jlhawn/subscriptions","organizations_url":"https://api.github.com/users/jlhawn/orgs","repos_url":"https://api.github.com/users/jlhawn/repos","events_url":"https://api.github.com/users/jlhawn/events{/privacy}","received_events_url":"https://api.github.com/users/jlhawn/received_events","type":"User","site_admin":false},"repo":{"id":29154467,"name":"distribution","full_name":"jlhawn/distribution","owner":{"login":"jlhawn","id":1441929,"avatar_url":"https://avatars.githubusercontent.com/u/1441929?v=3","gravatar_id":"","url":"https://api.github.com/users/jlhawn","html_url":"https://github.com/jlhawn","followers_url":"https://api.github.com/users/jlhawn/followers","following_url":"https://api.github.com/users/jlhawn/following{/other_user}","gists_url":"https://api.github.com/users/jlhawn/gists{/gist_id}","starred_url":"https://api.github.com/users/jlhawn/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jlhawn/subscriptions","organizations_url":"https://api.github.com/users/jlhawn/orgs","repos_url":"https://api.github.com/users/jlhawn/repos","events_url":"https://api.github.com/users/jlhawn/events{/privacy}","received_events_url":"https://api.github.com/users/jlhawn/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/jlhawn/distribution","description":"The Docker toolset to pack, ship, store, and deliver content","fork":true,"url":"https://api.github.com/repos/jlhawn/distribution","forks_url":"https://api.github.com/repos/jlhawn/distribution/forks","keys_url":"https://api.github.com/repos/jlhawn/distribution/keys{/key_id}","collaborators_url":"https://api.github.com/repos/jlhawn/distribution/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/jlhawn/distribution/teams","hooks_url":"https://api.github.com/repos/jlhawn/distribution/hooks","issue_events_url":"https://api.github.com/repos/jlhawn/distribution/issues/events{/number}","events_url":"https://api.github.com/repos/jlhawn/distribution/events","assignees_url":"https://api.github.com/repos/jlhawn/distribution/assignees{/user}","branches_url":"https://api.github.com/repos/jlhawn/distribution/branches{/branch}","tags_url":"https://api.github.com/repos/jlhawn/distribution/tags","blobs_url":"https://api.github.com/repos/jlhawn/distribution/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/jlhawn/distribution/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/jlhawn/distribution/git/refs{/sha}","trees_url":"https://api.github.com/repos/jlhawn/distribution/git/trees{/sha}","statuses_url":"https://api.github.com/repos/jlhawn/distribution/statuses/{sha}","languages_url":"https://api.github.com/repos/jlhawn/distribution/languages","stargazers_url":"https://api.github.com/repos/jlhawn/distribution/stargazers","contributors_url":"https://api.github.com/repos/jlhawn/distribution/contributors","subscribers_url":"https://api.github.com/repos/jlhawn/distribution/subscribers","subscription_url":"https://api.github.com/repos/jlhawn/distribution/subscription","commits_url":"https://api.github.com/repos/jlhawn/distribution/commits{/sha}","git_commits_url":"https://api.github.com/repos/jlhawn/distribution/git/commits{/sha}","comments_url":"https://api.github.com/repos/jlhawn/distribution/comments{/number}","issue_comment_url":"https://api.github.com/repos/jlhawn/distribution/issues/comments{/number}","contents_url":"https://api.github.com/repos/jlhawn/distribution/contents/{+path}","compare_url":"https://api.github.com/repos/jlhawn/distribution/compare/{base}...{head}","merges_url":"https://api.github.com/repos/jlhawn/distribution/merges","archive_url":"https://api.github.com/repos/jlhawn/distribution/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/jlhawn/distribution/downloads","issues_url":"https://api.github.com/repos/jlhawn/distribution/issues{/number}","pulls_url":"https://api.github.com/repos/jlhawn/distribution/pulls{/number}","milestones_url":"https://api.github.com/repos/jlhawn/distribution/milestones{/number}","notifications_url":"https://api.github.com/repos/jlhawn/distribution/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/jlhawn/distribution/labels{/name}","releases_url":"https://api.github.com/repos/jlhawn/distribution/releases{/id}","created_at":"2015-01-12T20:08:19Z","updated_at":"2015-05-06T18:17:23Z","pushed_at":"2015-09-25T21:33:06Z","git_url":"git://github.com/jlhawn/distribution.git","ssh_url":"git@github.com:jlhawn/distribution.git","clone_url":"https://github.com/jlhawn/distribution.git","svn_url":"https://github.com/jlhawn/distribution","homepage":null,"size":3955,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"docker:master","ref":"master","sha":"794975e9e65b48661bcfeb6e7a9383d9bb927096","user":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=3","gravatar_id":"","url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"repo":{"id":28366058,"name":"distribution","full_name":"docker/distribution","owner":{"login":"docker","id":5429470,"avatar_url":"https://avatars.githubusercontent.com/u/5429470?v=3","gravatar_id":"","url":"https://api.github.com/users/docker","html_url":"https://github.com/docker","followers_url":"https://api.github.com/users/docker/followers","following_url":"https://api.github.com/users/docker/following{/other_user}","gists_url":"https://api.github.com/users/docker/gists{/gist_id}","starred_url":"https://api.github.com/users/docker/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/docker/subscriptions","organizations_url":"https://api.github.com/users/docker/orgs","repos_url":"https://api.github.com/users/docker/repos","events_url":"https://api.github.com/users/docker/events{/privacy}","received_events_url":"https://api.github.com/users/docker/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/docker/distribution","description":"The Docker toolset to pack, ship, store, and deliver content","fork":false,"url":"https://api.github.com/repos/docker/distribution","forks_url":"https://api.github.com/repos/docker/distribution/forks","keys_url":"https://api.github.com/repos/docker/distribution/keys{/key_id}","collaborators_url":"https://api.github.com/repos/docker/distribution/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/docker/distribution/teams","hooks_url":"https://api.github.com/repos/docker/distribution/hooks","issue_events_url":"https://api.github.com/repos/docker/distribution/issues/events{/number}","events_url":"https://api.github.com/repos/docker/distribution/events","assignees_url":"https://api.github.com/repos/docker/distribution/assignees{/user}","branches_url":"https://api.github.com/repos/docker/distribution/branches{/branch}","tags_url":"https://api.github.com/repos/docker/distribution/tags","blobs_url":"https://api.github.com/repos/docker/distribution/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/docker/distribution/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/docker/distribution/git/refs{/sha}","trees_url":"https://api.github.com/repos/docker/distribution/git/trees{/sha}","statuses_url":"https://api.github.com/repos/docker/distribution/statuses/{sha}","languages_url":"https://api.github.com/repos/docker/distribution/languages","stargazers_url":"https://api.github.com/repos/docker/distribution/stargazers","contributors_url":"https://api.github.com/repos/docker/distribution/contributors","subscribers_url":"https://api.github.com/repos/docker/distribution/subscribers","subscription_url":"https://api.github.com/repos/docker/distribution/subscription","commits_url":"https://api.github.com/repos/docker/distribution/commits{/sha}","git_commits_url":"https://api.github.com/repos/docker/distribution/git/commits{/sha}","comments_url":"https://api.github.com/repos/docker/distribution/comments{/number}","issue_comment_url":"https://api.github.com/repos/docker/distribution/issues/comments{/number}","contents_url":"https://api.github.com/repos/docker/distribution/contents/{+path}","compare_url":"https://api.github.com/repos/docker/distribution/compare/{base}...{head}","merges_url":"https://api.github.com/repos/docker/distribution/merges","archive_url":"https://api.github.com/repos/docker/distribution/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/docker/distribution/downloads","issues_url":"https://api.github.com/repos/docker/distribution/issues{/number}","pulls_url":"https://api.github.com/repos/docker/distribution/pulls{/number}","milestones_url":"https://api.github.com/repos/docker/distribution/milestones{/number}","notifications_url":"https://api.github.com/repos/docker/distribution/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/docker/distribution/labels{/name}","releases_url":"https://api.github.com/repos/docker/distribution/releases{/id}","created_at":"2014-12-22T23:49:26Z","updated_at":"2015-09-28T08:59:29Z","pushed_at":"2015-09-28T08:08:30Z","git_url":"git://github.com/docker/distribution.git","ssh_url":"git@github.com:docker/distribution.git","clone_url":"https://github.com/docker/distribution.git","svn_url":"https://github.com/docker/distribution","homepage":null,"size":14484,"stargazers_count":1094,"watchers_count":1094,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":415,"mirror_url":null,"open_issues_count":137,"forks":415,"open_issues":137,"watchers":1094,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/docker/distribution/pulls/1023"},"html":{"href":"https://github.com/docker/distribution/pull/1023"},"issue":{"href":"https://api.github.com/repos/docker/distribution/issues/1023"},"comments":{"href":"https://api.github.com/repos/docker/distribution/issues/1023/comments"},"review_comments":{"href":"https://api.github.com/repos/docker/distribution/pulls/1023/comments"},"review_comment":{"href":"https://api.github.com/repos/docker/distribution/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/docker/distribution/pulls/1023/commits"},"statuses":{"href":"https://api.github.com/repos/docker/distribution/statuses/237aee74bd7f992d6ba87733a730ee86046dcce0"}}}}