The external gRPC service implements Envoy’s Authorization Service API to authenticate requests.

About passthrough

You might wonder, why should I use passthrough instead of a custom external auth server?

Benefits of passthrough: With gRPC passthrough, you can set up your own custom logic in the external gRPC service. You can still use the other Gloo Mesh Gateway external auth implementations, such as OIDC and API key auth. A custom auth server is not integrated with the Gloo Mesh Gateway external auth server, so you cannot use both at the same time.

Drawbacks of passthrough: To provide additional flexibility in auth configuration, passthrough sets up a separate gRPC service that the Gloo Mesh Gateway external auth server forwards requests to for authentication. This step requires an additional network hop, so you might notice an impact to latency.

Before you begin

  1. Set up Gloo Mesh Gateway in a single cluster.
  2. Install Bookinfo and other sample apps.
  3. Configure an HTTP listener on your gateway and set up basic routing for the sample apps.

  4. Make sure that the external auth service is installed and running. If not, install the external auth service in your Gloo environment.

      kubectl get pods  -A -l app=ext-auth-service
      
  5. If you did not already do so, create an ExtAuthServer resource for your workspace. This resource points to the destination server to use for external auth policies. The destination server can be the default ext-auth-service from Gloo Mesh Gateway, or your own custom server. Note: Change the cluster-1 value as needed.

      kubectl apply -f - <<EOF
    apiVersion: admin.gloo.solo.io/v2
    kind: ExtAuthServer
    metadata:
      annotations:
        cluster.solo.io/cluster: ""
      name: default-server
      namespace: bookinfo
    spec:
      destinationServer:
        port:
          number: 8083
        ref:
          cluster: cluster-1
          name: ext-auth-service
          namespace: gloo-mesh-addons
    EOF
      
  6. Get the external address of your ingress gateway. The steps vary depending on the type of load balancer that backs the ingress gateway.

    • LoadBalancer IP address:
        export INGRESS_GW_IP=$(kubectl get svc -n gloo-mesh-gateways istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
      echo $INGRESS_GW_IP
        
    • LoadBalancer hostname:
        export INGRESS_GW_IP=$(kubectl get svc -n gloo-mesh-gateways istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')
      echo $INGRESS_GW_IP
        

    Note: Depending on your environment, you might see <pending> instead of an external IP address. For example, if you are testing locally in kind or minikube, or if you have insufficent permissions in your cloud platform, you can instead port-forward the service port of the ingress gateway:

      kubectl -n gloo-mesh-gateways port-forward deploy/istio-ingressgateway-1-18 8081
      

Configure a passthrough gRPC service

Gloo Mesh Gateway supports adding an external gRPC service that implements Envoy’s Authorization Service API. The following steps use a sample image for the gRPC passthrough service, but you can use your own.

  1. Deploy a sample gRPC service that runs on port 9001. For more information, review the service spec in the Envoy docs.
      kubectl apply -f- <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: extauth-grpcservice
      namespace: bookinfo # <-- this namespace assumes auto injection is enabled
    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
    EOF
      
  2. Create a service to assign the deployment a static cluster IP address.
      kubectl apply -f- <<EOF
    apiVersion: v1
    kind: Service
    metadata:
      name: extauth-grpcservice
      namespace: bookinfo
      labels:
          app: grpc-extauth
    spec:
      ports:
      - port: 9001
        protocol: TCP
      selector:
          app: grpc-extauth
    EOF
      
  3. Confirm that the deployment is ready and the cluster IP address is assigned.
      kubectl get all -l app=grpc-extauth -n bookinfo
      

Secure routes with an external auth policy

Create an external auth policy for the ratings route so that requests are authenticated by the gRPC service that you previously deployed.

  kubectl apply -f- <<EOF
apiVersion: security.policy.gloo.solo.io/v2
kind: ExtAuthPolicy
metadata:
  name: passthrough-auth
  namespace: bookinfo
spec:
  applyToRoutes:
  - route:
      labels:
        route: ratings
  config:
    glooAuth:
      configs:
      - passThroughAuth:
          grpc:
            address: extauth-grpcservice.bookinfo.svc.cluster.local:9001
    server:
      name: default-server
      namespace: bookinfo
      cluster: $CLUSTER_NAME
EOF
  
Review the following table to understand this configuration.
SettingDescription
spec.applyToRoutesUse labels to configure which routes to apply the policy to. This example label matches the app and route from the example route table that you apply separately. If omitted and you do not have another selector such as applyToDestinations, the policy applies to all routes in the workspace.
spec.config.glooAuth.configs.passThroughAuthSet the gRPC service address. The example uses the service address and port that you created in the previous section. For more options, see the API reference.
spec.config.serverRefer to the ExtAuthServer resource that you created for either the default server or a custom server. The example uses the ExtAuthServer resource that you created in the external auth server setup guide.

Verify external auth policies

  1. Send a request to the ratings app. You get back a 403 (Unauthorized) response, because the request is not authenticated.

  2. Send an authenticated request to the ratings app. The gRPC service that you deployed is set up to accept any request with an authorization: authorize me header.

    Your request succeeds again!

Cleanup

You can optionally remove the resources that you set up as part of this guide.
  kubectl -n bookinfo delete Deployment extauth-grpcservice
kubectl -n bookinfo delete Service extauth-grpcservice
kubectl -n bookinfo delete ExtAuthServer default-server
kubectl -n bookinfo delete ExtAuthPolicy passthrough-auth
  

Share state with other auth steps

You can set up the Gloo Mesh Gateway external auth server to share state between the passthrough service and other auth steps, such as OPA, an API key, or a custom auth plug-in.

If you make a custom auth plug-in, you can use a state map to chain together the auth steps that you want to require. For more information, see the following resources:

Reading state from other auth steps

State from other auth steps is sent to the passthrough service via CheckRequest FilterMetadata under a unique key: solo.auth.passthrough.

Writing state to be used by other auth steps

State from the passthrough service can be sent to other auth steps via CheckResponse DynamicMetadata under a unique key: solo.auth.passthrough.

Passing in custom configuration to Passthrough Auth Service from AuthConfigs

You can pass a custom config to the passthrough authentication service by using the config.passThroughAuth section in the external auth policy. You might use a custom config to add extra authentication information to passed-through requests, such as a custom key.

This config is accessible via the CheckRequest FilterMetadata under a unique key: solo.auth.passthrough.config.

kubectl apply -f- <<EOF
apiVersion: security.policy.gloo.solo.io/v2
kind: ExtAuthPolicy
metadata:
  name: passthrough-auth
  namespace: bookinfo
spec:
  applyToRoutes:
  - route:
      labels:
        route: ratings
  config:
    glooAuth:
      configs:
      - passThroughAuth:
          grpc:
            address: example-grpc-auth-service.bookinfo.svc.cluster.local:9001
          config:
            customKey1: "customConfigStringValue"
            customKey2: false
    server:
      name: default-server
      namespace: bookinfo
      cluster: $CLUSTER_NAME
EOF