diff --git a/pkg/auth/user/user.go b/pkg/auth/user/user.go index 3af1959888e..f82a4776214 100644 --- a/pkg/auth/user/user.go +++ b/pkg/auth/user/user.go @@ -75,4 +75,8 @@ const ( Anonymous = "system:anonymous" APIServerUser = "system:apiserver" + + // core kubernetes process identities + KubeProxy = "system:kube-proxy" + KubeControllerManager = "system:kube-controller-manager" ) diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go index 99a4c6655c2..1510cb5633f 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go @@ -72,8 +72,9 @@ func init() { ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "cronjob-controller"}, Rules: []rbac.PolicyRule{ rbac.NewRule("get", "list", "watch", "update").Groups(batchGroup).Resources("cronjobs").RuleOrDie(), - rbac.NewRule("get", "list", "watch", "create", "delete").Groups(batchGroup).Resources("jobs").RuleOrDie(), + rbac.NewRule("get", "list", "watch", "create", "update", "delete").Groups(batchGroup).Resources("jobs").RuleOrDie(), rbac.NewRule("update").Groups(batchGroup).Resources("cronjobs/status").RuleOrDie(), + rbac.NewRule("list", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(), eventsRule(), }, }) @@ -103,11 +104,12 @@ func init() { addControllerRole(rbac.ClusterRole{ ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "disruption-controller"}, Rules: []rbac.PolicyRule{ - rbac.NewRule("get", "list").Groups(extensionsGroup).Resources("deployments").RuleOrDie(), - rbac.NewRule("get", "list").Groups(extensionsGroup).Resources("replicasets").RuleOrDie(), - rbac.NewRule("get", "list").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(), + rbac.NewRule("get", "list", "watch").Groups(extensionsGroup).Resources("deployments").RuleOrDie(), + rbac.NewRule("get", "list", "watch").Groups(extensionsGroup).Resources("replicasets").RuleOrDie(), + rbac.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(), rbac.NewRule("get", "list", "watch").Groups(policyGroup).Resources("poddisruptionbudgets").RuleOrDie(), rbac.NewRule("update").Groups(policyGroup).Resources("poddisruptionbudgets/status").RuleOrDie(), + eventsRule(), }, }) addControllerRole(rbac.ClusterRole{ @@ -119,17 +121,27 @@ func init() { eventsRule(), }, }) + addControllerRole(rbac.ClusterRole{ + ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "generic-garbage-collector"}, + Rules: []rbac.PolicyRule{ + // the GC controller needs to run list/watches, selective gets, and updates against any resource + rbac.NewRule("get", "list", "watch", "patch", "update", "delete").Groups("*").Resources("*").RuleOrDie(), + eventsRule(), + }, + }) addControllerRole(rbac.ClusterRole{ ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "horizontal-pod-autoscaler"}, Rules: []rbac.PolicyRule{ rbac.NewRule("get", "list", "watch").Groups(autoscalingGroup, extensionsGroup).Resources("horizontalpodautoscalers").RuleOrDie(), rbac.NewRule("update").Groups(autoscalingGroup, extensionsGroup).Resources("horizontalpodautoscalers/status").RuleOrDie(), rbac.NewRule("get", "update").Groups(legacyGroup).Resources("replicationcontrollers/scale").RuleOrDie(), + // TODO this should be removable when the HPA contoller is fixed + rbac.NewRule("get", "update").Groups(extensionsGroup).Resources("replicationcontrollers/scale").RuleOrDie(), rbac.NewRule("get", "update").Groups(extensionsGroup).Resources("deployments/scale", "replicasets/scale").RuleOrDie(), rbac.NewRule("list").Groups(legacyGroup).Resources("pods").RuleOrDie(), // TODO: fix MetricsClient to no longer require root proxy access // TODO: restrict this to the appropriate namespace - rbac.NewRule("proxy").Groups(legacyGroup).Resources("services").Names("https:heapster:").RuleOrDie(), + rbac.NewRule("proxy").Groups(legacyGroup).Resources("services").Names("https:heapster:", "http:heapster:").RuleOrDie(), eventsRule(), }, }) @@ -150,6 +162,13 @@ func init() { rbac.NewRule("get", "list", "delete", "deletecollection").Groups("*").Resources("*").RuleOrDie(), }, }) + addControllerRole(rbac.ClusterRole{ + ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "node-controller"}, + Rules: []rbac.PolicyRule{ + rbac.NewRule("get", "list", "update").Groups(legacyGroup).Resources("nodes").RuleOrDie(), + eventsRule(), + }, + }) addControllerRole(rbac.ClusterRole{ ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "persistent-volume-binder"}, Rules: []rbac.PolicyRule{ @@ -171,6 +190,7 @@ func init() { ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "pod-garbage-controller"}, Rules: []rbac.PolicyRule{ rbac.NewRule("list", "watch", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(), + rbac.NewRule("list").Groups(legacyGroup).Resources("nodes").RuleOrDie(), }, }) addControllerRole(rbac.ClusterRole{ @@ -188,7 +208,31 @@ func init() { // 1.0 controllers needed get, update, so without these old controllers break on new servers rbac.NewRule("get", "list", "watch", "update").Groups(legacyGroup).Resources("replicationcontrollers").RuleOrDie(), rbac.NewRule("update").Groups(legacyGroup).Resources("replicationcontrollers/status").RuleOrDie(), - rbac.NewRule("list", "watch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(), + rbac.NewRule("list", "watch", "patch", "create", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(), + eventsRule(), + }, + }) + addControllerRole(rbac.ClusterRole{ + ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "resourcequota-controller"}, + Rules: []rbac.PolicyRule{ + // quota can count quota on anything for reconcilation, so it needs full viewing powers + rbac.NewRule("list", "watch").Groups("*").Resources("*").RuleOrDie(), + rbac.NewRule("update").Groups(legacyGroup).Resources("resourcequotas/status").RuleOrDie(), + eventsRule(), + }, + }) + addControllerRole(rbac.ClusterRole{ + ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "route-controller"}, + Rules: []rbac.PolicyRule{ + rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(), + rbac.NewRule("patch").Groups(legacyGroup).Resources("nodes/status").RuleOrDie(), + eventsRule(), + }, + }) + addControllerRole(rbac.ClusterRole{ + ObjectMeta: api.ObjectMeta{Name: saRolePrefix + "service-account-controller"}, + Rules: []rbac.PolicyRule{ + rbac.NewRule("create").Groups(legacyGroup).Resources("serviceaccounts").RuleOrDie(), eventsRule(), }, }) diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy_test.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy_test.go index e6836481033..cdf9ab1199d 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy_test.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy_test.go @@ -30,6 +30,7 @@ import ( var rolesWithAllowStar = sets.NewString( saRolePrefix+"namespace-controller", saRolePrefix+"generic-garbage-collector", + saRolePrefix+"resourcequota-controller", ) // TestNoStarsForControllers confirms that no controller role has star verbs, groups, diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go index dbaa9e80efa..f2dbe31c4de 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go @@ -218,6 +218,7 @@ func ClusterRoles() []rbac.ClusterRole { Rules: []rbac.PolicyRule{ // Used to build serviceLister rbac.NewRule("list", "watch").Groups(legacyGroup).Resources("services", "endpoints").RuleOrDie(), + rbac.NewRule("get").Groups(legacyGroup).Resources("nodes").RuleOrDie(), }, }, { @@ -229,6 +230,23 @@ func ClusterRoles() []rbac.ClusterRole { rbac.NewRule("create").Groups(authorizationGroup).Resources("subjectaccessreviews").RuleOrDie(), }, }, + { + // a role to use for bootstrapping the kube-controller-manager so it can create the shared informers + // service accounts, and secrets that we need to create separate identities for other controllers + ObjectMeta: api.ObjectMeta{Name: "system:kube-controller-manager"}, + Rules: []rbac.PolicyRule{ + eventsRule(), + rbac.NewRule("create").Groups(legacyGroup).Resources("endpoints", "secrets", "serviceaccounts").RuleOrDie(), + rbac.NewRule("delete").Groups(legacyGroup).Resources("secrets").RuleOrDie(), + rbac.NewRule("get").Groups(legacyGroup).Resources("endpoints", "namespaces", "serviceaccounts").RuleOrDie(), + rbac.NewRule("update").Groups(legacyGroup).Resources("endpoints", "serviceaccounts").RuleOrDie(), + + rbac.NewRule("list", "watch").Groups("*").Resources("namespaces", "nodes", "persistentvolumeclaims", + "persistentvolumes", "pods", "secrets", "serviceaccounts").RuleOrDie(), + rbac.NewRule("list", "watch").Groups(extensionsGroup).Resources("daemonsets", "deployments", "replicasets").RuleOrDie(), + rbac.NewRule("list", "watch").Groups(batchGroup).Resources("jobs", "cronjobs").RuleOrDie(), + }, + }, } addClusterRoleLabel(roles) return roles @@ -241,7 +259,8 @@ func ClusterRoleBindings() []rbac.ClusterRoleBinding { rbac.NewClusterBinding("system:discovery").Groups(user.AllAuthenticated, user.AllUnauthenticated).BindingOrDie(), rbac.NewClusterBinding("system:basic-user").Groups(user.AllAuthenticated, user.AllUnauthenticated).BindingOrDie(), rbac.NewClusterBinding("system:node").Groups(user.NodesGroup).BindingOrDie(), - rbac.NewClusterBinding("system:node-proxier").Groups(user.NodesGroup).BindingOrDie(), + rbac.NewClusterBinding("system:node-proxier").Users(user.KubeProxy).BindingOrDie(), + rbac.NewClusterBinding("system:kube-controller-manager").Users(user.KubeControllerManager).BindingOrDie(), } addClusterRoleBindingLabel(rolebindings) return rolebindings diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-role-bindings.yaml b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-role-bindings.yaml index 5bb67c355fe..bf474f541eb 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-role-bindings.yaml +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-role-bindings.yaml @@ -46,6 +46,20 @@ items: name: system:authenticated - kind: Group name: system:unauthenticated +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRoleBinding + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:kube-controller-manager + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:kube-controller-manager + subjects: + - kind: User + name: system:kube-controller-manager - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRoleBinding metadata: @@ -72,7 +86,7 @@ items: kind: ClusterRole name: system:node-proxier subjects: - - kind: Group - name: system:nodes + - kind: User + name: system:kube-proxy kind: List metadata: {} diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml index 6abb09efad8..4909ee6c323 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml @@ -388,6 +388,89 @@ items: - /version verbs: - get +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRole + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:kube-controller-manager + rules: + - apiGroups: + - "" + attributeRestrictions: null + resources: + - events + verbs: + - create + - patch + - update + - apiGroups: + - "" + attributeRestrictions: null + resources: + - endpoints + - secrets + - serviceaccounts + verbs: + - create + - apiGroups: + - "" + attributeRestrictions: null + resources: + - secrets + verbs: + - delete + - apiGroups: + - "" + attributeRestrictions: null + resources: + - endpoints + - namespaces + - serviceaccounts + verbs: + - get + - apiGroups: + - "" + attributeRestrictions: null + resources: + - endpoints + - serviceaccounts + verbs: + - update + - apiGroups: + - '*' + attributeRestrictions: null + resources: + - namespaces + - nodes + - persistentvolumeclaims + - persistentvolumes + - pods + - secrets + - serviceaccounts + verbs: + - list + - watch + - apiGroups: + - extensions + attributeRestrictions: null + resources: + - daemonsets + - deployments + - replicasets + verbs: + - list + - watch + - apiGroups: + - batch + attributeRestrictions: null + resources: + - cronjobs + - jobs + verbs: + - list + - watch - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRole metadata: @@ -512,6 +595,13 @@ items: verbs: - list - watch + - apiGroups: + - "" + attributeRestrictions: null + resources: + - nodes + verbs: + - get - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRole metadata: diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-role-bindings.yaml b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-role-bindings.yaml index 12f56683e64..4f477d0ff34 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-role-bindings.yaml +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-role-bindings.yaml @@ -90,6 +90,21 @@ items: - kind: ServiceAccount name: endpoint-controller namespace: kube-system +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRoleBinding + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:generic-garbage-collector + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:controller:generic-garbage-collector + subjects: + - kind: ServiceAccount + name: generic-garbage-collector + namespace: kube-system - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRoleBinding metadata: @@ -135,6 +150,21 @@ items: - kind: ServiceAccount name: namespace-controller namespace: kube-system +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRoleBinding + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:node-controller + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:controller:node-controller + subjects: + - kind: ServiceAccount + name: node-controller + namespace: kube-system - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRoleBinding metadata: @@ -195,6 +225,51 @@ items: - kind: ServiceAccount name: replication-controller namespace: kube-system +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRoleBinding + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:resourcequota-controller + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:controller:resourcequota-controller + subjects: + - kind: ServiceAccount + name: resourcequota-controller + namespace: kube-system +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRoleBinding + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:route-controller + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:controller:route-controller + subjects: + - kind: ServiceAccount + name: route-controller + namespace: kube-system +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRoleBinding + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:service-account-controller + roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: system:controller:service-account-controller + subjects: + - kind: ServiceAccount + name: service-account-controller + namespace: kube-system - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRoleBinding metadata: diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml index 735509e9333..00944113282 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml @@ -79,6 +79,7 @@ items: - delete - get - list + - update - watch - apiGroups: - batch @@ -87,6 +88,14 @@ items: - cronjobs/status verbs: - update + - apiGroups: + - "" + attributeRestrictions: null + resources: + - pods + verbs: + - delete + - list - apiGroups: - "" attributeRestrictions: null @@ -226,6 +235,7 @@ items: verbs: - get - list + - watch - apiGroups: - extensions attributeRestrictions: null @@ -234,6 +244,7 @@ items: verbs: - get - list + - watch - apiGroups: - "" attributeRestrictions: null @@ -242,6 +253,7 @@ items: verbs: - get - list + - watch - apiGroups: - policy attributeRestrictions: null @@ -258,6 +270,15 @@ items: - poddisruptionbudgets/status verbs: - update + - apiGroups: + - "" + attributeRestrictions: null + resources: + - events + verbs: + - create + - patch + - update - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRole metadata: @@ -303,6 +324,35 @@ items: - create - patch - update +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRole + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:generic-garbage-collector + rules: + - apiGroups: + - '*' + attributeRestrictions: null + resources: + - '*' + verbs: + - delete + - get + - list + - patch + - update + - watch + - apiGroups: + - "" + attributeRestrictions: null + resources: + - events + verbs: + - create + - patch + - update - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRole metadata: @@ -337,6 +387,14 @@ items: verbs: - get - update + - apiGroups: + - extensions + attributeRestrictions: null + resources: + - replicationcontrollers/scale + verbs: + - get + - update - apiGroups: - extensions attributeRestrictions: null @@ -357,6 +415,7 @@ items: - "" attributeRestrictions: null resourceNames: + - 'http:heapster:' - 'https:heapster:' resources: - services @@ -453,6 +512,32 @@ items: - deletecollection - get - list +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRole + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:node-controller + rules: + - apiGroups: + - "" + attributeRestrictions: null + resources: + - nodes + verbs: + - get + - list + - update + - apiGroups: + - "" + attributeRestrictions: null + resources: + - events + verbs: + - create + - patch + - update - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRole metadata: @@ -560,6 +645,13 @@ items: - delete - list - watch + - apiGroups: + - "" + attributeRestrictions: null + resources: + - nodes + verbs: + - list - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRole metadata: @@ -638,6 +730,7 @@ items: - create - delete - list + - patch - watch - apiGroups: - "" @@ -648,6 +741,94 @@ items: - create - patch - update +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRole + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:resourcequota-controller + rules: + - apiGroups: + - '*' + attributeRestrictions: null + resources: + - '*' + verbs: + - list + - watch + - apiGroups: + - "" + attributeRestrictions: null + resources: + - resourcequotas/status + verbs: + - update + - apiGroups: + - "" + attributeRestrictions: null + resources: + - events + verbs: + - create + - patch + - update +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRole + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:route-controller + rules: + - apiGroups: + - "" + attributeRestrictions: null + resources: + - nodes + verbs: + - list + - watch + - apiGroups: + - "" + attributeRestrictions: null + resources: + - nodes/status + verbs: + - patch + - apiGroups: + - "" + attributeRestrictions: null + resources: + - events + verbs: + - create + - patch + - update +- apiVersion: rbac.authorization.k8s.io/v1alpha1 + kind: ClusterRole + metadata: + creationTimestamp: null + labels: + kubernetes.io/bootstrapping: rbac-defaults + name: system:controller:service-account-controller + rules: + - apiGroups: + - "" + attributeRestrictions: null + resources: + - serviceaccounts + verbs: + - create + - apiGroups: + - "" + attributeRestrictions: null + resources: + - events + verbs: + - create + - patch + - update - apiVersion: rbac.authorization.k8s.io/v1alpha1 kind: ClusterRole metadata: