Skip to content

xenit-eu/thunx

Repository files navigation

Thunx

build maven central Apache License 2

Thunx is a pluggable Attribute Based Access Control system, with and end-to-end implementation using:

This project uses a distributed authorization architecture, by applying:

  • early access decisions at the API Gateway
  • postponed access decisions in the Spring Data REST service

When the API Gateway does not have sufficient contextual information to grant or deny access, it delegates the policy decision to the Spring Data REST service. This API Service receives an authorization-predicate, a thunk from the API Gateway and rewrites the database queries to ensure the authorization-predicate is satisfied.

Advantages

This approach provides the following advantages:

  • Decoupling: The API service does not need to be concerned with authorization logic.
  • Performance: Using query-rewriting instead of post-filtering can be orders of magnitude faster.
  • Performance: By delegating decisions to the appropriate data-context, access policies can be much more fine-grained, without paying a big runtime penalty for loading data in the policy engine on demand.

Architecture overview

This section describes the Thunx architecture.

Please note all the diagrams use the C4 model style. A legend, included in every diagram, explains the meaning of each shape.

A Client-side webapp uses a REST API provided by the API Service. An API Gateway sits in between, which takes care of authentication and authorization concerns.

The Client-side webapp gets an access token with an OIDC Identity Provider and makes some REST API requests with the access token. The API Gateway first validates the access token (authentication step). The user-profile is (optionally) loaded from the OIDC User Endpoint. The Gateway asks the Policy Decision Point (PDP) to authorize the request.

In a simple ABAC system, the authorization requests has a binary response: the policy engine returns an access granted or access denied decision. The API Gateway adheres to this decision and either allows or denies the request, acting as a classic Policy Enforcement Point (PEP).

Our system also allows for a conditional and partial grant. When the policy engine determines it does not have sufficient information to make a decision, it returns a residual policy, a predicate. Access to the API resource is conditionally granted, if and only if, the predicated can be fulfilled when the missing information is available.

The residual policy, in this case an OpenPolicyAgent QuerySet, is translated into a technology-neutral boolean expression, called a thunk-expression. The thunk-expression is stored as a thunk-context in the API Gateway request context. The API Gateway forwards requests to the API Service and propagates the thunk-context by serializing and encoding the thunk-context as HTTP request headers.

The API Service receives the REST API request. A filter reconstructs the thunk-context from the HTTP request headers. The thunk-expression from the thunk-context can be converted into a QueryDSL predicate. When the API service uses a JPA Repository, the Spring Data QueryDSL Extension can be used to include the QueryDSL predicate, and with that fulfill the conditional authorization predicate.

overview

Solution mechanics

Gateway

Spring Data REST

Subprojects

This repository has several modules:

  • thunx-model is a set of (vendor-neutral) data structures to model authorization policy expressions
  • thunx-pdp is a central abstraction for a Policy Decision Point (PDP)
  • thunx-pdp-opa is a PDP implementation using OpenPolicyAgent.
  • thunx-encoding-json is a JSON-serialization library for thunk-expressions
  • thunx-predicates-querydsl is a library to convert thunk-expressions into QueryDSL predicates
  • thunx-spring-api provides an integration with Spring Data REST
  • thunx-spring-gateway provides an integration with Spring Cloud Gateway
  • thunx-spring-querydsl-predicate-resolver is a library to inject additional QueryDSL predicates to be processed together with the predicates from the Spring Data QueryDSL Extension

Getting Started

Installation

Requirements:

  • Java 17+

Spring Cloud Gateway

Using Gradle:

implementation "com.contentgrid.thunx:thunx-gateway-spring-boot-starter:${thunxVersion}"

Spring Data REST Service

Using Gradle:

implementation "com.contentgrid.thunx:thunx-gateway-spring-boot-starter:${thunxVersion}"

implementation "com.querydsl:querydsl-jpa" // Or another QueryDSL implementation, dependent on the spring data flavor you're using

License

Apache License Version 2.0