1. Answers
  2. Injecting External Authorization into Service Traffic with EnvoyFilter

How Do I Inject External Authorization Into Service Traffic With EnvoyFilter?

In this guide, we will demonstrate how to use an EnvoyFilter in Kubernetes to inject external authorization into service traffic. This involves creating an EnvoyFilter resource that configures Envoy proxies to call an external authorization service before allowing traffic to proceed to the intended service.

Introduction

Injecting external authorization into service traffic is crucial for securing applications running in Kubernetes environments. By using an EnvoyFilter, you can ensure that all incoming requests are vetted by an external service before they reach your application. This process enhances security by centralizing authorization logic and making it easier to manage and update.

Detailed Explanation

  1. Setup Kubernetes and Istio: Ensure you have a Kubernetes cluster with Istio installed. This setup is essential as Istio provides the necessary framework to manage traffic and apply policies using Envoy proxies.

  2. Define the External Authorization Service: Develop and deploy a service that handles authorization requests from Envoy. This service will evaluate the requests and determine whether they should be allowed or denied.

  3. Create the EnvoyFilter: Configure the EnvoyFilter to direct traffic to the external authorization service. The EnvoyFilter specifies how traffic should be intercepted and forwarded to the authorization service for evaluation.

Key Points

  • EnvoyFilter: A custom resource in Istio that allows you to customize the behavior of Envoy proxies.
  • External Authorization Service: A service that processes authorization requests and returns a decision to Envoy.

Code Implementation

import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";

const namespace = new k8s.core.v1.Namespace("auth-namespace", {
    metadata: {
        name: "auth-namespace",
    },
});

const externalAuthService = new k8s.core.v1.Service("external-auth-service", {
    metadata: {
        namespace: namespace.metadata.name,
        name: "external-auth-service",
    },
    spec: {
        selector: {
            app: "external-auth",
        },
        ports: [{
            protocol: "TCP",
            port: 8000,
            targetPort: 8000,
        }],
    },
});

const externalAuthDeployment = new k8s.apps.v1.Deployment("external-auth-deployment", {
    metadata: {
        namespace: namespace.metadata.name,
        name: "external-auth-deployment",
    },
    spec: {
        selector: {
            matchLabels: {
                app: "external-auth",
            },
        },
        replicas: 1,
        template: {
            metadata: {
                labels: {
                    app: "external-auth",
                },
            },
            spec: {
                containers: [{
                    name: "external-auth",
                    image: "your-external-auth-service-image",
                    ports: [{
                        containerPort: 8000,
                    }],
                }],
            },
        },
    },
});

const envoyFilter = new k8s.apiextensions.CustomResource("envoy-filter", {
    apiVersion: "networking.istio.io/v1alpha3",
    kind: "EnvoyFilter",
    metadata: {
        namespace: namespace.metadata.name,
        name: "authz-filter",
    },
    spec: {
        workloadSelector: {
            labels: {
                app: "your-app",
            },
        },
        configPatches: [{
            applyTo: "HTTP_FILTER",
            match: {
                context: "SIDECAR_INBOUND",
                listener: {
                    filterChain: {
                        filter: {
                            name: "envoy.http_connection_manager",
                            subFilter: {
                                name: "envoy.router",
                            },
                        },
                    },
                },
            },
            patch: {
                operation: "INSERT_BEFORE",
                value: {
                    name: "envoy.ext_authz",
                    config: {
                        grpc_service: {
                            google_grpc: {
                                target_uri: "external-auth-service.auth-namespace.svc.cluster.local:8000",
                                stat_prefix: "ext_authz",
                            },
                            timeout: "5s",
                        },
                    },
                },
            },
        }],
    },
});

Summary

In this guide, we created a Kubernetes namespace, deployed an external authorization service, and configured an EnvoyFilter to inject external authorization into the service traffic. The EnvoyFilter directs traffic to the external authorization service, which processes the authorization requests and returns a decision to Envoy.

By following these steps, you can enhance the security of your services by integrating an external authorization mechanism using EnvoyFilter in Kubernetes. This approach centralizes authorization logic, making it easier to manage and update security policies across your services.

Deploy this code

Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.

Sign up

New to Pulumi?

Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.

Sign up