Delegate API gateway authorization to an external service on virtual machines
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 virtual machines (VM). If your services are deployed to Kubernetes-orchestrated containers, refer to Delegate API gateway authorization to an external service on Kubernetes.
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 service defaults configuration entry 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
ExtAuthzblock in the API gateway configuration entry sets the default authorization behavior for all routes attached to the gateway. When the extension is applied but noExtAuthzblock is present, external authorization is enabled for all routes. - Per-route override: The
ExtAuthzfilter in an HTTP route configuration entry overrides the gateway-wide default for the routes it matches.
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 service defaults configuration entry 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.hcl
Kind = "service-defaults"
Name = "api-gateway"
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.
Write the configuration entry to Consul:
$ consul config write gateway-service-defaults.hcl
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
ExtAuthz.Enabledtofalsein the API gateway configuration entry. This makes external authorization opt-in for all routes. - Enable external authorization for specific routes using the
ExtAuthzfilter in an HTTP route configuration entry.
Disable external authorization for the API gateway
External authorization is enabled by default for all routes attached to the gateway. This step is optional and only necessary when you want to make external authorization opt-in at the route level.
Use the ExtAuthz block in the API gateway configuration entry to set ExtAuthz.Enabled to false.
api-gateway.hcl
Kind = "api-gateway"
Name = "api-gateway"
ExtAuthz = {
Enabled = false
}
Listeners = [
{
Name = "http-listener"
Port = 8443
Protocol = "http"
}
]
Write the configuration entry to Consul:
$ consul config write api-gateway.hcl
Use the HTTP route ExtAuthz filter
Use the ExtAuthz filter in an HTTP route configuration entry to force external authorization on or off for the routes that the rule matches. The route-level setting takes precedence over the gateway-wide default.
In the following example, external authorization is enabled for requests to /admin even when the gateway-wide default is opt-in:
http-route.hcl
Kind = "http-route"
Name = "admin-route"
Parents = [
{
Kind = "api-gateway"
Name = "api-gateway"
}
]
Rules = [
{
Matches = [
{
Path = {
Match = "prefix"
Value = "/admin"
}
}
]
Filters = {
ExtAuthz = {
Enabled = true
}
}
Services = [
{
Name = "admin"
}
]
}
]
Write the configuration entry to Consul:
$ consul config write http-route.hcl
After Consul applies the configuration, the API gateway calls the external authorization service according to the authorization behavior you configured before it forwards matching requests to upstream services.