{"action":"created","comment":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/73180272","id":73180272,"diff_hunk":"@@ -0,0 +1,150 @@\n+<!-- BEGIN MUNGE: UNVERSIONED_WARNING -->\n+\n+<!-- BEGIN STRIP_FOR_RELEASE -->\n+\n+<img src=\"http://kubernetes.io/kubernetes/img/warning.png\" alt=\"WARNING\"\n+     width=\"25\" height=\"25\">\n+<img src=\"http://kubernetes.io/kubernetes/img/warning.png\" alt=\"WARNING\"\n+     width=\"25\" height=\"25\">\n+<img src=\"http://kubernetes.io/kubernetes/img/warning.png\" alt=\"WARNING\"\n+     width=\"25\" height=\"25\">\n+<img src=\"http://kubernetes.io/kubernetes/img/warning.png\" alt=\"WARNING\"\n+     width=\"25\" height=\"25\">\n+<img src=\"http://kubernetes.io/kubernetes/img/warning.png\" alt=\"WARNING\"\n+     width=\"25\" height=\"25\">\n+\n+<h2>PLEASE NOTE: This document applies to the HEAD of the source tree</h2>\n+\n+If you are using a released version of Kubernetes, you should\n+refer to the docs that go with that version.\n+\n+<!-- TAG RELEASE_LINK, added by the munger automatically -->\n+<strong>\n+The latest release of this document can be found\n+[here](http://releases.k8s.io/release-1.3/docs/proposals/addon-auth-pattern.md).\n+\n+Documentation for other releases can be found at\n+[releases.k8s.io](http://releases.k8s.io).\n+</strong>\n+--\n+\n+<!-- END STRIP_FOR_RELEASE -->\n+\n+<!-- END MUNGE: UNVERSIONED_WARNING -->\n+\n+## Pattern for Addon Authentication\n+\n+This document proposes a reference pattern for cluster addons to authenticate users, and suggests two new \n+features that enable this pattern.\n+\n+### Goals\n+\n+- Programs which run on the kubernetes cluster, and which provide services to users of the cluster,\n+  can authenticate those users.\n+  - Can implement this without the need to write much authentication code, allowing ease of development/extending kubernetes.\n+- Programs that do not need to handle authentication credentials do not have to, thus allowing a \"service admin\"\n+  to maintain a service, without that service admin ever getting access to other users authentication creds,\n+  which could then be replayed against other services.\n+- To keep authentication and authorization separate, since this improves composability.\n+- Allow users to reuse the cluster credentials in their `~/.kube/config`, so they do not need\n+  creds per cluster\n+- Do not use basic-auth creds in browsers, which are subject to CSRF attacks.\n+- Do not use client certs in browsers, which are hard to install.\n+\n+The example used in this pattern is the kubernetes Dashboard.\n+\n+### Current pattern which has problems\n+\n+The following pattern is in use today.\n+\n+1. Dashboard is running with service `dashboard` in namespace `kube-system`.\n+1. User runs `kubectl proxy -p 8001 &`.\n+  -  This causes kubectl to serve HTTP on `localhost:8001`, and to reverse proxy that to the users current cluster, using TLS and the users\n+     currently configured authentication method.\n+1. User enters this into their browser navigation bar: `http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard/#/workload`\n+  - This causes the API server to proxy a single HTTP request.  The effect of the two proxies is that an HTTP request on localhost:8001 becomes an HTTP request for `/workloads` on port 80 on the pod IP of one of the Pods that backs services `dashboard` in namespace `kube-system`.  So far so good.\n+1. The response is sent back from the Pod to the Apiserver.\n+1. The response is sent back to the users.\n+1. The user sees the Kubernetes Dashboard.\n+\n+The problem with this is that the Dashboard does not know which user is accessing it, so it cannot support multiple users with different capabilities.\n+\n+### Proposed Pattern\n+\n+The proposed pattern has the following key improvements over the current pattern:\n+- a header is injected which tells the Dashboard pod the user who is reaching it.\n+- the header can be validated easily as being signed by the apiserver, which is trusted to authenticate users\n+\n+1. Dashboard is running with service `dashboard` in namespace `kube-system`.\n+1. User runs `kubectl proxy -p 8001 &`.\n+  -  Same as before.\n+1. User enters this into their browser navigation bar: `http://localhost:8001/api/v1/proxy/namespaces/kube-system/services/kubernetes-dashboard/?add-auth=true#/workload`\n+  - Difference is the addition of the `add-auth=true` query parameter, which is handled by the APIserver.  When the API server sees this, it:\n+    1. checks for a cached token\n+    1. if not found, generates and signs a token which attests the identity of the user.\n+    1. injects a header `Authorization: Bearer $TOKEN` into the HTTP request.\n+1. The Dashboard sees the request.\n+1. The dashboard sees the Authorization header and verifies the signature of the token, and extracts the username from one of the claims of the token.\n+1. The dashboard uses the username as needed in its authorization logic (e.g. put into `Impersonate-User` header when doing actions on users behalf.\n+1. The dashboard sends a response back to the user.\n+1. The user sees the Kubernetes Dashboard.\n+\n+Properties of this token:\n+- It is a JWT\n+- The sub (subject) claim gives the kubernetes username of the user. The exact format of these is up to how the cluster admin setup apiserver auth in the cluster.\n+- The exp (expiration) claim is some short amount of time, say a minute.  This prevents replay.\n+- The aud (audience) claim contains the namespace and name of the service that the request is being forwarded to.  This allows one service to ensure that it is not getting tokens intended for another service (in other words, it prevents Dashboard from replaying tokens to another service in the cluster)\n+- The token is signed with the private key of the apiserver.\n+\n+A thing that wants to verify the JWT should do the normal JWT verifying things, which include:\n+- check expiration\n+- check signature.  In this case, the public key is already available inside the cert for the apiserver, which is automatically provided to pods\n+  running on the cluster by the service account controller.\n+- Check that the aud claim matches the service that this pod thinks it belongs in (How it does this is TDB).\n+\n+Revokation:","path":"docs/proposals/addon-auth-pattern.md","position":105,"original_position":105,"commit_id":"c2945d6c81a3b4d4ad70d29abb43b83ba0e7cdec","original_commit_id":"c2945d6c81a3b4d4ad70d29abb43b83ba0e7cdec","user":{"login":"erictune","id":8105590,"avatar_url":"https://avatars.githubusercontent.com/u/8105590?v=3","gravatar_id":"","url":"https://api.github.com/users/erictune","html_url":"https://github.com/erictune","followers_url":"https://api.github.com/users/erictune/followers","following_url":"https://api.github.com/users/erictune/following{/other_user}","gists_url":"https://api.github.com/users/erictune/gists{/gist_id}","starred_url":"https://api.github.com/users/erictune/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erictune/subscriptions","organizations_url":"https://api.github.com/users/erictune/orgs","repos_url":"https://api.github.com/users/erictune/repos","events_url":"https://api.github.com/users/erictune/events{/privacy}","received_events_url":"https://api.github.com/users/erictune/received_events","type":"User","site_admin":false},"body":"fixed","created_at":"2016-08-02T15:37:57Z","updated_at":"2016-08-02T15:37:57Z","html_url":"https://github.com/kubernetes/kubernetes/pull/29714#discussion_r73180272","pull_request_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/29714","_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments/73180272"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/29714#discussion_r73180272"},"pull_request":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/29714"}}},"pull_request":{"url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/29714","id":79122479,"html_url":"https://github.com/kubernetes/kubernetes/pull/29714","diff_url":"https://github.com/kubernetes/kubernetes/pull/29714.diff","patch_url":"https://github.com/kubernetes/kubernetes/pull/29714.patch","issue_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/29714","number":29714,"state":"open","locked":false,"title":"Added Addon Authn Pattern proposal","user":{"login":"erictune","id":8105590,"avatar_url":"https://avatars.githubusercontent.com/u/8105590?v=3","gravatar_id":"","url":"https://api.github.com/users/erictune","html_url":"https://github.com/erictune","followers_url":"https://api.github.com/users/erictune/followers","following_url":"https://api.github.com/users/erictune/following{/other_user}","gists_url":"https://api.github.com/users/erictune/gists{/gist_id}","starred_url":"https://api.github.com/users/erictune/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erictune/subscriptions","organizations_url":"https://api.github.com/users/erictune/orgs","repos_url":"https://api.github.com/users/erictune/repos","events_url":"https://api.github.com/users/erictune/events{/privacy}","received_events_url":"https://api.github.com/users/erictune/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-07-28T00:57:53Z","updated_at":"2016-08-02T15:37:57Z","closed_at":null,"merged_at":null,"merge_commit_sha":"59e6e2faf58e5b6c7c815b9aae754b9347e30015","assignee":{"login":"bgrant0607","id":7725777,"avatar_url":"https://avatars.githubusercontent.com/u/7725777?v=3","gravatar_id":"","url":"https://api.github.com/users/bgrant0607","html_url":"https://github.com/bgrant0607","followers_url":"https://api.github.com/users/bgrant0607/followers","following_url":"https://api.github.com/users/bgrant0607/following{/other_user}","gists_url":"https://api.github.com/users/bgrant0607/gists{/gist_id}","starred_url":"https://api.github.com/users/bgrant0607/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bgrant0607/subscriptions","organizations_url":"https://api.github.com/users/bgrant0607/orgs","repos_url":"https://api.github.com/users/bgrant0607/repos","events_url":"https://api.github.com/users/bgrant0607/events{/privacy}","received_events_url":"https://api.github.com/users/bgrant0607/received_events","type":"User","site_admin":false},"assignees":[{"login":"bgrant0607","id":7725777,"avatar_url":"https://avatars.githubusercontent.com/u/7725777?v=3","gravatar_id":"","url":"https://api.github.com/users/bgrant0607","html_url":"https://github.com/bgrant0607","followers_url":"https://api.github.com/users/bgrant0607/followers","following_url":"https://api.github.com/users/bgrant0607/following{/other_user}","gists_url":"https://api.github.com/users/bgrant0607/gists{/gist_id}","starred_url":"https://api.github.com/users/bgrant0607/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bgrant0607/subscriptions","organizations_url":"https://api.github.com/users/bgrant0607/orgs","repos_url":"https://api.github.com/users/bgrant0607/repos","events_url":"https://api.github.com/users/bgrant0607/events{/privacy}","received_events_url":"https://api.github.com/users/bgrant0607/received_events","type":"User","site_admin":false}],"milestone":null,"commits_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/29714/commits","review_comments_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/29714/comments","review_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/29714/comments","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/c2945d6c81a3b4d4ad70d29abb43b83ba0e7cdec","head":{"label":"erictune:addon-auth-pattern","ref":"addon-auth-pattern","sha":"c2945d6c81a3b4d4ad70d29abb43b83ba0e7cdec","user":{"login":"erictune","id":8105590,"avatar_url":"https://avatars.githubusercontent.com/u/8105590?v=3","gravatar_id":"","url":"https://api.github.com/users/erictune","html_url":"https://github.com/erictune","followers_url":"https://api.github.com/users/erictune/followers","following_url":"https://api.github.com/users/erictune/following{/other_user}","gists_url":"https://api.github.com/users/erictune/gists{/gist_id}","starred_url":"https://api.github.com/users/erictune/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erictune/subscriptions","organizations_url":"https://api.github.com/users/erictune/orgs","repos_url":"https://api.github.com/users/erictune/repos","events_url":"https://api.github.com/users/erictune/events{/privacy}","received_events_url":"https://api.github.com/users/erictune/received_events","type":"User","site_admin":false},"repo":{"id":21629362,"name":"kubernetes","full_name":"erictune/kubernetes","owner":{"login":"erictune","id":8105590,"avatar_url":"https://avatars.githubusercontent.com/u/8105590?v=3","gravatar_id":"","url":"https://api.github.com/users/erictune","html_url":"https://github.com/erictune","followers_url":"https://api.github.com/users/erictune/followers","following_url":"https://api.github.com/users/erictune/following{/other_user}","gists_url":"https://api.github.com/users/erictune/gists{/gist_id}","starred_url":"https://api.github.com/users/erictune/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/erictune/subscriptions","organizations_url":"https://api.github.com/users/erictune/orgs","repos_url":"https://api.github.com/users/erictune/repos","events_url":"https://api.github.com/users/erictune/events{/privacy}","received_events_url":"https://api.github.com/users/erictune/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/erictune/kubernetes","description":"Container Cluster Manager","fork":true,"url":"https://api.github.com/repos/erictune/kubernetes","forks_url":"https://api.github.com/repos/erictune/kubernetes/forks","keys_url":"https://api.github.com/repos/erictune/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/erictune/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/erictune/kubernetes/teams","hooks_url":"https://api.github.com/repos/erictune/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/erictune/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/erictune/kubernetes/events","assignees_url":"https://api.github.com/repos/erictune/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/erictune/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/erictune/kubernetes/tags","blobs_url":"https://api.github.com/repos/erictune/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/erictune/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/erictune/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/erictune/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/erictune/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/erictune/kubernetes/languages","stargazers_url":"https://api.github.com/repos/erictune/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/erictune/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/erictune/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/erictune/kubernetes/subscription","commits_url":"https://api.github.com/repos/erictune/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/erictune/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/erictune/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/erictune/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/erictune/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/erictune/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/erictune/kubernetes/merges","archive_url":"https://api.github.com/repos/erictune/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/erictune/kubernetes/downloads","issues_url":"https://api.github.com/repos/erictune/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/erictune/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/erictune/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/erictune/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/erictune/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/erictune/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/erictune/kubernetes/deployments","created_at":"2014-07-08T21:00:59Z","updated_at":"2016-01-15T20:40:20Z","pushed_at":"2016-07-29T16:20:53Z","git_url":"git://github.com/erictune/kubernetes.git","ssh_url":"git@github.com:erictune/kubernetes.git","clone_url":"https://github.com/erictune/kubernetes.git","svn_url":"https://github.com/erictune/kubernetes","homepage":null,"size":293315,"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":"kubernetes:master","ref":"master","sha":"75c93b4063c479c35dd77106e704476e86ab6c98","user":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"repo":{"id":20580498,"name":"kubernetes","full_name":"kubernetes/kubernetes","owner":{"login":"kubernetes","id":13629408,"avatar_url":"https://avatars.githubusercontent.com/u/13629408?v=3","gravatar_id":"","url":"https://api.github.com/users/kubernetes","html_url":"https://github.com/kubernetes","followers_url":"https://api.github.com/users/kubernetes/followers","following_url":"https://api.github.com/users/kubernetes/following{/other_user}","gists_url":"https://api.github.com/users/kubernetes/gists{/gist_id}","starred_url":"https://api.github.com/users/kubernetes/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/kubernetes/subscriptions","organizations_url":"https://api.github.com/users/kubernetes/orgs","repos_url":"https://api.github.com/users/kubernetes/repos","events_url":"https://api.github.com/users/kubernetes/events{/privacy}","received_events_url":"https://api.github.com/users/kubernetes/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/kubernetes/kubernetes","description":"Production-Grade Container Scheduling and Management","fork":false,"url":"https://api.github.com/repos/kubernetes/kubernetes","forks_url":"https://api.github.com/repos/kubernetes/kubernetes/forks","keys_url":"https://api.github.com/repos/kubernetes/kubernetes/keys{/key_id}","collaborators_url":"https://api.github.com/repos/kubernetes/kubernetes/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/kubernetes/kubernetes/teams","hooks_url":"https://api.github.com/repos/kubernetes/kubernetes/hooks","issue_events_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/events{/number}","events_url":"https://api.github.com/repos/kubernetes/kubernetes/events","assignees_url":"https://api.github.com/repos/kubernetes/kubernetes/assignees{/user}","branches_url":"https://api.github.com/repos/kubernetes/kubernetes/branches{/branch}","tags_url":"https://api.github.com/repos/kubernetes/kubernetes/tags","blobs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/kubernetes/kubernetes/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/kubernetes/kubernetes/git/refs{/sha}","trees_url":"https://api.github.com/repos/kubernetes/kubernetes/git/trees{/sha}","statuses_url":"https://api.github.com/repos/kubernetes/kubernetes/statuses/{sha}","languages_url":"https://api.github.com/repos/kubernetes/kubernetes/languages","stargazers_url":"https://api.github.com/repos/kubernetes/kubernetes/stargazers","contributors_url":"https://api.github.com/repos/kubernetes/kubernetes/contributors","subscribers_url":"https://api.github.com/repos/kubernetes/kubernetes/subscribers","subscription_url":"https://api.github.com/repos/kubernetes/kubernetes/subscription","commits_url":"https://api.github.com/repos/kubernetes/kubernetes/commits{/sha}","git_commits_url":"https://api.github.com/repos/kubernetes/kubernetes/git/commits{/sha}","comments_url":"https://api.github.com/repos/kubernetes/kubernetes/comments{/number}","issue_comment_url":"https://api.github.com/repos/kubernetes/kubernetes/issues/comments{/number}","contents_url":"https://api.github.com/repos/kubernetes/kubernetes/contents/{+path}","compare_url":"https://api.github.com/repos/kubernetes/kubernetes/compare/{base}...{head}","merges_url":"https://api.github.com/repos/kubernetes/kubernetes/merges","archive_url":"https://api.github.com/repos/kubernetes/kubernetes/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/kubernetes/kubernetes/downloads","issues_url":"https://api.github.com/repos/kubernetes/kubernetes/issues{/number}","pulls_url":"https://api.github.com/repos/kubernetes/kubernetes/pulls{/number}","milestones_url":"https://api.github.com/repos/kubernetes/kubernetes/milestones{/number}","notifications_url":"https://api.github.com/repos/kubernetes/kubernetes/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/kubernetes/kubernetes/labels{/name}","releases_url":"https://api.github.com/repos/kubernetes/kubernetes/releases{/id}","deployments_url":"https://api.github.com/repos/kubernetes/kubernetes/deployments","created_at":"2014-06-06T22:56:04Z","updated_at":"2016-08-02T15:29:48Z","pushed_at":"2016-08-02T15:29:09Z","git_url":"git://github.com/kubernetes/kubernetes.git","ssh_url":"git@github.com:kubernetes/kubernetes.git","clone_url":"https://github.com/kubernetes/kubernetes.git","svn_url":"https://github.com/kubernetes/kubernetes","homepage":"http://kubernetes.io","size":516114,"stargazers_count":15913,"watchers_count":15913,"language":"Go","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":5034,"mirror_url":null,"open_issues_count":4084,"forks":5034,"open_issues":4084,"watchers":15913,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/29714"},"html":{"href":"https://github.com/kubernetes/kubernetes/pull/29714"},"issue":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/29714"},"comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/issues/29714/comments"},"review_comments":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/29714/comments"},"review_comment":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/kubernetes/kubernetes/pulls/29714/commits"},"statuses":{"href":"https://api.github.com/repos/kubernetes/kubernetes/statuses/c2945d6c81a3b4d4ad70d29abb43b83ba0e7cdec"}}}}
{"actor":{"display_login":"erictune"}}