• Stars
    star
    113
  • Rank 310,115 (Top 7 %)
  • Language
    Go
  • License
    Apache License 2.0
  • Created almost 6 years ago
  • Updated 5 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

JWT-to-RBAC lets you automatically generate RBAC resources based on JWT tokens

CircleCI Go Report Card Docker Automated build

JWT-to-RBAC

JWT-to-RBAC lets you automatically generate RBAC resources based on JWT token.

Context

For authentication we use Dex with the LDAP and GitHub connectors. The users in LDAP have group memberships, GitHub users can be members of a team in an organization and Dex issues a JWT token containing these memberships. The JWT-to-RBAC project can create ServiceAccount, ClusterRoles and ClusterroleBindings based on JWT tokens. When we create a new ServiceAccount K8s automatically generates a service account token.

For more information and context please read the Provider agnostic authentication and authorization in Kubernetes post.

JWT-to-RBAC is a core part of Banzai Cloud Pipeline, a Cloud Native application and devops platform that natively supports multi- and hybrid-cloud deployments with multiple authentication backends. Check out the developer beta:

Requirements:

There are some pre-requirements to kick this of for your own testing.

  • Configured Dex server as OIDC provider which issues JWT tokens. If you want to issue tokens with Dex you have to configure it with LDAP connector. You can use the Banzai Cloud Dex chart.
  • GitHub account assigned for an organization or configured LDAP server - you can use the openldap Docker image
  • Authentication application which uses Dex as an OpenID connector (in our case is Pipeline.

Dex acts as a shim between a client app and the upstream identity provider. The client only needs to understand OpenID Connect to query Dex.

The issued ID tokens must contain the following claims:

  • name: string
  • email: string
  • email_verified: bool
  • groups: list of strings
  • federated_claims: object

federated_claims must contain:

  • connector_id: string (github/ldal/local)
  • user_id: string

The whole process is broken down to two main parts:

  • Dex (OIDC) auth flow
  • jwt-to-rbac ServiceAccount creation flow

Dex authentication flow:

  1. User visits Authentication App.
  2. Authentication App redirects user to Dex with an OAuth2 request.
  3. Dex determines user's identity.
  4. Dex redirects user to Authentication App with a code.
  5. Authentication App exchanges code with Dex for an ID token.

jwt-to-rbac Flow:

  1. Authentication App has ID token (JWT)
  2. POST ID token to jwt-to-rbac App
  3. jwt-to-rbac validates ID token with Dex or other OIDC prvider
  4. jwt-to-rbac extracts username, groups and so on from the token
  5. jwt-to-rbac calls API server to crate ServiceAccount, ClusterRoles and ClusterRoleBindings
  6. jwt-to-rbac get service account token and sends it to Authentication App
  7. Authentication App sends back the service account token to User
  8. User authenticate on K8s using service account token

The ID token issued by Dex has a following content:

{
  "iss": "http://dex/dex",
  "sub": "CiNjbj1qYW5lLG91PVBlb3BsZSxkYz1leGFtcGxlLGRjPW9yZxIEbGRhcA",
  "aud": "example-app",
  "exp": 1549661603,
  "iat": 1549575203,
  "at_hash": "_L5EkeNocRsG7iuUG-pPpQ",
  "email": "[email protected]",
  "email_verified": true,
  "groups": [
    "admins",
    "developers"
  ],
  "name": "jane",
  "federated_claims": {
    "connector_id": "ldap",
    "user_id": "cn=jane,ou=People,dc=example,dc=org"
  }
}

After jwt-to-rbac extracts the information from the token, creates ServiceAccount and ClusterRoleBinding using one of the default K8s ClusterRole as roleRef or generate one defined in configuration if it does't exist.

Default K8s ClusterRoles used by jwt-to-rbac

The JWT-to-RBAC dos not create a new ClusterRole in every case; for example if a user is a member of admin group, it doesn't create this ClusterRole because K8s has already one by default.

Default ClusterRole Description
cluster-admin Allows super-user access to perform any action on any resource.
admin Allows admin access, intended to be granted within a namespace using a RoleBinding.
edit Allows read/write access to most objects in a namespace.
view Allows read-only access to see most objects in a namespace.

jwt-to-rbac crate custom ClusterRole defined in config

In most of the cases there are different LDAP groups, so custom groups can be configured with custom rules.

[[rbachandler.customGroups]]
groupName = "developers"
[[rbachandler.customGroups.customRules]]
verbs = [
  "get",
  "list"
]
resources = [
  "deployments",
  "replicasets",
  "pods"
]
apiGroups = [
  "",
  "extensions",
  "apps"
]

define GitHub custom roles in config

[[rbachandler.customGroups]]
groupName = "githubOrg-githubTeam"
[[rbachandler.customGroups.customRules]]
verbs = [
  "get",
  "list"
]
resources = [
  "deployments",
  "replicasets",
  "pods"
]
apiGroups = [
  "",
  "extensions",
  "apps"
]

or specify GitHub organization as default org

[rbachandler]
githubOrg = "github_organization"
[[rbachandler.customGroups]]
groupName = "githubTeam"
[[rbachandler.customGroups.customRules]]
verbs = [
  "get",
  "list"
]
resources = [
  "deployments",
  "replicasets",
  "pods"
]
apiGroups = [
  "",
  "extensions",
  "apps"
]

Example configuration in yaml using default GitHub org

issued jwt:

{
  "iss": "http://dex/dex",
  "sub": "xxxxxxxxxxxxxxxxxxxxx",
  "aud": "example-app",
  "exp": 1551179050,
  "iat": 1551092650,
  "at_hash": "xxxxxxxxxxxxxxxxxxx",
  "email": "[email protected]",
  "email_verified": true,
  "groups": [
    "pokeorg",
    "pokeorg:admin",
    "pokeorg:developer"
  ],
  "name": "Peter Balogh",
  "federated_claims": {
    "connector_id": "github",
    "user_id": "13311234"
  }
}

example config:

app:
  addr: ":5555"

log:
  level: "4"
  format: "json"
  noColor: true

tokenhandler:
  oidc:
    clientID: example-app
    issuerURL: "http://dex/dex"

rbachandler:
  githubOrg: "pokeorg"
  customGroups:
  - groupName: developer
    customRules:
    - verbs: [ "get", "list" ]
      resources: [ "deployments", "replicasets", "pods" ]
      apiGroups: [ "", "extensions", "apps" ]
    namespaces: ["example_namespace"] # Only if you want to isolate the customRules to some namespaces, if you want that the customRules to apply to all namespaces delete this hole line...
  kubeConfig: "/Users/poke/.kube/config"

Define custom CA cert or set insecure connection

[tokenhandler]
caCertPath = "/path/to/tls.crt"
insecure = false

Setting insecure conection in command line:

jwt-to-rbac --tokenhandler.insecure=true

So to conclude on the open source JWT-to-RBAC project - follow these stpes if you would like to try it or check it out already in action by subscribing to our free developer beta at https://beta.banzaicloud.io/.

1. Deploy jwt-to-rbac to Kubernetes

After you cloning the GitHub repository you can compile a code and make a docker image with one command.

make docker

If you are using docker-for-desktop or minikube, you'll be able to deploy it using locally with the newly built image.

kubectl create -f deploy/rbac.yaml
kubectl create -f deploy/configmap.yaml
kubectl create -f deploy/deployment.yaml
kubectl create -f deploy/service.yaml
# port-forward locally
kubectl port-forward svc/jwt-to-rbac 5555

Now you can communicate with the jwt-to-rbac app.

2. POST ID token issued by Oidc to jwt-to-rbac API

curl --request POST \
  --url http://localhost:5555/rbac/ \
  --header 'Content-Type: application/json' \
  --data '{"token": "example.jwt.token"}'

# response:
{
    "Email": "[email protected]",
    "Groups": [
        "admins",
        "developers"
    ],
    "FederatedClaims": {
        "connector_id": "ldap",
        "user_id": "cn=jane,ou=People,dc=example,dc=org"
    }
}

The ServiceAccount, ClusterRoles (if ID token has some defined custom groups we discussed) and ClusterRoleBindings are created.

Listing the created K8s resources:

curl --request GET \
  --url http://localhost:5555/rbac \
  --header 'Content-Type: application/json'

#response:
{
    "sa_list": [
        "janedoe-example-com"
    ],
    "crole_list": [
        "developers-from-jwt"
    ],
    "crolebind_list": [
        "janedoe-example-com-admin-binding",
        "janedoe-example-com-developers-from-jwt-binding"
    ]
}

3. GET the default K8s token of ServiceAccount

curl --request GET \
  --url http://localhost:5555/tokens/janedoe-example-com \
  --header 'Content-Type: application/json'

# response:
[
    {
        "name": "janedoe-example-com-token-m4gbj",
        "data": {
            "ca.crt": "example-ca-cer-base64",
            "namespace": "ZGVmYXVsdA==",
            "token": "example-k8s-sa-token-base64"
        }
    }
]

4. Generate a ServiceAccount token with TTL

curl --request POST \
  --url http://localhost:5555/tokens/janedoe-example-com \
  --header 'Content-Type: application/json'
  --data '{"duration": "12h30m"}'

# response:
[
    {
        "name": "janedoe-example-com-token-df3re",
        "data": {
            "ca.crt": "example-ca-cer-base64",
            "namespace": "ZGVmYXVsdA==",
            "token": "example-k8s-sa-token-with-ttl-base64"
        }
    }
]

Now you have a base64 encoded service account token.

5. Accessing with ServiceAccount token

You can use service account token from command line:

kubectl --token $TOKEN_TEST --server $APISERVER get po

Or create kubectl context with it:

export TOKEN=$(echo "example-k8s-sa-token-base64" | base64 -D)
kubectl config set-credentials "janedoe-example-com" --token=$TOKEN
# with kubectl config get-clusters you can get cluster name
kubectl config set-context "janedoe-example-com-context" --cluster="clustername" --user="janedoe-example-com" --namespace=default
kubectl config use-context janedoe-example-com-context
kubectl get pod

As a final note - since we use Dex, which is an identity service that uses OpenID Connect to drive authentication for other apps, any other supported connector can be used for authentication to Kubernetes.

More Repositories

1

bank-vaults

A Vault swiss-army knife: a K8s operator, Go client with automatic token renewal, automatic configuration, multiple unseal options and more. A CLI tool to init, unseal and configure Vault (auth methods, secret engines). Direct secret injection into Pods.
Go
1,864
star
2

pipeline

Banzai Cloud Pipeline is a solution-oriented application platform which allows enterprises to develop, deploy and securely scale container-based applications in multi- and hybrid-cloud environments.
Go
1,494
star
3

logging-operator

Logging operator for Kubernetes based on Fluentd and Fluentbit
Go
1,027
star
4

koperator

Oh no! Yet another Apache Kafka operator for Kubernetes
Go
782
star
5

istio-operator

An operator that manages Istio deployments on Kubernetes
Go
534
star
6

banzai-charts

Curated list of Banzai Cloud Helm charts used by the Pipeline Platform
Mustache
367
star
7

thanos-operator

Kubernetes operator for deploying Thanos
Go
280
star
8

pke

PKE is an extremely simple CNCF certified Kubernetes installer and distribution, designed to work on any cloud, VM or bare metal.
Go
263
star
9

hpa-operator

Horizontal Pod Autoscaler operator for Kubernetes. Annotate and let the HPA operator do the rest.
Go
239
star
10

dast-operator

Dynamic Application and API Security Testing
Go
189
star
11

spark-metrics

Spark metrics related custom classes and sinks (e.g. Prometheus)
Scala
175
star
12

cloudinfo

Cloud instance type and price information as a service
Go
165
star
13

telescopes

Telescopes is a cloud instance types and full cluster layout recommender consisting of on-demand and spot/preemptible AWS EC2, Google, Azure, Oracle and Alibaba cloud instances.
Go
163
star
14

hollowtrees

A ruleset based watchguard to keep spot/preemptible instance based clusters safe, with plugins for VMs, Kubernetes, Prometheus and Pipeline
Go
155
star
15

kurun

Run main.go in Kubernetes with one command, also port-forward your app into Kubernetes
Go
132
star
16

service-tools

Prepare your Node.js application for production
TypeScript
99
star
17

nodepool-labels-operator

Nodepool Labels operator for Kubernetes
Go
69
star
18

drone-kaniko

A thin shim-wrapper around the official Google Kaniko Docker image to make it behave like the Drone Docker plugin.
Shell
56
star
19

pvc-operator

Go
51
star
20

satellite

Determine your cloud provider with a simple HTTP call
Go
50
star
21

prometheus-jmx-exporter-operator

Go
45
star
22

chartsec

Helm Chart security scanner
Go
45
star
23

anchore-image-validator

Anchore Image Validator lets you automatically detect or block security issues just before a Kubernetes pod starts.
Go
44
star
24

spot-price-exporter

Prometheus exporter to track spot price history
Go
41
star
25

logrus-runtime-formatter

Golang runtime package based automatic function, line and package fields for Logrus
Go
40
star
26

kubeconfiger

Example tool for cleaning up untrusted kubeconfig files
Go
36
star
27

spot-termination-exporter

Prometheus spot instance exporter to monitor AWS instance termination with Hollowtrees
Go
36
star
28

imps

ImagePullSecrets controller allows you to distribute image pull secrets based on namespace/pod matches.
Go
32
star
29

banzai-cli

CLI for Banzai Cloud Pipeline platform
Go
30
star
30

allspark

AllSpark is a simple building block for quickly building web microservice deployments for demo purposes.
Go
26
star
31

istio-client-go

Golang API representation for Istio resources
Go
23
star
32

istio-external-demo

Working example for restricting access to external services from an Istio service mesh
23
star
33

k8s-cncf-meetup

Kubernetes and Cloud Native Computing Meetup slides
DIGITAL Command Language
19
star
34

spot-config-webhook

A Kubernetes mutating admission webhook that sets the scheduler of specific pods based on a ConfigMap.
Go
19
star
35

aws-billing-alarm

Shell
15
star
36

aws-autoscaling-exporter

Prometheus exporter with AWS auto scaling group and instance level metrics for Hollowtrees
Go
14
star
37

docker-cruise-control

Linkedin's Cruise Control container image built for Koperator (https://github.com/banzaicloud/koperator)
Shell
13
star
38

lambda-slack-bot

AWS Lambda Golang Slack bot to list running EC2 instances
Go
12
star
39

fluent-plugin-label-router

Fluentd plugin to route records based on Kubernetes labels and namespace
Ruby
11
star
40

preemption-exporter

Prometheus preemptible instance exporter to monitor GCP instance termination with Hollowtrees
Go
11
star
41

docker-kafka

Dockerfile to building Docker image for Apache Kafka
Dockerfile
10
star
42

ht-k8s-action-plugin

Hollowtrees plugin used to interact with Kubernetes on specific event triggers
Go
10
star
43

crd-updater

Helm 3 library chart that emulates Helm 2 CRD update behavior.
Go
10
star
44

jmx-exporter-loader

Java
10
star
45

go-code-generation-demo

Go
9
star
46

bank-vaults-workshop

Material for the Hacktivity 2019 - Bank-Vaults workshop
7
star
47

pipeline-cp-launcher

Pipeline ControlPlane launcher using AWS Cloudformation or Azure ARM template, running on Kubernetes
Makefile
7
star
48

go-cruise-control

It's client library written in Golang for interacting with Linkedin Cruise Control using its HTTP API.
Go
6
star
49

zeppelin-pdi-example

6
star
50

bank-vaults-docs

Bank-Vaults documentation
Shell
5
star
51

logging-operator-docs

Logging operator documentation
Shell
4
star
52

koperator-docs

Documentation for Koperator - the operator for managing Apache Kafka on Kubernetes
HTML
4
star
53

banzai-types

Common types, configs and utils used across several Banzai Cloud projects
Go
4
star
54

circleci-orbs

Makefile
3
star
55

ht-aws-asg-action-plugin

Hollowtrees plugin to detach instances from auto scaling groups
Go
3
star
56

drone-plugin-sonar

Drone plugin for static code analysis
Go
3
star
57

fluent-plugin-tag-normaliser

Fluent output plugin to transform tags based on record content
Ruby
2
star
58

cicd-go

A Go client for the Pipeline CI/CD subsystem
Go
2
star
59

gin-utilz

Gin framework utilities
Go
2
star
60

banzailint

Custom lint rules for Banzai Cloud code
Makefile
2
star
61

docker-jmx-exporter

Docker image for JMX-exporter
Dockerfile
2
star
62

.github

Github default files
1
star
63

developer-guide

Guide for developers on writing code and maintaining projects
1
star
64

cadence-aws-sdk

Cadence wrapper around the AWS Go SDK to make working with the AWS API easier in Cadence workflows
Go
1
star
65

drone-plugin-k8s-client

Drone plugin implementation for k8s operations
Go
1
star
66

thanos-operator-docs

Thanos operator documentation
Shell
1
star
67

dynamic-class-gen

Java
1
star
68

custom-runner

go custom runner
Go
1
star
69

cluster-registry

Go
1
star
70

log-socket

Service and CLI tool for forwarding logs through a WebSocket connection
Go
1
star
71

kube-service-annotate

A Kubernetes mutating webhook to annotate services based on rules
Go
1
star
72

pipeline-sdk

SDK for extending Pipeline
Go
1
star
73

integrated-service-sdk

Client SDK for the Integrated Service Operator
Go
1
star
74

pipeline-cp-images

Pipeline ControlPlane images
Shell
1
star
75

dockerized-newman

Automated end-2-end testing with Postman in Docker
1
star
76

drone-plugin-zeppelin-client

Zeppelin REST API client plugin for Drone. A step in the Pipeline PaaS CI/CD component to provision a Kubernetes cluster or use a managed one
Go
1
star