Coder Social home page Coder Social logo

gepaplexx / multena-proxy Goto Github PK

View Code? Open in Web Editor NEW
17.0 2.0 4.0 20.82 MB

Multi-tenancy LGTM stack proxy enhancing authorization with LBAC, integrating with metrics & logs for Grafana

License: GNU Affero General Public License v3.0

Dockerfile 0.46% Go 98.31% Python 1.24%
grafana multi-tenancy multi-tenant prometheus proxy thanos authorization loki middleware multitenancy

multena-proxy's Introduction

Multena Proxy

Making the LGTM-Stack multi tenancy ready

Go Report Card Build Status GoDoc Release License


Multena Proxy is a multi-tenancy ready tool designed to enhance the authorization capabilities of your LGTM (Loki Grafana Tempo Mimir(Prometheus Style API / OpenMetrics)) stack. Built with LBAC (Label Based Access Control) at its core.

Multena provides secure and granular user authorization based on assigned tenant labels. It integrates seamlessly with PrometheusAPI and Loki, and should support generic oauth provider for identity management. With features like ConfigMap-based configuration, flexible authorization providers, and multiple tenant labels, Multena ensures that the right data is accessible to the right users.


NOTE: Multena was initially developed to support OpenShift 4's internal Prometheus, which is powered by Thanos. As a result, many references in Multena are made to Thanos, which serves as an API following the Prometheus style.

How does it work?

graph TD
    A[Receive Request] -->|Extract Token| B{Get OAuth Token?}
    B -->|Error| E[Deny Request]
    D -->|Error| E
    D -->|Valid & Not Skip| G{Enforce Query?}
    D -->|Valid & Skip| F[Stream Up to Upstream and End]
    B -->|Success| D{Validate Labels?}
    G -->|Error| E
    G -->|Success| F

In summary, here's how Multena works:

  1. Multena receives a request.
  2. Multena performs an authorization check in the form of a JWT token validation.
  3. If the user is not authorized, Multena denies the query without further processing.
  4. If the user is authorized, Multena examines which labels corrispond to the user.
  5. If the user has no labels, Multena denies the query without further processing.
  6. if the user has labels and its skip (e.g., cluster wide access), it will forward the request to the upstream server without further processing.
  7. If the user has labels, and it's not a skip, Multena checks if the values in the label match in the query are allowed for the user.
  8. If the values are not allowed, Multena dienies the request without further processing.
  9. If there are no label matches for the tenant label (e.g., namespace), Multena will append the allowed labels to the query.
  10. If the values are allowed, Multena forwards the query to the specific endpoint or service responsible for processing the query.
  11. Multena streams the response from the upstream server to the client.

By performing authorization checks, label matching, appending labels, Multena ensures that users can only query data they are authorized to access.

Multena Features

Feature Description
Authorization Based on Labels Enables access control and permissions based on specified labels, ensuring fine-grained access control tailored to your needs.
Configurable via ConfigMap Allows easy configuration of the proxy using a ConfigMap, simplifying setup process and management of configuration settings.
Flexible Authorization Providers Supports both ConfigMap and database label store providers. Choose the provider that best fits your requirements.
Integration with PrometheusAPI and Loki Seamlessly integrates with PrometheusAPI and Loki for efficient authorization. Manage and control access to these powerful observability tools.
Authentication via OAuth Authenticate users using a OAuth provider with JWKS (JSON Web Key Set) to ensure secure and reliable authorization.
Admin Group Privileges Includes an admin group feature allowing users in the specified admin group to bypass enforcing steps. This is useful for granting administrative privileges to specific users.
Multiple Tenant Label values Supports multiple tenant label values for managing different sets of label values for different tenants. Customize and control access for various groups and users based on their respective tenant label.
Strict communication Multena can send either a bearer token in requests to communicate with components protected by OAuth2 proxy or use mutualTLS to ensure a strict and secure communication.

Currently queryable

  • Metrics
  • Logging
  • Traces
  • Profiles

Request flow

integrated flow

flowchart LR
    User -->|Authentication| OauthIDP
    OauthIDP -->|OauthToken| Grafana
    Grafana -->|OauthToken| Multena
    Multena -->|Jwks| OauthIDP
    Multena --> Thanos
    Multena --> Loki

Jwks is the JSON Web Key Set, which is used to validate the JWT token. It's like a public key for the JWT token.

Deploy Multena

The helm chart for Multena is available at gp-helm-charts

To install run the following commands:

helm repo add gepardec https://gepaplexx.github.io/gp-helm-charts/
helm install multena gepardec/gp-multena -n <grafana-namespace>

To upgrade, run the following commands:

helm repo update
helm upgrade multena gepardec/gp-multena -n <grafana-namespace>

NOTE: If your using the grafana operator, the helm chart provides an option to install grafana-operator-datasources which simplifies the deployment of Multena. If you deploy Multena without the grafana-operator-datasources you have to configure the datasource manually.

Configuring Multena

Labelstore Providers

NOTE: Currently Multena offers two different providers for label lookup, namely ConfigMap and MySQL.

ConfigMap Provider

With the ConfigMap provider, Multena can retrieve labels by reading a separate ConfigMap that defines a list of allowed labels for each user or group. This approach allows for easy configuration and management of label permissions by specifying the allowed labels directly in the ConfigMap. An example can be found here labels.yaml

You can define the allowed labels for groups and users manually, but if you deploy multena in a single cluster, we recommend to use the multena-rbac-collector to continuesly collect the permissions for each user and group. This tool will create a labels.yaml file which can be directly used by Multena. To enable it set, the following setting

rbac-collector:
  enabled: true 

in the helm chart.

MySQL Provider

The MySQL provider enables label lookup through executing a custom query against a MySQL database. This capability allows Multena to dynamically fetch the allowed tenant lalbel (e.g., namespace) for a specified email or user or groups. By setting the appropriate query in the configuration, Multena can seamlessly retrieve the relevant label information from the MySQL database.

This makes only sense if you already have a MySQL database with a systematic way to get the permissions for a user.

NOTE: As every query sends a query to the database, we recommend enabling caching for the database.

config.yaml

proxy section

web:
  proxy_port: 8080 # port on which the proxy will listen
  metrics_port: 8081 # port on which the metrics will be exposed
  host: localhost # host on which the proxy will listen
  tls_verify_skip: true # skip tls verification for the upstream server, very insecure!!!
  trusted_root_ca_path: "./certs/" # path to the trusted root ca
  label_store_kind: "configmap" # kind of label store, currently only configmap and mysql are supported
  jwks_cert_url: https://sso.example.com/realms/internal/protocol/openid-connect/certs # url to the jwks certificate
  oauth_group_name: "groups" # name of the group field in the jwt token

datasource section (thanos|loki)

thanos|loki: # choose either thanos or loki
url: https://localhost:9091 # url to the thanos or loki endpoint     | Required
tenant_label: namespace # label which is used to enforce the query   | Required
cert: "./certs/thanos/tls.crt" # path to the mtls certificate        | Optional
key: "./certs/thanos/tls.key" # path to the mtls key                 | Optional
Header: # headers which will be added to the request                 | Optional
  X-Scope-OrgID: "application"

logging section

log:
  level: 1 # log level, 0 = debug, 1 = info, 2 = warn, 3 = error, -1 = trace exposes sensitive data!!!
  log_tokens: false # logs jwt, expose sensitive data!!!

admin section

admin:
  bypass: true # enable bypassing the enforcing steps
  group: gepardec-run-admins # group which is allowed to bypass the enforcing steps

db section

db:
  enabled: false # enable connection to a database
  user: multitenant # username for the database
  password_path: "." # path to the password for the database (kubernetes secret)
  host: localhost # host of the database
  port: 3306 # port of the database
  dbName: example # name of the database
  query: "SELECT * FROM users WHERE username = ?" # query to retrieve data from the database, must return a list of labels
  token_key: "email|username|groups" # field in the jwt which will be used to query the database 

labels.yaml

The labels.yaml file is used to define the allowed labels for groups and users in Multena. It follows a specific YAML format as shown below:

group1:
  '#cluster-wide': true # this grants the group to skip enforcement
user1:
  hogarama: true # single namespace
user3:
  grafana: true # multi namespace
  opernshift-logging: true
  opernshift-monitoring: true

The format consists of a key for username|groupname, followed by another key value pair where the key is the label and value is true. This has been done to look up the labels faster.

How to Configure Multena Proxy

Step 1: Install/Upgrade Multena Using Helm

Multena can be deployed using its Helm chart. Execute the following commands to install or upgrade Multena:

To install:

helm repo add gepardec https://gepaplexx.github.io/gp-helm-charts/
helm install multena gepardec/gp-multena -n <grafana-namespace>

To upgrade:

helm repo update
helm upgrade multena gepardec/gp-multena -n <grafana-namespace>

Note: When using the Grafana operator, the Helm chart provides an option to install grafana-operator-datasources to simplify the deployment of Multena. If you deploy it without the grafana-operator-datasources, you'll have to configure the datasource manually.

Step 2: Choose a Labelstore Provider

Multena offers two types of providers for label lookup - ConfigMap and MySQL.

a. ConfigMap Provider

  • Utilizes a separate ConfigMap to define allowed labels for each user/group.
  • Labels can be defined manually, or use multena-rbac-collector for automatic collection of permissions.

To enable the use of multena-rbac-collector in the Helm chart:

rbac-collector:
  enabled: true 

b. MySQL Provider

  • Performs a custom query against a MySQL database to retrieve allowed tenant labels dynamically for a specified user/group.
  • Suitable if you have a systematic way to retrieve permissions for a user via a MySQL database.

Note: Enable caching for the database since every query sends a request to it.

Step 3: Configure config.yaml

Multena's config.yaml contains crucial configuration sections such as proxy, datasource, logging, admin, and db.

a. Proxy Section

Define configurations like proxy port, host, TLS verification, and OAuth group name here.

b. Datasource Section (Thanos/Loki)

Specify either thanos or loki and define configurations like URL, tenant label, certificate paths, and headers.

c. Logging Section

Manage log level and token logging here.

d. Admin Section

Configure if and which group can bypass enforcing steps.

e. DB Section

Enable and configure database connections, define query parameters, and specify which JWT field will be used to query the database.

multena-proxy's People

Contributors

apatecwagnerc avatar lucostus avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

multena-proxy's Issues

Availability of Tempo Trace Proxying

Hi team,

We are currently looking at using Multena as a proxy for our logs and traces. As far as I understand Trace proxying is currently not supported. Do you have a timeline of when this will be possible?

Cheers,
Stephan

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

dockerfile
build/Containerfile
build/Containerfile.Build
github-actions
.github/workflows/release.yml
  • actions/setup-go v5
  • actions/checkout v4
  • golangci/golangci-lint-action v4
  • actions/checkout v4
  • github/codeql-action v3
  • actions/checkout v4
  • actions/setup-go v5
  • actions/checkout v4
  • actions/cache v4
  • actions/setup-go v5
  • actions/checkout v4
  • actions/cache v4
  • anothrNick/github-tag-action 1.67.0
  • docker/metadata-action v5
  • redhat-actions/buildah-build v2
  • redhat-actions/podman-login v1
  • github/codeql-action v3
  • redhat-actions/push-to-registry v2
  • anothrNick/github-tag-action 1.67.0
gomod
go.mod
  • go 1.22.1
  • github.com/MicahParks/keyfunc/v3 v3.2.9
  • github.com/fsnotify/fsnotify v1.7.0
  • github.com/go-sql-driver/mysql v1.8.0
  • github.com/golang-jwt/jwt/v5 v5.2.1
  • github.com/gorilla/mux v1.8.1
  • github.com/observatorium/api v0.1.3-0.20240311102334-63c873db5762@63c873db5762
  • github.com/prometheus-community/prom-label-proxy v0.8.1
  • github.com/prometheus/client_golang v1.19.0
  • github.com/prometheus/prometheus v0.50.1
  • github.com/rs/zerolog v1.32.0
  • github.com/slok/go-http-metrics v0.11.0
  • github.com/spf13/viper v1.18.2
  • github.com/stretchr/testify v1.9.0
  • golang.org/x/exp v0.0.0-20240119083558-1b970713d09a@1b970713d09a
  • github.com/prometheus/prometheus v0.50.1

  • Check this box to trigger a request for Renovate to run again on this repository

Allow defining arbitrary labels for users and groups

I think it would come really handy if we could define arbitrary labels an entity would be allowed to read. Is this something you have thought about and do you see any issues with this approach

user1:
  namespace: foo
  team: foo
  app: foo-bar

user2:
  namespace: bar
  service: bar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.