---
layout: docs
page_title: Delegate authorization to an external service
description: Learn how to use the `ext-authz` Envoy extension to delegate data plane authorization requests to external systems. 
---

# Delegate authorization to an external service

This topic describes how to use the external authorization Envoy extension to delegate data plane authorization requests to external systems. 

## Workflow

Complete the following steps to use the external authorization extension:

1. Configure an `EnvoyExtensions` block in a service defaults or proxy defaults configuration entry. 
1. Apply the configuration entry.

## Add the `EnvoyExtensions`

Add Envoy extension configurations to a proxy defaults or service defaults configuration entry. Place the extension configuration in an `EnvoyExtensions` block in the configuration entry.

- When you configure Envoy extensions on proxy defaults, they apply to every service.
- When you configure Envoy extensions on service defaults, they apply to a specific service.

Consul applies Envoy extensions configured in proxy defaults before it applies extensions in service defaults. As a result, the Envoy extension configuration in service defaults may  override configurations in proxy defaults.

The following example shows a service defaults configuration entry for the `api` service that directs the Envoy proxy to make gRPC authorization requests to the `authz` service:

<Tabs>
<Tab heading="HCL" group="hcl">
<CodeBlockConfig filename="api-auth-service-defaults.hcl">

```hcl
Kind = "service-defaults"
Name = "api"
EnvoyExtensions = [
  {
    Name = "builtin/ext-authz"
    Arguments = {
      ProxyType = "connect-proxy"
      Config = {
        GrpcService = {
          Target = {
            Service = {
              Name = "authz"
            }
          }
        }
      }
    }
  }
]
```
</CodeBlockConfig>
</Tab>
<Tab heading="JSON" group="json">
<CodeBlockConfig filename="api-auth-service-defaults.json">

```json
{
  "Kind": "service-defaults",
  "Name": "api",
  "EnvoyExtensions": [{
    "Name": "builtin/ext-authz",
    "Arguments": {
      "ProxyType": "connect-proxy",
      "Config": {
        "GrpcService": {
          "Target": {
            "Service": {
              "Name": "authz"
              }
            }
          }
        }
      }
    }
  ]
}
```

</CodeBlockConfig>
</Tab>
<Tab heading="Kubernetes" group="yaml">
<CodeBlockConfig filename="api-auth-service-defaults.yaml">

```yaml
apiVersion: consul.hashicorp.com/v1alpha1
kind: ServiceDefaults
metadata:
  name: api
  namespace: default
spec:
  envoyExtensions:
  - name: builtin/ext-authz
    arguments:
      proxyType: connect-proxy
      config:
        grpcService:
          target:
            service:
              name: authz
              namespace: authz
```
</CodeBlockConfig>
</Tab>
</Tabs>

Refer to the [external authorization extension configuration reference](/consul/docs/connect/proxies/envoy-extensions/configuration/ext-authz) for details on how to configure the extension. 

Refer to the [proxy defaults configuration entry reference](/consul/docs/connect/config-entries/proxy-defaults) and [service defaults configuration entry reference](/consul/docs/connect/config-entries/service-defaults) for details on how to define the configuration entries. 

!> **Warning:** Adding Envoy extensions default proxy configurations may have unintended consequences. We recommend configuring `EnvoyExtensions` in service defaults configuration entries in most cases.

### Unsupported Envoy configuration fields

The following Envoy configurations are not supported:

| Configuration | Workaround |
| --- | --- |
| `deny_at_disable` | Disable filter by removing it from the service’s configuration in the configuration entry. |
| `failure_mode_allow` | Set the `EnvoyExtension.Required` field to `true` in the [service defaults configuration entry](/consul/docs/connect/config-entries/service-defaults#envoyextensions) or [proxy defaults configuration entry](/consul/docs/connect/config-entries/proxy-defaults#envoyextensions). |
| `filter_enabled` | Set the `EnvoyExtension.Required` field to `true` in the [service defaults configuration entry](/consul/docs/connect/config-entries/service-defaults#envoyextensions) or [proxy defaults configuration entry](/consul/docs/connect/config-entries/proxy-defaults#envoyextensions). |
| `filter_enabled_metadata` | Set the `EnvoyExtension.Required` field to `true` in the [service defaults configuration entry](/consul/docs/connect/config-entries/service-defaults#envoyextensions) or [proxy defaults configuration entry](/consul/docs/connect/config-entries/proxy-defaults#envoyextensions). |
| `transport_api_version` | Consul only supports v3 of the transport API. As a result, there is no workaround for implementing the behavior of this field. |

## Apply the configuration entry

If your network is deployed to virtual machines, use the `consul config write` command and specify the proxy defaults or service defaults configuration entry to apply the configuration. For Kubernetes-orchestrated networks, use the `kubectl apply` command. The following example applies the extension in a proxy defaults configuration entry.

<Tabs>
<Tab heading="HCL" group="hcl">

```shell-session
$ consul config write api-auth-service-defaults.hcl
```

</Tab>
<Tab heading="JSON" group="json">

```shell-session
$ consul config write api-auth-service-defaults.json
```

</Tab>
<Tab heading="Kubernetes" group="kubernetes">

```shell-session
$ kubectl apply -f api-auth-service-defaults.yaml
```

</Tab>
</Tabs>
