mesosphere / traefik-forward-auth

215 stars 46 forks source link

RBAC support #12

Closed jr0d closed 4 years ago

jr0d commented 4 years ago

Description

This patch adds an authorizer interface with a single implementation based on Kubernetes RBAC. Adding this interface to the forward auth layer allows for defining application independent authorization policies targeting HTTP paths. This feature is useful for applications which share a TFA instance (needed for SSO) but do not implement an authorization mechanism.

RBAC Implementation

Rather than creating a new set of policy CRDs or a new policy database, it was deemed acceptable during discovery to take advantage of PolicyRule.NonResourceURLs provided by the Kubernetes RBAC API. Access review is performed internally in order to reduce access review requests to the API server. In order to accomplish this, an informer cache is constructed for ClusterRole and ClusterRoleBinding objects.

Usage

traefik-foward-auth must be launched with the --enable-rbac flag.

ClusterRoles for view, edit, and admin are defined for various endpoints. For instance:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: konvoy-graphql-view
rules:
- nonResourceURLs:
  - /ops/portal/graphql
  - /ops/portal/graphql/*
  verbs:
  - get
  - head

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: konvoy-graphql-edit
rules:
- nonResourceURLs:
  - /ops/portal/graphql
  - /ops/portal/graphql/*
  verbs:
  - get
  - head
  - post
  - put

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: konvoy-graphql-admin
rules:
- nonResourceURLs:
  - /ops/portal/graphql
  - /ops/portal/graphql/*
  verbs:
  - get
  - head
  - post
  - put
  - delete

User or Group subjects are bound to these roles in order to create the desired access policy:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: scientist-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: konvoy-graphql-edit
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: oidc:scientists

AuthZ Passthrough

For resources which implement an internal RBAC policy, routes can be defined which bypass the authorization flow. For example:

--authz-passthrough="/myapp,/myapp/*"

Alternative Approaches

Initially, I attempted to use a generic rest client targeting SubjectAccessReview endpoint for authorizing requests. For user interfaces with 100s of resources (images, scripts, etc) and asynchronous browser side requests, I quickly ran into default api server rate limits. This is where I transitioned to using an informer cache with internal authorization.

I was later informed of a specialized client which caches authorization results for a short time, which seems like a great thing do. I still may implement this in future iterations but did not get a chance to fully test this. I still worry that even with caching, busy clusters with multiple simultaneous users accessing "feature rich" UIs may still overwhelm the pod API server connection pool as each request for every verb, user, and endpoint must be verified once before it can be cached.

sebbrandt87 commented 4 years ago

fixes #8