Before you begin

  1. Follow the Get started guide to install Gloo Gateway, set up a gateway resource, and deploy the httpbin sample app.

  2. Get the external address of the gateway and save it in an environment variable.

Create the gRPC auth server

  1. Deploy a sample gRPC auth server that is configured to authorize requests that include the authorization: authorize me request header. This example is based on the Envoy service specification. You can review the source code for the gRPC auth server in the Gloo Gateway GitHub repository.

      kubectl apply -f - <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: extauth-grpcservice
      namespace: httpbin
    spec:
      selector:
        matchLabels:
          app: grpc-extauth
      replicas: 1
      template:
        metadata:
          labels:
            app: grpc-extauth
        spec:
          containers:
            - name: grpc-extauth
              image: quay.io/solo-io/passthrough-grpc-service-example
              imagePullPolicy: IfNotPresent
              ports:
                - containerPort: 9001
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: example-grpc-auth-service
      namespace: httpbin
      labels:
          app: grpc-extauth
    spec:
      ports:
      - port: 9001
        protocol: TCP
      selector:
        app: grpc-extauth
    EOF
      
  2. Verify that the gRPC auth server is up and running.

      kubectl get pods -n httpbin
      

Set up external auth

  1. Create an AuthConfig resource and add your external authentication rules. The following example passes authentication requests through to the gRPC auth server that you deployed earlier.

      kubectl apply -f - <<EOF
    apiVersion: enterprise.gloo.solo.io/v1
    kind: AuthConfig
    metadata:
      name: passthrough-auth
      namespace: httpbin
    spec:
      configs:
      - passThroughAuth:
          grpc:
            # Address of the grpc auth server to query
            address: example-grpc-auth-service.httpbin.svc.cluster.local:9001
            # Set a connection timeout to external service, default is 5 seconds
            connectionTimeout: 3s
    EOF
      
  2. Create a RouteOption resource and reference the AuthConfig resource that you just created.

      kubectl apply -f- <<EOF
    apiVersion: gateway.solo.io/v1
    kind: RouteOption
    metadata:
      name: passthrough-auth
      namespace: httpbin
    spec:
      options:
        extauth:
          configRef:
            name: passthrough-auth
            namespace: httpbin
    EOF
      
  3. Create an HTTPRoute resource for the httpbin app that requires authentication for requests on the extauth.example domain.

      kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1beta1
    kind: HTTPRoute
    metadata:
      name: httpbin-passthrough-auth
      namespace: httpbin
    spec:
      parentRefs:
      - name: http
        namespace: gloo-system
      hostnames:
        - extauth.example
      rules:
        - filters:
            - type: ExtensionRef
              extensionRef:
                group: gateway.solo.io
                kind: RouteOption
                name: passthrough-auth
          backendRefs:
            - name: httpbin
              port: 8000
    EOF
      
  4. Send a request to the httpbin app on the extauth.example domain. Verify that your request is denied and that you get back a 403 HTTP response code.

    Example output:

      * Mark bundle as not supporting multiuse
    < HTTP/1.1 403 Forbidden
    < date: Wed, 05 Jun 2024 14:12:36 GMT
    < server: envoy
    < content-length: 0
      
  5. Send another request to the httpbin app. This time, you include the authorization: authorize me request header. Verify that the request succeeds and that you get back a 200 HTTP response code.

    Example output:

      * Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < access-control-allow-credentials: true
    < access-control-allow-origin: *
    < date: Wed, 05 Jun 2024 14:18:28 GMT
    < content-length: 0
    < x-envoy-upstream-service-time: 1
    < server: envoy
      

Configure retries for unresponsive passthrough servers

You can configure the Gloo external auth server to retry the connection to the passthrough service in the case that the passthrough service becomes unavailable. Consider the following two scenarios to learn more about how retries to the passthrough service are executed:

Passthrough service becomes unavailable after initial connection

In this scenario, the external auth server successfully established an initial connection to the passthrough service. However later on, the passthrough service becomes unavailable. You can add a retry policy to your AuthConfig resource to retry the connection to the passthrough service if the service becomes unavailable. In the following AuthConfig, the external auth server in Gloo Gateway is configured to retry the connection to the passthrough service 10 times.

To not overload the passthrough service, an optional exponential backoff strategy is defined. The backoff strategy configures the external auth server to start retries after 1 second (baseInterval). Retries are then executed exponentially, such as after 2 seconds, 4 seconds, 8 seconds, etc up to the maxInterval that defaults to 10 times the baseInterval. In this example, the maxInterval configures a maximum delay of 2 seconds between retries.

apiVersion: enterprise.gloo.solo.io/v1
kind: AuthConfig
metadata:
  name: passthrough-auth
  namespace: gloo-system
spec:
  configs:
  - passThroughAuth:
      grpc:
        # Address of the grpc auth server to query
        address: example-grpc-auth-service.default.svc.cluster.local:9001
        # Set a connection timeout to external service, default is 5 seconds
        connectionTimeout: 3s
        retryPolicy: 
          numRetries: 10
          retryBackOff:
            baseInterval: 1s
            maxInterval: 2s

Passthrough service is unavailable during the initial connection

When you configure your AuthConfig with a retry policy, auth requests are retried only after the initial connection between the Gloo Gateway auth server and passthrough service is established successfully. If establishing the initial connection fails, the external auth server retries the connection up to the defined connectionTimeout in the AuthConfig. The settings in the retry policy are ignored and any auth requests that are sent to the external auth server during that time fail immediately. Auth requests continue to fail when the connectionTimeout is reached, even if the passthrough service becomes available afterwards. To mitigate this issue, you can try increasing the connectionTimeout setting if you think that your passthrough service can recover and become available within the specified connection timeout.

Cleanup

You can optionally remove the resources that you set up as part of this guide.
  kubectl delete authconfig passthrough-auth -n httpbin
kubectl delete routeoption passthrough-auth -n httpbin
kubectl delete httproute httpbin-passthrough-auth -n httpbin
kubectl delete deployment extauth-grpcservice -n httpbin
kubectl delete service example-grpc-auth-service -n httpbin