Concepts

Everything you need to know.

Pipeline

As described in the Welcome section and also shown in the diagram below, Heimdall authenticates and authorizes incoming HTTP requests, rejecting unauthenticated or unauthorized ones, as well as enriches the valid requests with further information and transforms resulting subject information to a format, required by the upstream services. This is done in upstream service specific rules, which define the required individual pipelines.

Diagram
Figure 1. Request Pipeline

Each rule defines which pipeline steps are required and executed in which order.

In general each rule contains

  • an identifier - to uniquely identify a rule

  • an url pattern - to match the incoming request against

  • a list of allowed HTTP methods for the matched requests

  • a regular pipeline, consisting of a list with

    • authentication mechanisms, so-called Authenticators, to be executed (if multiple are defined, they are executed as fallbacks) - step 1 in the figure above.

      Here, heimdall would typically communicate with the actual authentication systems to get information about the authenticated subject, or to get key material to verify the authentication information provided in the request, or perform other activities related to authentication.

    • contextualization mechanisms, so-called Hydrators, to be executed (if multiple are defined, they are executed in the order of their definition; can be mixed with authorization mechanisms) - step 2 in the figure above.

      Here, heimdall would communicate with other systems as well, either to get further information about the subject, like specific attributes required by the upstream service and not available in the authentication information, information about the request IP, like provided by AbuseIPDB, etc.

    • authorization mechanisms, so-called Authorizers, to be executed (if multiple are defined, they are executed in the order of their definition; can be mixed with contextualization mechanisms) - step 3 in the figure above.

      Here, heimdall would perform authorization checks, either locally in the pipeline, or by communicating with yet again further system, like Open Policy Agent, Ory Keto and alike.

    • unification mechanisms, so-called Mutators, to be executed (if multiple are defined, they are executed in the order of their definition) - step 4 in the figure above.

      This step transform the subject information collected so far into an object expected by the upstream service. That reaches from a simple custom header, carrying e.g. the id of the subject, to a JWT carried in the Authorization header.

  • an error pipeline, consisting of an error handler list (if multiple are defined, they are executed as fallbacks), which are executed if any of the regular pipeline mechanisms fails. These range from a simple error response to the client, which sent the request, to sophisticated handlers supporting complex logic and redirects.

The diagram below sketches the related execution logic

Diagram
  1. Url matches rule? - This is the first step executed by heimdall. The information about the scheme, host and path is taken either from the URL itself, or if present from the X-Forwarded-Proto, X-Forwarded-Host, X-Forwarded-Path, or X-Forwarded-Uri headers of the incoming request. The request is denied if there is no matching rule. Otherwise, the rule specific pipeline is executed.

  2. Method allowed? - As soon as a rule matches a request, a verification is done whether the used HTTP method is allowed or not. The information about the HTTP method is either taken from the request itself or, if present from the X-Forwarded-Method.

  3. Execute regular pipeline - when the above steps succeed, the regular pipeline mechanisms defined in the matched rule are executed.

  4. Forward request, respectively respond to the API gateway - when the above steps succeed, heimdall, depending on the operating mode, responds with, respectively forwards whatever was defined in the pipeline (usually this is a set of HTTP headers). Otherwise

  5. Execute error pipeline is executed if any of the mechanisms, defined in the regular pipeline fail. This again results in a response, this time however, based on the definition in the used error handler.

Operating Modes

To support different deployment scenarios, Heimdall supports two operating modes:

Proxy Mode

Diagram
Figure 2. Proxy Deployment

In this mode heimdall forwards requests to the upstream service, if these satisfy the conditions defined in pipeline definition rules. Otherwise, heimdall returns an error to the client. If the pipeline execution was successful, it also forwards additional headers, specified in the used pipeline to the upstream service.

Starting heimdall in this mode happens via the serve proxy command. Head over to the description of CLI as well as Configuration options for more details.

Example 1. Reverse Proxy Example

Imagine following request hits Heimdall

GET /my-service/api HTTP/1.1
Host: heimdall:4455

Some payload

And there is a rule, which defines a pipeline, allowing anonymous requests and setting a header with subject id set to anonymous like this

id: rule:my-service:anonymous-api-access
url: /my-service/api
upstream: https://my-backend-service:8888
methods:
  - GET
execute:
  - authenticator: anonymous-authn
  - mutator: id-header

Then the request will be forwarded as follows:

GET /my-service/api HTTP/1.1
Host: my-backend-service:8888
X-User-ID: anonymous

Some payload

Decision API Mode

Diagram
Figure 3. Decision API Deployment

In this mode, you can integrate heimdall with most probably all modern API gateways and reverse proxies as a so-called "authentication middleware". Here the reverse proxy, respectively API gateway integrating with heimdall, will forward requests to heimdall by making use of its decisions service endpoint for authentication and authorization purposes. As in the Reverse Proxy mode, heimdall will check if these satisfy the conditions defined in pipeline definition rules. Otherwise, heimdall returns an error to its client (here API gateway/reverse proxy). If the pipeline execution was successful, it also responds to the API gateway/reverse proxy with additional headers, specified in the used pipeline, which can then be forwarded by it to the upstream service.

Starting heimdall in this mode happens via the serve decision command. Head over to the description of CLI as well as to Configuration options for more details.

Example 2. Decision API Example

Imagine following request hits Heimdall (sent to it by an API gateway)

GET /my-service/api HTTP/1.1
Host: heimdall:4455
X-Forwarded-Host: my-backend-service

Some payload

And there is a rule, which defines a pipeline, allowing anonymous requests and setting a header with subject id set to anonymous like this

id: rule:my-service:anonymous-api-access
url: http:my-backend-service/my-service/api
methods:
  - GET
execute:
  - authenticator: anonymous-authn
  - mutator: id-header

Then heimdall will respond with:

HTTP/1.1 202 Accepted
X-User-ID: anonymous

Last updated on Aug 29, 2022