{"action":"created","comment":{"url":"https://api.github.com/repos/snapcore/snapd/pulls/comments/69548139","id":69548139,"diff_hunk":"@@ -117,6 +131,88 @@ func User(st *state.State, id int) (*UserState, error) {\n \treturn nil, fmt.Errorf(\"invalid user\")\n }\n \n+// SetDeviceIdentity sets the device's identity as used for communication with the store.\n+// XXX: Should eventually require the serial assertion to be the\n+// assertions DB rather than taking it directly, but that requires\n+// significant work.\n+// XXX: Doesn't check that the serial assertion is trustworthy, just\n+// that it matches the purported identity. But the assertion is only\n+// used to establish a store session, and the store performs the\n+// requisite checks.\n+func SetDeviceIdentity(st *state.State, brand string, model string, serial string, serialAssertionEncoded []byte) error {\n+\tvar authStateData AuthState\n+\n+\t// Verify that the serial assertion matches the brand, model and\n+\t// serial.\n+\tassert, err := asserts.Decode(serialAssertionEncoded)\n+\tif err != nil {\n+\t\treturn err\n+\t}\n+\tif assert.Type() != asserts.SerialType {\n+\t\treturn fmt.Errorf(\"serial assertion is actually %s\", assert.Type())\n+\t}\n+\tserialAssertion := assert.(*asserts.Serial)\n+\tif brand != serialAssertion.BrandID() || model != serialAssertion.Model() || serial != serialAssertion.Serial() {\n+\t\treturn fmt.Errorf(\"serial assertion doesn't match purported identity\")\n+\t}\n+\n+\terr = st.Get(\"auth\", &authStateData)\n+\tif err == state.ErrNoState {\n+\t\tauthStateData = AuthState{}\n+\t} else if err != nil {\n+\t\treturn err\n+\t}\n+\n+\tif authStateData.Device == nil {\n+\t\tauthStateData.Device = &DeviceState{}\n+\t}\n+\n+\tauthStateData.Device.Brand = brand\n+\tauthStateData.Device.Model = model\n+\tauthStateData.Device.Serial = serial\n+\tauthStateData.Device.SerialAssertion = serialAssertionEncoded\n+\tst.Set(\"auth\", authStateData)\n+\n+\treturn nil\n+}\n+\n+// SetDeviceStoreMacaroon sets the credentials used to authenticate to the store as the device.\n+func SetDeviceStoreMacaroon(st *state.State, macaroon string, discharges []string) error {","path":"overlord/auth/auth.go","position":81,"original_position":81,"commit_id":"a15ecd7ff57869462855148f7a04a3b649636a5f","original_commit_id":"a15ecd7ff57869462855148f7a04a3b649636a5f","user":{"login":"niemeyer","id":378683,"avatar_url":"https://avatars.githubusercontent.com/u/378683?v=3","gravatar_id":"","url":"https://api.github.com/users/niemeyer","html_url":"https://github.com/niemeyer","followers_url":"https://api.github.com/users/niemeyer/followers","following_url":"https://api.github.com/users/niemeyer/following{/other_user}","gists_url":"https://api.github.com/users/niemeyer/gists{/gist_id}","starred_url":"https://api.github.com/users/niemeyer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/niemeyer/subscriptions","organizations_url":"https://api.github.com/users/niemeyer/orgs","repos_url":"https://api.github.com/users/niemeyer/repos","events_url":"https://api.github.com/users/niemeyer/events{/privacy}","received_events_url":"https://api.github.com/users/niemeyer/received_events","type":"User","site_admin":false},"body":"Instead of these two methods, can we have a single `auth.SetDevice` one that takes a `*DeviceState`?","created_at":"2016-07-05T11:37:57Z","updated_at":"2016-07-05T11:37:57Z","html_url":"https://github.com/snapcore/snapd/pull/1478#discussion_r69548139","pull_request_url":"https://api.github.com/repos/snapcore/snapd/pulls/1478","_links":{"self":{"href":"https://api.github.com/repos/snapcore/snapd/pulls/comments/69548139"},"html":{"href":"https://github.com/snapcore/snapd/pull/1478#discussion_r69548139"},"pull_request":{"href":"https://api.github.com/repos/snapcore/snapd/pulls/1478"}}},"pull_request":{"url":"https://api.github.com/repos/snapcore/snapd/pulls/1478","id":76152990,"html_url":"https://github.com/snapcore/snapd/pull/1478","diff_url":"https://github.com/snapcore/snapd/pull/1478.diff","patch_url":"https://github.com/snapcore/snapd/pull/1478.patch","issue_url":"https://api.github.com/repos/snapcore/snapd/issues/1478","number":1478,"state":"closed","locked":false,"title":"many: Add device authentication skeleton.","user":{"login":"wgrant","id":806600,"avatar_url":"https://avatars.githubusercontent.com/u/806600?v=3","gravatar_id":"","url":"https://api.github.com/users/wgrant","html_url":"https://github.com/wgrant","followers_url":"https://api.github.com/users/wgrant/followers","following_url":"https://api.github.com/users/wgrant/following{/other_user}","gists_url":"https://api.github.com/users/wgrant/gists{/gist_id}","starred_url":"https://api.github.com/users/wgrant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wgrant/subscriptions","organizations_url":"https://api.github.com/users/wgrant/orgs","repos_url":"https://api.github.com/users/wgrant/repos","events_url":"https://api.github.com/users/wgrant/events{/privacy}","received_events_url":"https://api.github.com/users/wgrant/received_events","type":"User","site_admin":false},"body":"This branch adds a functional skeleton of device identity and authentication, mostly for design review and store testing. A new `/v2/experimental-device-identity` API is added to exercise the new code, and POSTing a brand, model, serial and serial-assertion to it causes snapd to establish a device session with the store and use it for further communications. The session is in the form of a macaroon that is sent to the store in an extra `X-Device-Authorization` header wherever a normal user-identifying `Authorization` header can be. Behaviour is unchanged from master until device identity is established via the experimental API.\r\n\r\nIn this design, device key operations and serial assertion self-enrolment are handled by a new `snap-identity-helper` subprocess, ensuring that we keep a clean interface so the behaviours can in future be selectively overridden by gadget snaps. But since classic doesn't have a gadget snap and gadget snap interactions aren't yet well defined, I've left these as direct subprocess calls for now. Injecting existing identity information from snapd into a future identity-managing gadget snap is technically the same as provisioning a new device with a factory-defined identity, so the upgrade path is clear.\r\n\r\nI've eschewed AssertManager initially in favour of persisting the serial assertion directly in state, as the manager is not yet well exercised inside snapd itself, and plausible unit tests require utilities to be moved from private/test-only parts of other packages. Since we presently only use the assertion as evidence for the store, and don't need to verify it ourselves, this doesn't cause any problems, and it's an easy hack to remove once snapd's asserts integration is more mature.\r\n\r\nThe tests are ugly in places; existing wrappers in store/auth.go need to be refactored for easier mocking, and the aforementioned test utilities in asserts need to be made public so assertion consumers can eg. generate keys to get valid assertions.","created_at":"2016-07-04T11:56:50Z","updated_at":"2016-07-05T11:37:57Z","closed_at":"2016-07-05T11:01:27Z","merged_at":null,"merge_commit_sha":"be3b8d0ca5d2327a8d429b67465fdee128aa6842","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/snapcore/snapd/pulls/1478/commits","review_comments_url":"https://api.github.com/repos/snapcore/snapd/pulls/1478/comments","review_comment_url":"https://api.github.com/repos/snapcore/snapd/pulls/comments{/number}","comments_url":"https://api.github.com/repos/snapcore/snapd/issues/1478/comments","statuses_url":"https://api.github.com/repos/snapcore/snapd/statuses/a15ecd7ff57869462855148f7a04a3b649636a5f","head":{"label":"wgrant:store-device-identity","ref":"store-device-identity","sha":"a15ecd7ff57869462855148f7a04a3b649636a5f","user":{"login":"wgrant","id":806600,"avatar_url":"https://avatars.githubusercontent.com/u/806600?v=3","gravatar_id":"","url":"https://api.github.com/users/wgrant","html_url":"https://github.com/wgrant","followers_url":"https://api.github.com/users/wgrant/followers","following_url":"https://api.github.com/users/wgrant/following{/other_user}","gists_url":"https://api.github.com/users/wgrant/gists{/gist_id}","starred_url":"https://api.github.com/users/wgrant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wgrant/subscriptions","organizations_url":"https://api.github.com/users/wgrant/orgs","repos_url":"https://api.github.com/users/wgrant/repos","events_url":"https://api.github.com/users/wgrant/events{/privacy}","received_events_url":"https://api.github.com/users/wgrant/received_events","type":"User","site_admin":false},"repo":{"id":61117444,"name":"snapd","full_name":"wgrant/snapd","owner":{"login":"wgrant","id":806600,"avatar_url":"https://avatars.githubusercontent.com/u/806600?v=3","gravatar_id":"","url":"https://api.github.com/users/wgrant","html_url":"https://github.com/wgrant","followers_url":"https://api.github.com/users/wgrant/followers","following_url":"https://api.github.com/users/wgrant/following{/other_user}","gists_url":"https://api.github.com/users/wgrant/gists{/gist_id}","starred_url":"https://api.github.com/users/wgrant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/wgrant/subscriptions","organizations_url":"https://api.github.com/users/wgrant/orgs","repos_url":"https://api.github.com/users/wgrant/repos","events_url":"https://api.github.com/users/wgrant/events{/privacy}","received_events_url":"https://api.github.com/users/wgrant/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/wgrant/snapd","description":"The snapd and snap tools enable systems to work with .snap files.","fork":true,"url":"https://api.github.com/repos/wgrant/snapd","forks_url":"https://api.github.com/repos/wgrant/snapd/forks","keys_url":"https://api.github.com/repos/wgrant/snapd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/wgrant/snapd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/wgrant/snapd/teams","hooks_url":"https://api.github.com/repos/wgrant/snapd/hooks","issue_events_url":"https://api.github.com/repos/wgrant/snapd/issues/events{/number}","events_url":"https://api.github.com/repos/wgrant/snapd/events","assignees_url":"https://api.github.com/repos/wgrant/snapd/assignees{/user}","branches_url":"https://api.github.com/repos/wgrant/snapd/branches{/branch}","tags_url":"https://api.github.com/repos/wgrant/snapd/tags","blobs_url":"https://api.github.com/repos/wgrant/snapd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/wgrant/snapd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/wgrant/snapd/git/refs{/sha}","trees_url":"https://api.github.com/repos/wgrant/snapd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/wgrant/snapd/statuses/{sha}","languages_url":"https://api.github.com/repos/wgrant/snapd/languages","stargazers_url":"https://api.github.com/repos/wgrant/snapd/stargazers","contributors_url":"https://api.github.com/repos/wgrant/snapd/contributors","subscribers_url":"https://api.github.com/repos/wgrant/snapd/subscribers","subscription_url":"https://api.github.com/repos/wgrant/snapd/subscription","commits_url":"https://api.github.com/repos/wgrant/snapd/commits{/sha}","git_commits_url":"https://api.github.com/repos/wgrant/snapd/git/commits{/sha}","comments_url":"https://api.github.com/repos/wgrant/snapd/comments{/number}","issue_comment_url":"https://api.github.com/repos/wgrant/snapd/issues/comments{/number}","contents_url":"https://api.github.com/repos/wgrant/snapd/contents/{+path}","compare_url":"https://api.github.com/repos/wgrant/snapd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/wgrant/snapd/merges","archive_url":"https://api.github.com/repos/wgrant/snapd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/wgrant/snapd/downloads","issues_url":"https://api.github.com/repos/wgrant/snapd/issues{/number}","pulls_url":"https://api.github.com/repos/wgrant/snapd/pulls{/number}","milestones_url":"https://api.github.com/repos/wgrant/snapd/milestones{/number}","notifications_url":"https://api.github.com/repos/wgrant/snapd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/wgrant/snapd/labels{/name}","releases_url":"https://api.github.com/repos/wgrant/snapd/releases{/id}","deployments_url":"https://api.github.com/repos/wgrant/snapd/deployments","created_at":"2016-06-14T11:30:23Z","updated_at":"2016-06-14T11:30:25Z","pushed_at":"2016-07-04T10:44:58Z","git_url":"git://github.com/wgrant/snapd.git","ssh_url":"git@github.com:wgrant/snapd.git","clone_url":"https://github.com/wgrant/snapd.git","svn_url":"https://github.com/wgrant/snapd","homepage":"","size":31897,"stargazers_count":0,"watchers_count":0,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"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":"snapcore:master","ref":"master","sha":"cdf1cfa5a733923c53ff0d75edd66c3fe3c22e0b","user":{"login":"snapcore","id":19532717,"avatar_url":"https://avatars.githubusercontent.com/u/19532717?v=3","gravatar_id":"","url":"https://api.github.com/users/snapcore","html_url":"https://github.com/snapcore","followers_url":"https://api.github.com/users/snapcore/followers","following_url":"https://api.github.com/users/snapcore/following{/other_user}","gists_url":"https://api.github.com/users/snapcore/gists{/gist_id}","starred_url":"https://api.github.com/users/snapcore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snapcore/subscriptions","organizations_url":"https://api.github.com/users/snapcore/orgs","repos_url":"https://api.github.com/users/snapcore/repos","events_url":"https://api.github.com/users/snapcore/events{/privacy}","received_events_url":"https://api.github.com/users/snapcore/received_events","type":"Organization","site_admin":false},"repo":{"id":44672744,"name":"snapd","full_name":"snapcore/snapd","owner":{"login":"snapcore","id":19532717,"avatar_url":"https://avatars.githubusercontent.com/u/19532717?v=3","gravatar_id":"","url":"https://api.github.com/users/snapcore","html_url":"https://github.com/snapcore","followers_url":"https://api.github.com/users/snapcore/followers","following_url":"https://api.github.com/users/snapcore/following{/other_user}","gists_url":"https://api.github.com/users/snapcore/gists{/gist_id}","starred_url":"https://api.github.com/users/snapcore/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/snapcore/subscriptions","organizations_url":"https://api.github.com/users/snapcore/orgs","repos_url":"https://api.github.com/users/snapcore/repos","events_url":"https://api.github.com/users/snapcore/events{/privacy}","received_events_url":"https://api.github.com/users/snapcore/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/snapcore/snapd","description":"The snapd and snap tools enable systems to work with .snap files.","fork":false,"url":"https://api.github.com/repos/snapcore/snapd","forks_url":"https://api.github.com/repos/snapcore/snapd/forks","keys_url":"https://api.github.com/repos/snapcore/snapd/keys{/key_id}","collaborators_url":"https://api.github.com/repos/snapcore/snapd/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/snapcore/snapd/teams","hooks_url":"https://api.github.com/repos/snapcore/snapd/hooks","issue_events_url":"https://api.github.com/repos/snapcore/snapd/issues/events{/number}","events_url":"https://api.github.com/repos/snapcore/snapd/events","assignees_url":"https://api.github.com/repos/snapcore/snapd/assignees{/user}","branches_url":"https://api.github.com/repos/snapcore/snapd/branches{/branch}","tags_url":"https://api.github.com/repos/snapcore/snapd/tags","blobs_url":"https://api.github.com/repos/snapcore/snapd/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/snapcore/snapd/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/snapcore/snapd/git/refs{/sha}","trees_url":"https://api.github.com/repos/snapcore/snapd/git/trees{/sha}","statuses_url":"https://api.github.com/repos/snapcore/snapd/statuses/{sha}","languages_url":"https://api.github.com/repos/snapcore/snapd/languages","stargazers_url":"https://api.github.com/repos/snapcore/snapd/stargazers","contributors_url":"https://api.github.com/repos/snapcore/snapd/contributors","subscribers_url":"https://api.github.com/repos/snapcore/snapd/subscribers","subscription_url":"https://api.github.com/repos/snapcore/snapd/subscription","commits_url":"https://api.github.com/repos/snapcore/snapd/commits{/sha}","git_commits_url":"https://api.github.com/repos/snapcore/snapd/git/commits{/sha}","comments_url":"https://api.github.com/repos/snapcore/snapd/comments{/number}","issue_comment_url":"https://api.github.com/repos/snapcore/snapd/issues/comments{/number}","contents_url":"https://api.github.com/repos/snapcore/snapd/contents/{+path}","compare_url":"https://api.github.com/repos/snapcore/snapd/compare/{base}...{head}","merges_url":"https://api.github.com/repos/snapcore/snapd/merges","archive_url":"https://api.github.com/repos/snapcore/snapd/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/snapcore/snapd/downloads","issues_url":"https://api.github.com/repos/snapcore/snapd/issues{/number}","pulls_url":"https://api.github.com/repos/snapcore/snapd/pulls{/number}","milestones_url":"https://api.github.com/repos/snapcore/snapd/milestones{/number}","notifications_url":"https://api.github.com/repos/snapcore/snapd/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/snapcore/snapd/labels{/name}","releases_url":"https://api.github.com/repos/snapcore/snapd/releases{/id}","deployments_url":"https://api.github.com/repos/snapcore/snapd/deployments","created_at":"2015-10-21T11:51:46Z","updated_at":"2016-07-04T18:35:12Z","pushed_at":"2016-07-05T11:29:47Z","git_url":"git://github.com/snapcore/snapd.git","ssh_url":"git@github.com:snapcore/snapd.git","clone_url":"https://github.com/snapcore/snapd.git","svn_url":"https://github.com/snapcore/snapd","homepage":"","size":33795,"stargazers_count":342,"watchers_count":342,"language":"Go","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":67,"mirror_url":null,"open_issues_count":28,"forks":67,"open_issues":28,"watchers":342,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/snapcore/snapd/pulls/1478"},"html":{"href":"https://github.com/snapcore/snapd/pull/1478"},"issue":{"href":"https://api.github.com/repos/snapcore/snapd/issues/1478"},"comments":{"href":"https://api.github.com/repos/snapcore/snapd/issues/1478/comments"},"review_comments":{"href":"https://api.github.com/repos/snapcore/snapd/pulls/1478/comments"},"review_comment":{"href":"https://api.github.com/repos/snapcore/snapd/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/snapcore/snapd/pulls/1478/commits"},"statuses":{"href":"https://api.github.com/repos/snapcore/snapd/statuses/a15ecd7ff57869462855148f7a04a3b649636a5f"}}}}
{"actor":{"display_login":"niemeyer"}}