Delegate API gateway authorization to an external service on Kubernetes
Enterprise
This feature requires Consul Enterprise. Refer to the enterprise feature matrix for additional information.
This topic describes how to delegate authorization for requests to Consul API gateways to an external service on Kubernetes-orchestrated networks. If your services are deployed to virtual machines, refer to Delegate API gateway authorization to an external service on virtual machines.
Overview
The external authorization Envoy extension (builtin/ext-authz) instructs Envoy to call an external authorization service before it forwards a request to an upstream.
Consul uses the extension's ProxyType field to determine where to enforce authorization:
- When
ProxyTypeis set toconnect-proxy, authorization is enforced at a service's sidecar proxy level. This is used for east-west traffic. - When
ProxyTypeis set toapi-gateway, the extension is applied to the API gateway itself and external authorization is applied to the requests received by the API gateway. This is used for north-south traffic.
This topic describes the api-gateway case.
Applying the extension to the gateway's ServiceDefaults resource is a prerequisite for external authorization. Once applied, external authorization is enabled by default for every route attached to that gateway.
After you apply the extension, you can control external authorization at two levels:
- Gateway-wide default: The
consul.hashicorp.com/ext-authzannotation on theGatewayresource sets the default authorization behavior for all routes attached to that gateway. When the extension is applied but no annotation is present, external authorization is enabled for all routes. - Per-route override: The
RouteAuthFilterresource or theconsul.hashicorp.com/ext-authzannotation on anHTTPRouteoverrides the gateway-wide default for the routes it defines.
Requirements
- Consul Enterprise 2.0.2 or later
- An API gateway deployed and configured to route to one or more mesh services
- An external authorization service that implements the Envoy external authorization gRPC or HTTP API
Enable external authorization
Add the external authorization extension to the ServiceDefaults resource for your API gateway and set ProxyType to api-gateway.
The api-gateway ProxyType allows you to configure Target.URI to point at an authorization service on a remote host.
gateway-service-defaults.yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
name: api-gateway
spec:
protocol: http
envoyExtensions:
- name: builtin/ext-authz
arguments:
ProxyType: api-gateway
Config:
GrpcService:
Target:
URI: authz.example.com:9191
AllowedHeaders:
- Prefix: x-
DisallowedHeaders:
- Exact: authorization
IgnoreCase: true
For the full list of configurable fields, including request and response header controls, refer to the external authorization extension configuration reference.
Apply the resource to your cluster:
$ kubectl apply -f gateway-service-defaults.yaml
Override external authorization behavior for specific routes
This section describes how to change the gateway-wide default or enable external authorization for individual routes only. To do so, complete the following steps:
- Disable external authorization for the API gateway by setting the
consul.hashicorp.com/ext-authzannotation on theGatewayresource todisabled. This makes external authorization opt-in for all routes. - Enable external authorization for specific routes using a
RouteAuthFilterconfiguration entry or an annotation on theHTTPRouteresource.
Disable external authorization for the API gateway
External authorization is enabled by default for all routes attached to the Gateway resource. This step is optional and only necessary when you want to make external authorization opt-in at the route level.
Add the consul.hashicorp.com/ext-authz annotation to the Gateway resource and set it to disabled.
gateway.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: api-gateway
annotations:
consul.hashicorp.com/ext-authz: disabled
spec:
gatewayClassName: consul
listeners:
- name: http-listener
port: 8443
protocol: HTTP
Apply the resource to your cluster:
$ kubectl apply -f gateway.yaml
Use RouteAuthFilter configuration entry
Define a RouteAuthFilter that uses the external authentication. The filter's spec.extAuthz.enabled value takes precedence over the gateway-wide default.
route-auth-filter.yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: RouteAuthFilter
metadata:
name: admin-ext-authz
namespace: default
spec:
extAuthz:
enabled: true
Reference the filter from an HTTPRoute with an extensionRef filter.
http-route.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: admin-route
spec:
parentRefs:
- name: api-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /admin
filters:
- type: ExtensionRef
extensionRef:
group: consul.hashicorp.com
kind: RouteAuthFilter
name: admin-ext-authz
backendRefs:
- name: admin
port: 8080
Apply the resources to your cluster:
$ kubectl apply -f route-auth-filter.yaml
$ kubectl apply -f http-route.yaml
Use an annotation in the HTTPRoute configuration entry
Alternatively, add the consul.hashicorp.com/ext-authz annotation directly to an HTTPRoute to override the authorization behavior for the routes it defines. Set the value to enabled or disabled. It takes more precedence over gateways consul.hashicorp.com/ext-authz annotation.
http-route-annotation.yaml
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: admin-route
annotations:
consul.hashicorp.com/ext-authz: enabled
spec:
parentRefs:
- name: api-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /admin
backendRefs:
- name: admin
port: 8080
Apply the resource to your cluster:
$ kubectl apply -f http-route-annotation.yaml
After Consul reconciles the resources, the API gateway calls the external authorization service according to the authorization behavior you configured before it forwards matching requests to upstream services.