Envoy Gateway Integration

This guide explains how to integrate heimdall with Envoy Gateway.

Envoy Gateway is an open source project for managing Envoy Proxy as a Kubernetes-based application gateway by making use of the Gateway API resources.

Prerequisites

  • A kubernetes cluster

  • Deployed Envoy Gateway (See here for installation options)

  • Deployed GatewayClass resource that matches Envoy Gateway’s configured controllerName (typically gateway.envoyproxy.io/gatewayclass-controller), as well as a deployed Gateway resource.

  • heimdall installed and operated in Decision Operation Mode.

Integration Options

Technically, the integration happens the same way as with Envoy itself by making use of the External Authorization filter, and can be done in two ways:

  • either via HTTP

  • or via gRPC (recommended)

In both cases, the filter calls an external gRPC or HTTP service (here heimdall) to check whether an incoming HTTP request is authorized or not. If heimdall responses with 2xx the request is forwarded to the upstream service, otherwise the response from heimdall is returned to the caller.

In case of Envoy Gateway the abovesaid configuration happens via a SecurityPolicy custom resource, that can be linked to a Gateway, HTTPRoute, or a GRPCRoute resource.

As of today, there is a limitation in the implementation of the Envoy Gateway - it does not allow cross-namespace reference of external auth services (see also envoyproxy/gateway#3322). That means, the HTTPRoute, the Gateway resource and heimdall must be deployed in the same namespace.

Global Configuration

To integrate heimdall with the gateway globally, that is, each and every request will be forwarded to heimdall for authentication and authorization purposes first, create a SecurityPolicy as shown below in the namespace, the Gateway resource is deployed into.

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: ext-auth-heimdall (1)
  namespace: heimdall (2)
spec:
  targetRef: (3)
    group: gateway.networking.k8s.io
    kind: Gateway
    name: eg
    namespace: heimdall
  extAuth:
    grpc:
      backendRef: (4)
        name: heimdall
        port: 4456
        namespace: heimdall
1The name of the SecurityPolicy. You can change it to any other value if you like.
2The namespace for the policy. It must be the same namespace the Gateway resource and heimdall are deployed into. So change it to your namespace.
3Defines the Gateway resource, this policy should be applied to. Change the name property to the name of your Gateway resource and the namespace property to the proper namespace (same as in 2)
4Defines the reference to the heimdall Service using the gRPC protocol. Change the name and the namespace to the proper values of your setup.

Route-level Configuration

The integration on the route level happens similar to the global integration. The difference is that the SecurityPolicy is applied to an HTTPRoute as shown below and not the Gateway resource.

apiVersion: gateway.envoyproxy.io/v1alpha1
kind: SecurityPolicy
metadata:
  name: ext-auth-example (1)
  namespace: heimdall (2)
spec:
  targetRef: (3)
    group: gateway.networking.k8s.io
    kind: HTTPRoute
    name: heimdall
  extAuth:
    grpc:
      backendRef: (4)
        name: heimdall
        port: 4456
        namespace: heimdall
1The name of the SecurityPolicy. You can change it to any other value if you like.
2The namespace for the policy. It must be the same namespace the HTTPRoute resource is deployed into, so the namespace, your application is deployed to. So change it to your namespace.
3Defines the HTTPRoute resource, this policy should be applied to. Change the name property to the name of your HTTPRoute resource and the namespace property to the proper namespace (same as in 2)
4Defines the reference to the heimdall Service using the gRPC protocol. Change the name and the namespace to the proper values of your setup.

Security Considerations

The configuration options shown above are highly insecure, as the communication from the gateway to heimdall happens over plain HTTP. Therefore, it is highly recommended to enable TLS. This can be achieved by enabling TLS for heimdall and attaching a BackendTLSPolicy resource shown below to heimdall’s Service.

apiVersion: gateway.networking.k8s.io/v1alpha2
kind: BackendTLSPolicy
metadata:
  name: heimdall-btls
  namespace: heimdall (1)
spec:
  targetRef: (2)
    group: ''
    kind: Service
    namespace: heimdall
    name: heimdall
    sectionName: "4456"
  tls: (3)
    caCertRefs:
      - name: demo-ca (4)
        group: ''
        kind: ConfigMap
    hostname: heimdall (5)
1Change it to the namespace in which heimdall is deployed
2The reference to heimdall’s Service. Change the name and the namespace to the proper values.
3Here we configure the reference to the ConfigMap with the certificate of the CA, used to issue a TLS server authentication certificate for heimdall, as well as the hostname used by heimdall (and present in the SAN extension of heimdall’s TLS certificate). The ConfigMap must be in the same namespace as the BackendTLSPolicy.
4The name of the ConfigMap. Change it to the proper value.
5The expected hostname used by heimdall. Change it to the proper value.

Additional Resources

  • A fully working example with Envoy Gateway is also available on GitHub.

  • You can find the official external authentication guide for Envoy Gateway here. It contains a fully working setup with a demo application.

  • Secure Gateways is a highly recommended read as well.

Last updated on May 6, 2024