Proxy K8S app delegating authentication of requests from other pods

4/25/2019

Background

I have a K8S cluster with a number of different pods that have their own specific service accounts, cluster roles, and cluster role bindings, so that they can execute various read/write requests directly with the K8S REST API. There are some complicated requests that can be issued, and I'd like to make a function to wrap the complex logic. However, the various services in the cluster are written in multiple (i.e. 6+) programming languages, and there does not (yet) seem to be a trivial way to allow all these services to directly re-use this code.

I'm considering creating a "proxy" micro-service, that exposes its own REST API, and issues the necessary requests and handles the "complex logic" on behalf of the client.


Problem

The only problem is that, with the current deployment model, a client could request that the proxy micro-service execute an HTTP request that the client itself isn't authorized to make.


Question

Is there a trivial/straightforward way for one pod, for example, to identify the client pod, and execute some kind of query/result-of-policy operation (i.e. by delegating the authentication to the K8S cluster authentication mechanism itself) to determine if it should honor the request from the client pod?


-- Coder
api-design
authentication
kubernetes
rest
security

1 Answer

6/19/2019

Kubernetes Authentication model represents a way how the particular user or service account can be entitled in k8s cluster, however Authorization methods determine whether initial request from the cluster visitor, aimed to do some action on cluster resources/objects, has sufficient permissions to make that possible.

Due to the fact that you've used specific service accounts per each Pod entire the cluster and granting them specific RBAC rules, it might be possible to use SelfSubjectAccessReview API in order to inspect requests to k8s REST API and determine whether the client's Pod service account has appropriate permission to perform any action on target's Pod namespace.

That can be achievable using kubectl auth can-i subcommand by submitting essential information for user impersonation.

I assume that you might also be able to query k8s authorization API group within HTTP request schema and then parse structured data from JSON/YAML format, like in the example below:

Regular kubectl auth can-i command to check whether default SA can retrieve data about Pods in default namespace:

kubectl auth can-i get pod --as system:serviceaccount:default:default

Equivalent method via HTTP call to k8s REST API using JSON type of content within Bearer Token authentication:

curl -k \
    -X POST \
    -d @- \
    -H "Authorization: Bearer $MY_TOKEN" \
    -H 'Accept: application/json' \
    -H "Impersonate-User: system:serviceaccount:default:default" \
    -H 'Content-Type: application/json' \
    https://<API-Server>/apis/authorization.k8s.io/v1/selfsubjectaccessreviews <<'EOF'
{
  "kind": "SelfSubjectAccessReview",
  "apiVersion": "authorization.k8s.io/v1",
  "spec":{"resourceAttributes":{"namespace":"default","verb":"get","resource":"pods"}}
}
EOF

Output:

.... "status": { "allowed": true, "reason": "RBAC: allowed by RoleBinding ....

-- mk_sta
Source: StackOverflow