heimdall icon indicating copy to clipboard operation
heimdall copied to clipboard

Add gRPC support

Open dadrus opened this issue 5 months ago • 0 comments

Preflight checklist

  • [x] I agree to follow this project's Code of Conduct.
  • [x] I have read and am following this repository's Contribution Guidelines."
  • [x] I have discussed this feature request with the community.

Describe the background of your feature request

Heimdall currently focuses on securing HTTP-based traffic. However, many modern microservice architectures also use gRPC for (inter-service) communication due to its efficiency, streaming capabilities, and strong typing.

Describe your idea

Extend Heimdall to support gRPC traffic alongside existing HTTP-based capabilities.

Are there any workarounds or alternatives?

Not yet tested, but there might be some workarounds, which you can see described in the "Additional Context" section below.

Version

0.17.0

Additional Context

Below is a status quo related to grpc support.

In principle an unary grpc request looks as following (These examples are taken from grpc docs).

HEADERS (flags = END_HEADERS)
:method = POST
:scheme = http
:path = /google.pubsub.v2.PublisherService/CreateTopic
:authority = pubsub.googleapis.com
grpc-timeout = 1S
content-type = application/grpc+proto
grpc-encoding = gzip
authorization = Bearer y235.wef315yfh138vh31hv93hv8h3v

DATA (flags = END_STREAM)
<Length-Prefixed Message>

and a response like this

HEADERS (flags = END_HEADERS)
:status = 200
grpc-encoding = gzip
content-type = application/grpc+proto

DATA
<Length-Prefixed Message>

HEADERS (flags = END_STREAM, END_HEADERS)
grpc-status = 0 # OK
trace-proto-bin = jher831yy13JHy3hc

In go, http1 and http2 requests and responses are represented by the same http.Request and http.Response types internally used by heimdall. That means, heimdall can already support grpc calls on a rule level. E.g. the above request could be matched and handled by the following rule:

- id: my grpc rule
  match:
    routes:
      - path: /google.pubsub.v2.PublisherService/CreateTopic
    methods: ["POST"]
    hosts:
      - type: exact
        value: pubsub.googleapis.com
  execute:
    # whatever
  on_error:
    # whatever

The main limitations surface when creating the response, as grpc is using http2 as tunneling protocol:

  • grpc requires that the :status pseudo header is always set to 200, and
  • the grpc-status trailer header is used to signal the actual response status instead.

This is not yet natively supported by heimdall as the :status pseudo header will be set based on the result of the authentication & authorization pipeline result (definitions in the execute property), respectively the result of the error handling pipeline (definitions in the on_error property).

There is also a limitation related to the ability of heimdall to map raised errors to HTTP response codes globally. This mapping should apply to grpc-status instead of the HTTP status code.

Since grpc is a binary protocol, respectively the transferred data is a protobuf message, heimdall is unable to decode it, if a step in a pipeline makes use of .Request.Body function. Though, this might be an acceptable limitation.

The corresponding options and how to proceed are discussed in the gRPC Support channel in heimdall's Discord.

dadrus avatar Sep 15 '25 08:09 dadrus