Skip to main content

Protecting APIs Deployed Behind Istio Service Mesh

Learn how to install and configure SecureAuth's Istio Authorizer to protect APIs and services deployed behind the Istio Service Mesh. You can learn, for example, how to deploy and protect HTTP and gRPC services.

Install Istio Authorizer

Installation Alternative

As an alternative to this procedure, you can install both Istio Service Mesh and Istio Authorizer using the SecureAuth on k8s repository which provides simple deployment commands you can use out of the box.

Prerequisites

  • Kubernetes version 1.19 or subsequent

  • Kubernetes cluster is set up.

    Setting Up k8s Cluster

    You can set up a Kubernetes cluster locally using kind.

    Go version below 1.17

    GO111MODULE="on" go get sigs.k8s.io/kind@v0.9.0 && kind create cluster               

    Go version 1.17 or above

    GO111MODULE="on" go install sigs.k8s.io/kind@ && kind create cluster               
  • Istio version 1.9 or subsequent is installed and up and running.

  • Istio Sidecar is installed.

    Injecting Istio Sidecar

    To configure Istio proxies, you need to inject Istio Sidecar to pods running in your Istio Service Mesh. It can be done either automatically at pod creation and using admission controller, or manually at any given time.

    SecureAuth recommends using automatic sidecar injection and setting the istio-injection flag to enabled for any namespace that contains the services you wish to protect with Istio Authorizer.

  • Helm version 3.0 or subsequent

Create Istio Authorizer in SecureAuth

  1. In the workspace of your choice, select Authorization > Gateways> CREATE GATEWAY.

  2. Select Istio, enter the name and the description for your authorizer, and select NEXT.

  3. In the Gateway Management view, go to the QUICK START tab and proceed as follows:

    1. Install Istio Authorizer using Helm chart:

      helm repo add acp https://charts.cloudentity.io && helm repo update
      helm upgrade --install istio-authorizer acp/istio-authorizer \
      --set clientCredentials.clientID={yourClientIdentifier} \
      --set clientCredentials.clientSecret={yourClientSecret} \
      --set issuerURL={yourIssuerURL} \
      --set "discovery.namespaces={default}" \
      --namespace acp-istio-authorizer \
      --create-namespace

      You can find this command with the arguments filled for you in the QUICKSTART view for your authorizer instance.

      The clientCredentials.clientID, clientCredentials.clientSecret, and issuerURL parameters are used in the client credentials OAuth grant type to authenticate your authorizer's requests to, for example, fetch authorization policies from SecureAuth.

      The clientCredentials.clientID argument should point to the client identifier of the client application created for your authorizer in the System workspace of your tenant. You can find the client identifier in the Settings view for your authorizer.

      The clientCredentials.clientSecret argument should point to the client secret of the client application created for your authorizer in the System workspace of your tenant. You can find the client secret in the Settings view for your authorizer.

      Credentials security

      For production environments, you should create Kubernetes secrets manually that are responsible for storing your credentials values.

      To increase security of secrets stored in your repository, it is recommended to encrypt your Kubernetes secrets. You can use tools like Mozilla SOPS or Bitnami Sealed Secrets to encrypt your secrets.

      When the secrets are applied to your Kubernetes deployment, the secrets are visible as plain text. Anyone who is authorized to create a Pod in a namespace can read any secret in that namespace; this includes indirect access such as the ability to create a Deployment. To mitigate the risks, Kubernetes recommends to:

      • Enable encryption at Rest for secrets.

      • Enable or configure RBAC rules that restrict reading data in secrets.

      • Where appropriate, use mechanisms such as RBAC to limit which principals are allowed to create or replace secrets.

      To learn more, visit Kubernetes secrets documentation.

      The issuerURL argument should point to the issuer URL of your Istio Authorizer client application created within the System workspace of your tenant. You can find the issuer URL in the Settings view for your authorizer. If you are using a vanity domain for your SecureAuth tenant and it is impossible to retrieve the tenant's and server's identifier from the URL, provide values for the tenantID and serverID parameters in your values.yaml file.

      The discovery.namespaces={default} parameter is responsible for providing the namespaces where Istio Authorizer performs the service discovery. By default, Istio Authorizer performs discovery only in the default namespace. You can add a comma-separated list of namespaces as the value for the discovery.namespaces parameter provided that those namespaces already exist, for example, discovery.namespaces={default,example1,example2}. If you wish to know more, see the API Discovery Configuration for Istio Authorizer article.

      tip

      If you need to change your Istio Authorizer settings, see configuration reference.

      Result: Istio Authorizer scans deployments in configured namespaces and funnels information about discovered APIs to SecureAuth. Note that if you didn't deploy any services yet, there's nothing to discover. To quickly deploy a sample HTTP/gPRC service, follow:

Add Istio Authorizer as Extension Provider to Istio

To delegate access control enforcement to your Istio Authorizer, you need to define it as an external authorization provider for your Istio Service Mesh.

  1. Edit the mesh configuration using the following command:

    kubectl edit configmap istio -n istio-system                  
  2. Define SecureAuth Authorizer using extension providers, for example:

    data:
    mesh: |-
    extensionProviders:
    - name: "acp-authorizer"
    envoyExtAuthzGrpc:
    service: "istio-authorizer.acp-istio-authorizer.{cluster-name}"
    port: "9001"

    The {cluster-name} variable should point to your cluster name, for example, svc.cluster.local.

    Istio Extension Providers

    Since v1.14.0, Istio added an example extension provider to their mesh configuration. When adding the acp-authorizer extension provider to the Istio configmap, make sure that you do not duplicate the extensionProviders entry as it may result in the authorizer or your additional extension providers not working properly.

  3. Restart Istio to apply the changes:

    kubectl rollout restart deployment/istiod -n istio-system                  

Deploy and Protect Services

With Istio Authorizer installed and attached to Istio Service Mesh as an external authorization provider, you can:

Parsing Request Bodies

For HTTP services, SecureAuth supports parsing request bodies. It can be used, for example, to write an authorization policy that checks request bodies.

If you wish to parse request bodies, you need to set the parseBody.enabled flag to true in the values.yaml file for your authorizer.

API Discovery Configuration for Istio Authorizer

SecureAuth Istio Authorizer supports automatic service discovery based on the OpenAPI specification.

Services Hosting OpenAPI Endpoints

For services that host an OpenAPI endpoint, it is possible to provide this endpoint's path as the value for the openAPIEndpoint parameter in Istio Authorizer's configuration. By doing so, you can instruct Istio Authorizer to add this path to the whitelist enabling the API discovery functionality to work without being blocked by the authorization layer.

A service can use the services.k8s.cloudentity.com/spec-url annotation on a deployed k8s resource to specify a URL where its OpenAPI or Proto specification is available, for example:

kind: Deployment
metadata:
name: hello
labels:
app: hello
namespace: default
annotations:
services.k8s.cloudentity.com/spec-url: "https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml"

Istio Authorizer scans k8s deployments and, once it has found the annotation described above, it fetches the specification, parses it to get a list of APIs that a service is exposing, and then it's sending this information to SecureAuth.

By default, Istio Authorizer is configured to perform service discovery only in the default namespace. To make Istio Authorizer perform the service discovery in other namespaces, edit the values.yaml file. In th data.config section, add your namespaces:

discovery:
namespaces:
- default
- namespace1
- namespace2

With the above settings, Istio performs service discovery in all of the following namespaces: default, namespace1, and namespace2.

To learn how you can configure API discovery for Configuration Reference Istio Authorizer, see its configuration reference.

Deploy and Protect HTTP Services

Prerequisites

  • Istio Authorizer is installed

Deploy Sample Service

Deploy a sample HTTP service using the following command:

kubectl apply -f - <<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
---
apiVersion: v1
kind: Service
metadata:
name: httpbin
spec:
selector:
app: httpbin
ports:
- port: 80
name: http
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
labels:
app: httpbin
annotations:
services.k8s.cloudentity.com/spec-url: "http://httpbin.org/spec.json"
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
template:
metadata:
labels:
app: httpbin
spec:
serviceAccountName: httpbin
containers:
- name: httpbin
image: "kennethreitz/httpbin"
ports:
- containerPort: 80
name: http
EOF

Connect Service

There are two ways to connect Istio API groups to SecureAuth services: starting from the gateway to be connected or starting from the service that you want to connect.

From Gateway

  1. From the list of available gateways, select your newly-created Istio gateway and go to its APIs tab.

    A list of imported API groups opens.

  2. From the list of API groups available, select an API group and, from its drop-down menu, pick a service to which you'd like to connect the API group.

    note

    You can connect the API group to an existing service or a new one you create, both options available from the same service drop-down menu.

From Service

  1. Select APIs from the left sidebar and go to the AUTHORIZATION tab.

  2. Pick a service that you want to connect and select ADD GATEWAY API for the selected service.

  3. In the Connect Istio API Group popup window, select an API gateway and an API group to be connected. Click CONNECT to proceed.

    Result:In the APIS tab of the Gateway Management view, you can see specific API groups integrated to services.

Apply Policy

Once SecureAuth has discovered the APIs deployed behind your Istio gateway, you can protect those APIs with an SecureAuth policy.

  1. Create an API policy:

  2. Select APIs from the left sidebar and go to the AUTHORIZATION tab.

  3. Select any Istio-protected API with authorization status Unrestricted. The policy selection form opens.

  4. In the policy selection form, select a policy from the dropdown list and click Update to proceed.

    Result:You have successfully assigned a policy to your Istio API.

Test Enforcement

To test your deployed and protected service, change the variables and execute the command:

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.9/samples/sleep/sleep.yaml
export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec -it $SLEEP_POD -c sleep curl {YOUR_SERVICE_URL}/{ENDPOINT}

Example:

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.9/samples/sleep/sleep.yaml
export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec -it $SLEEP_POD -c sleep curl http://httpbin:80/deny

Verify that the request is blocked or passing in accordance with your applied policy.

Deploy and Protect gRPC Services

About gRPC

gRPC is an open source Remote Procedure Call (RPC) framework that allows you to efficiently connect services to data centers while maintaining a high performance results. gRPC uses protocol buffers as both its Interface Definition Language (IDL) and as its underlying message interchange format.

It makes it easier to create a distributed applications and services system with gRPC, as your client applications can directly call methods on the server application that resides on a different machine as they were local objects. Most of the RPCs, including gRPC, are based on the solution to define a service and to specify the methods that can be called remotely with their parameters and return types. On the server side (in this case, SecureAuth, the server implements those interfaces and runs a gRPC server that handles the requests coming from client applications.

Prerequisites

  • Istio Authorizer is installed

Deploy Sample Service

Deploy a sample grpc service using the following command:

kubectl apply -f https://raw.githubusercontent.com/cloudentity/acp-on-k8s/master/examples/fortune-teller/deployment.yaml            

Connect Service

There are two ways to connect Istio API groups to SecureAuth services: starting from the gateway to be connected or starting from the service that you want to connect.

From Gateway

  1. From the list of available gateways, select your newly-created Istio gateway and go to its APIs tab.

    A list of imported API groups opens.

  2. From the list of API groups available, select an API group and, from its drop-down menu, pick a service to which you'd like to connect the API group.

    note

    You can connect the API group to an existing service or a new one you create, both options available from the same service drop-down menu.

From Service

  1. Select APIs from the left sidebar and go to the AUTHORIZATION tab.

  2. Pick a service that you want to connect and select ADD GATEWAY API for the selected service.

  3. In the Connect Istio API Group popup window, select an API gateway and an API group to be connected. Click CONNECT to proceed.

    Result:In the APIS tab of the Gateway Management view, you can see specific API groups integrated to services.

Apply Sample Policy

  1. Create a policy.

  2. Select APIs from the left sidebar and go to the AUTHORIZATION tab.

  3. Select a service protected by Istio and any API with authorization status None.

  4. In the Edit API popup window, select Policy from the dropdown list and click Update to proceed.

    Result:You have successfully assigned a policy to your API.

Test Enforcement

To test your deployed and protected service, change the variables and execute the command:

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.9/samples/sleep/sleep.yaml
export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec -it $SLEEP_POD -c sleep curl {YOUR_SERVICE_URL}/{ENDPOINT}

Example:

kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.9/samples/sleep/sleep.yaml
export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name})
kubectl exec -it $SLEEP_POD -c sleep curl http://httpbin:80/deny
note

grpcurl is using reflection to be able to call gRPC service endpoints. By default the authorizer blocks calls to unknown APIs (APIs that were not discovered). To be able to use the grpcurl run the authorizer with the enforcement.allow_unkown value set to true in your Istio Authorizer installation values.yaml file. Use this for testing purposes only.

Configure Istio Authorizer

Istio Authorizer configuration changes are done by adjusting the Istio Authorizer's values.yaml file and upgrading your Helm Chart release. To know which settings are available for your authorizer, see the Configuration reference section.

Commonly used properties like, for example, issuerURL, client credentials, and more are easily available top-level properties.

The following snippet shows a simple configuration with some of the popular options tuned.

parseBody:
enabled: true
discovery:
enabled: true
namespaces:
- default
extraConfig:
acp:
reload_interval: 1m0s # reload interval
enforcement:
allow_unkown: false

Values Case

Note that top-level settings are provided using camelCase and settings in the extraConfig value are provided with underscores.

If you want to change more advanced settings of the authorizer, you can use the extraConfig value. Properties in the extraConfig value correspond to the raw configuration passed to the istio-authorizer binary.

Configuration Order

Properties defined through top-level properties take precedence over configuration provided in the extraConfig value.

You can apply your changes to the configuration using the helm upgrade release-name chart-name -f ValuesYamlFile. See example below:

helm upgrade istio-authorizer acp/istio-authorizer \
--values ./values/istio-authorizer.yaml \
--namespace acp-istio-authorizer \
--timeout 5m \
--wait
tip

If you need help with upgrading Helm Charts, use the helm upgrade --help command in your terminal.

Configuration Reference

# acp
acp:
reload_interval: 1m0s # reload interval
reload_timeout: 30s # reload configuration timeout
issuer_url: https://localhost:8443/sample/system # issuer url
client_id: bqesdrc4m4co2s81mpu0 # client id
client_secret: LH6mAb6PNljvjYMIF-A5RP2bElA5a5bnQah8sG0fsLA # client secret
tenant_id: "" # tenant id
server_id: "" # server id
# http client
http_client:
timeout: 10s # http client timeout
retry_wait_min: 0s # minimum time to wait between retries
retry_wait_max: 0s # maximum time to wait between retries
retry_max: 0 # maximum number of retries
root_ca: "" # root ca that this client should trust (defaults to system root ca)
insecure_skip_verify: false # disable cert verification
disable_follow_redirects: false # disable follow redirects
disable_retry: true # disable retry
# metrics
metrics:
enabled: false # enable metrics endpoint
port: 9000 # metrics endpoint port
# analytics
analytics:
enabled: true # when enabled, events are sent to audit log
# event format
event_format:
include_policy_output: false # when enabled, policy evaluation output is sent to audit log
# sampling
sampling:
probability: 1 # Probability of an event to be published (0.0-1.0)
batch_inverval: 1s # Max duration to wait for a batch to publish
batch_limit: 100 # Max number of events in a batch
limit: 5 # Max number of batches per second to be published
timeout: 5s # Timeout for a single batch to send
workers: 8 # Number of sending workers
# cache
cache:
ttl: 10s # ttl
max_size: 100 # max size
# logging config
logging:
level: info # log level severity
# token echange config
token_exchange:
enabled: false # enable token exchange
# cache
cache:
ttl: 1m0s # ttl
max_size: 1000 # max size
# inject config (supported only for istio authorizer)
inject:
mode: "" # Defines what token should be sent to the target service when token is exchanged
# headers config
headers:
exchanged_token: "" # Defines the name of the header that contains an exchanged token.
original_token: "" # Defines the name of the header that contains an original token.
strip_bearer: false # Allows to strip the bearer prefix in headers
# enforcement config
enforcement:
allow_unknown: false # allow requests with no matching rule
# discovery config
discovery:
enabled: true # when true, API discovery is enabled
timeout: 10s # discovery process timeout
interval: 30s # how often discovery is performed
disable_proxy: false # disable proxy in discovery
open_api_endpoint: "" # if your service is self-hosting an OpenAPI endpoint, you need to provide the path to this endpoint to enable Istio authorizer to call this endpoint and automatically discover your APIs
# discover services in a given namespaces
namespaces:
- default
grpc_reflection_calls: false # allow grpc reflection calls
# http server
http_server:
port: 9002 # http port
dangerous_disable_tls: true # diables TLS
# certificate configuration
certificate:
password: "" # key passphrase
cert_path: "" # path to the certificate PEM file
key_path: "" # path to the key PEM file
cert: "" # base64 encoded cert PEM
key: "" # base64 encoded key PEM
generated_key_type: "" # type for generated key if cert and key are not provided (rsa or ecda)
client_auth_type: 0 # client auth type
# grpc server
grpc_server:
port: 9001 # gRPC port
# target service config
target_service:
# inject config
inject:
# headers config
headers:
custom_data_prefix: x-output- # custom data header name prefix used to propage global variables defined in a policy
auth_ctx: x-auth-ctx # header name containing base64 encoded authentication context json object
trust_domain: cluster.local
kubeconfig: "" # absolute path to the kubeconfig file

Import Istio Authorizer Configuration Declaratively

Declarative Configuration Import for SecureAuth platform

To learn about declarative configuration import for SecureAuth configuration, see the Declarative configuration import for SecureAuth article.

Prerequisites

  1. All prerequisites for Declarative configuration import for SecureAuth are met.

  2. Istio version 1.9 or subsequent is installed and up and running.

  3. Istio Authorizer is added as an extension provider for your Istio Service Mesh.

    For instructions on how to define Istio Authorizer as an external authorization provider for Istio, see Installing Istio Authorizer guide.

  4. Service of your choice deployed in your Kubernetes cluster

    You need to deploy a service in order to be able to import APIs to your SecureAuth instance and apply access control to protect them.

    tip

    If you do not have a deployment-ready service at hand, you can deploy, for example, a httpbin service which can be found in the acp-on-k8s GitHub repository . For more instructions regarding protecting HTTP services, see Deploying and protecting HTTP services.

Import Istio Authorizer

  1. Edit your acp-cd Helm Chart's values.yaml file and provide your configuration definition for Istio Authorizer and its client application.

    tip

    To learn how to import authorizers to SecureAuth, see Authorizers section of the Declarative configuration import for SecureAuth article.

    data:
    gateways:
    - tenant_id: {tid}
    authorization_server_id: {aid}
    id: sample-istio-authorizer
    client_id: istio-authorizer-client
    client_secret: cf53caab-fb55-40a7-8c63-620ce11102e2
    name: Sample Istio Authorizer
    description: Sample imported Istio Authorizer
    type: istio
    create_and_bind_services_automatically: true
    clients:
    - tenant_id: {tid}
    authorization_server_id: system
    client_id: istio-authorizer-client
    client_secret: cf53caab-fb55-40a7-8c63-620ce11102e2
    token_endpoint_auth_method: client_secret_basic
    system: false
    trusted: false
    client_name: Istio Authorizer client
    application_type: web
    grant_types:
    - client_credentials
    response_types:
    - code
    scopes:
    - introspect_tokens
    - push_gateway_requests
    - read_gateway_configuration
    - write_gateway_configuration
  2. Upgrade your Helm Chart.

    Result: Your Istio Authorizer is imported to SecureAuth and a client application for the authorizer is created in the System workspace of your tenant.

Install Istio Authorizer in k8s

Install Istio Authorizer using its Helm Chart and adjust its configuration to your needs. You do not need to manually create your authorizer in SecureAuth's UI as you had already imported the authorizer in the previous step of this guide.

Import API Groups and Services

To learn how to import API groups and services and to know what are the possible scenarios that differ between your authorizer configuration for service discovery, get familiar with the API groups and services section of the Declarative configuration import for SecureAuth article.

For Istio Authorizer, API group identifier and service identifiers are Base64 URL encoded SPIFFE IDs which are built being based on the service account of the protected pod. To avoid using long and unreadable API groups identifiers, SecureAuth supports Base64 encoding of SPIFFE IDs.

You can define your API group identifier using the encSpiffeID function as shown below:

gateway_api_groups:
- id: "{{ encSpiffeID \"spiffe://{domain}/ns/{namespace}/sa/{service_account}\" }}"

You can define your service identifier using the encServiceID function as shown below:

services:
- id: "{{ encServiceID \"spiffe://{domain}/ns/{namespace}/sa/{service_account}\" }}"
  1. Prepare your values.yaml file.

    If you disabled service discovery for your authorizer, an import example can look like the following:

    data:
    gateway_api_groups:
    - tenant_id: {tid}
    server_id: {aid}
    id: "{{ encSpiffeID \"spiffe://cluster.local/ns/default/sa/httpbin\" }}"
    service_id: httpbin-service
    gateway_id: sample-istio-authorizer
    name: default/httpbin_api_group
    apis:
    - method: GET
    path: /deny
    - method: GET
    path: /anything
    services:
    - id: httpbin-service
    tenant_id: {tid}
    authorization_server_id: {aid}
    gateway_id: sample-istio-authorizer
    name: default/httpbin_service
    apis:
    - method: GET
    path: /deny
    can_have_policy: true
    policy_id: block_api
    - method: GET
    path: /anything
    can_have_policy: true
    policy_id: block_api

    You can see that in the example above, the service identifier is not encoded. When you encode your API group identifier, you do not need to encode the service ID. You can encode it if you wish, but then, in the service_id parameter of the gateway_api_groups object, you need to provide the encoded service identifier as well.

    If the service discovery setting is enabled for your authorizer, an import example can look like the following:

    data:
    services:
    - id: "{{ encServiceID \"spiffe://cluster.local/ns/default/sa/httpbin\" }}"
    tenant_id: {tid}
    authorization_server_id: {aid}
    gateway_id: sample-istio-authorizer
    name: default/httpbin_service
    apis:
    - method: GET
    path: /deny
    can_have_policy: true
    policy_id: block_api
    - method: GET
    path: /anything
    can_have_policy: true
    policy_id: block_api

    You can see that to avoid long and unreadable service ID, it is encoded using the {{ encServiceID }} function.

    Policies Assignment

    The above example includes policies already assigned to your APIs. You can assign policies when importing services as long as they already exist within SecureAuth or are imported as a part of the same values.yaml file.

  2. Upgrade your Helm Chart.

    Result:Your API groups and services are imported to SecureAuth and visible in the APIs view.

    If you imported the definition for services with policies assigned, your APIs are already protected. If not, you can assign them manually.

Troubleshooting

RBAC: Access Denied

Example:

$ curl -v http://httpbin.default:80/get
...
< HTTP/1.1 403 Forbidden
RBAC: access denied

If your calls to protected APIs always result with the RBAC: access denied response, verify your Istio configuration for Istio authorization policies and Istio configuration (configmap). Such response may be a result of Istio changing the authorization policy from, for example, ALLOW or CUSTOM to DENY:

│ 2022-10-07T13:49:40.972592Z    error    authorization    Processed authorization policy: failed to parse CUSTOM action, will generate a deny all config: available providers are [] but found "acp-authorizer"  │            

In case of the SecureAuth Istio Authorizer, such situation may happen if you duplicate the extensionProviders configuration in your Istio configmap when adding the acp-authorizer extension provider.

Incorrect Configmap Example:

apiVersion: v1
data:
mesh: |-
extensionProviders:
- name: "acp-authorizer"
envoyExtAuthzGrpc:
service: "istio-authorizer.acp-istio-authorizer.svc.cluster.local"
port: 9001
accessLogFile: /dev/stdout
defaultConfig:
discoveryAddress: istiod.istio-system.svc:15012
proxyMetadata: {}
tracing:
zipkin:
address: zipkin.istio-system:9411
enablePrometheusMerge: true
extensionProviders:
- envoyOtelAls:
port: 4317
service: opentelemetry-collector.istio-system.svc.cluster.local
name: otel
[...]

In the example above, notice how the extensionProviders entry is added twice to the Istio configuration. Because of this, Istio treats your configuration for the acp-authorizer as invalid and switches the following Istio authorization policy for the SecureAuth Istio Authorizer from the CUSTOM action to the DENY_ALL action:

Spec:
Action: CUSTOM
Provider:
Name: acp-authorizer
Rules:
Events: <none>
tip

This authorization policy is added for you automatically to Istio as part of the SecureAuth Istio Authorizer Helm Chart installation process.

Correct Configmap Example:

apiVersion: v1
data:
mesh: |-
accessLogFile: /dev/stdout
defaultConfig:
discoveryAddress: istiod.istio-system.svc:15012
proxyMetadata: {}
tracing:
zipkin:
address: zipkin.istio-system:9411
enablePrometheusMerge: true
extensionProviders:
- envoyOtelAls:
port: 4317
service: opentelemetry-collector.istio-system.svc.cluster.local
name: otel
- name: "acp-authorizer"
envoyExtAuthzGrpc:
service: "istio-authorizer.acp-istio-authorizer.svc.cluster.local"
port: 9001
[...]