Minimal permission for karmada dashboard
What would you like to be added: Don't use kubeconfig directly, prefered to use jwt token as the first choice, if not fallback to kubeconfig.
Why is this needed:
Security is an important topic for karmada dashboard development, since some security problems have been submited, we should pay more attention to security. Currently, karmada dashboard relies on kubeconfig file including karmada-api context and karmada-host context to take control of apisever including karmada apiserver and kubernetes apiserver, but we found that it's not necessary to use kubeconfig directly from early bi-weekly meetiing discussion. So we decided to minibase the permission requirements, but make sure karmada dasbboard still works.
for the kubernetes-dashboard-api module, follow the instructions:
-
on member cluster, create a serviceaccount and authorize the serviceaccount
kubectl apply --kubeconfig ~/.kube/members.config --context member1 -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: testsa --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: testsa roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: testsa namespace: default EOF -
on karmada control-plane , create a serviceaccount and authorize the serviceaccount with
clusters/proxypermissionkubectl apply --kubeconfig ~/.kube/karmada.config --context karmada-apiserver -f - <<EOF apiVersion: v1 kind: ServiceAccount metadata: name: testsa namespace: default --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: cluster-proxy-clusterrole rules: - apiGroups: - 'cluster.karmada.io' resources: - clusters/proxy resourceNames: - member1 verbs: - '*' - apiGroups: - cluster.karmada.io resources: - clusters verbs: - list - get --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: cluster-proxy-clusterrolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-proxy-clusterrole subjects: - kind: ServiceAccount name: testsa namespace: default # The token generated by the serviceaccount can parse the group information. Therefore, you need to specify the group information below. - kind: Group name: "system:serviceaccounts" - kind: Group name: "system:serviceaccounts:default" EOF -
validate the service acount with jwt token
- create a secret for sa and generate a jwt token
command to fetch jwt tokenkubectl apply --kubeconfig ~/.kube/karmada.config --context karmada-apiserver -f - <<EOF apiVersion: v1 kind: Secret metadata: name: testsa annotations: kubernetes.io/service-account.name: testsa type: kubernetes.io/service-account-token EOFkubectl --kubeconfig ~/.kube/karmada.config --context karmada-apiserver get secret testsa -oyaml | grep token: | awk '{print $2}' | base64 -d - generate a kubeconfig based on jwt token
TOKEN=$(kubectl --kubeconfig ~/.kube/karmada.config --context karmada-apiserver get secret testsa -oyaml | grep token: | awk '{print $2}' | base64 -d) cat > testsa.config <<EOF apiVersion: v1 clusters: - cluster: insecure-skip-tls-verify: true server: {karmada-apiserver-address} # Replace {karmada-apiserver-address} with karmada-apiserver-address. You can find it in /root/.kube/karmada.config file. name: testsa contexts: - context: cluster: testsa user: testsa name: testsa current-context: testsa kind: Config users: - name: testsa user: token: {token} # Replace {token} with the token obtain above. EOF - test the kubeconfig file:
-
get resource from member1 cluster ✅
-
get resource from member2/member3 cluster ❌
-
- create a secret for sa and generate a jwt token
-
test the jwt token with rest api(throw the api module lifted from the kubernetes dashboard)
-
get resource from member1 cluster ✅
curl -s GET 'http://127.0.0.1:8000/api/v1/namespace?filterBy&sortBy&itemsPerPage&page&metricNames&aggregations' \ --header 'X-Member-ClusterName: member1' \ --header 'Authorization: Bearer {token}' -
get resource from member2 cluster ❌
curl -s GET 'http://127.0.0.1:8000/api/v1/namespace?filterBy&sortBy&itemsPerPage&page&metricNames&aggregations' \ --header 'X-Member-ClusterName: member2' \ --header 'Authorization: Bearer {token}'
-
references:
- https://karmada.io/docs/userguide/globalview/aggregated-api-endpoint/#step2-grant-permission-to-user-systemadmin
- https://karmada.io/docs/userguide/bestpractices/unified-auth/#step2-create-serviceaccount-in-karmada-control-plane
TBD
for the karmada-dashboard-api module, currently used permissions:
- read configmap from karmada-host
- permission for communication with karmada-api-server
references:
- https://karmada.io/docs/next/administrator/security/component-permission/