Apigee Envoy Adapter third party JWT integration

Hey, I'm starting an PoC based on Apigee Envoy Adapter as internal gateway.
(I'm totally new on it)

I have an Auth0 tenant and I'm trying to integrate it with Apigee Envoy Adapter and use the JWT tokens issued by it to authenticate the API Calls targeting my backend.

My envoy config file is defined as follows:

 

# Copyright 2020 Google LLC
# 
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
# 
#       http://www.apache.org/licenses/LICENSE-2.0
# 
#  Unless required by applicable law or agreed to in writing, software
#  distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

# This is for Envoy 1.16+.

admin:
  access_log_path: /tmp/envoy_admin.log
  address:
    socket_address:
      address: 127.0.0.1
      port_value: 9000

static_resources:
  listeners:
  - address:
      socket_address: { address: 0.0.0.0, port_value: 8080 }

    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:  
          "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
          stat_prefix: ingress_http
          route_config:
            virtual_hosts:
            - name: default
              domains: "*"
              routes:
              - match: { prefix: / }
                route:
                  cluster: httpbin

          http_filters:

          # evaluate JWT tokens, allow_missing allows API Key also
          - name: envoy.filters.http.jwt_authn
            typed_config: 
              "@type": type.googleapis.com/envoy.extensions.filters.http.jwt_authn.v3.JwtAuthentication
              providers:
                auth0:
                  issuer: https://dev-y8zk4.us.auth0.com/
                  audiences:
                  - remote-service-client
                  remote_jwks:
                    http_uri:
                      uri: https://dev-y8zk4.us.auth0.com/.well-known/jwks.json
                      cluster: apigee-auth-service
                      timeout: 5s
                    cache_duration:
                      seconds: 300
                  payload_in_metadata: https://dev-y8zk4.us.auth0.com
              rules:
              - match:
                  prefix: /
                requires:
#                  provider_name: auth0
                  requires_any:
                    requirements:
                    - provider_name: auth0
                    - allow_missing: {}

          # evaluate Apigee rules
          - name: envoy.filters.http.ext_authz
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
              transport_api_version: V3
              grpc_service:
                envoy_grpc:
                  cluster_name: apigee-remote-service-envoy
                timeout: 1s
              metadata_context_namespaces:
              - envoy.filters.http.jwt_authn

          - name: envoy.filters.http.router
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

          access_log: 

          # collect Apigee analytics
          - name: envoy.access_loggers.http_grpc
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.access_loggers.grpc.v3.HttpGrpcAccessLogConfig
              common_config:
                transport_api_version: V3
                grpc_service:
                  envoy_grpc:
                    cluster_name: apigee-remote-service-envoy
                log_name: apigee-remote-service-envoy

  clusters:

  # define cluster for httpbin.org target
  - name: httpbin
    connect_timeout: 2s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: httpbin
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: "httpbin.org"
                port_value: 443
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        sni: "httpbin.org"

  # define cluster for Apigee remote service
  - name: apigee-remote-service-envoy
    type: LOGICAL_DNS
    http2_protocol_options: {}
    load_assignment:
      cluster_name: apigee-remote-service-envoy
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: "localhost"
                port_value: 5000
    common_lb_config:
      healthy_panic_threshold:
        value: 50.0
    health_checks:
      - timeout: 1s
        interval: 5s
        interval_jitter: 1s
        no_traffic_interval: 5s
        unhealthy_threshold: 1
        healthy_threshold: 3
        grpc_health_check: {}
    connect_timeout: 0.25s

  # define cluster for Apigee JWKS certs
  - name: apigee-auth-service
    connect_timeout: 2s
    type: LOGICAL_DNS
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: apigee-auth-service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: "dev-y8zk4.us.auth0.com"
                port_value: "443"
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        "@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
#        sni: "dev-y8zk4.us.auth0.com"

 

The apigee remote service config file is as follows:

 

# Configuration for apigee-remote-service-envoy (platform: GCP)
# generated by apigee-remote-service-cli provision on 2022-10-26 15:50:10
apiVersion: v1
kind: ConfigMap
metadata:
  name: apigee-remote-service-envoy
  namespace: apigee
data:
  config.yaml: |
    tenant:
      remote_service_api: https://34.102.185.252.nip.io/remote-service
      org_name: apigeex-poc
      env_name: eval
    analytics:
      collection_interval: 10s
    auth:
      jwt_provider_key: https://dev-y8zk4.us.auth0.com/
      append_metadata_headers: true
---
apiVersion: v1
kind: Secret
metadata:
  name: apigeex-poc-eval-policy-secret
  namespace: apigee
type: Opaque
data:
  remote-service.crt: eyJrZXlzIjpbeyJhbGciOiJSUzI1NiIsImUiOiJBUUFCIiwia2lkIjoiMjAyMi0wOS0xMlQyMjoxNjo0M1oiLCJrdHkiOiJSU0EiLCJuIjoicmU5RXVZYndZdi16ZVZxc0stLVljUXUxcGtESnNheUxYLUpBY...
  remote-service.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBcmU5RXVZYndZdit6ZVZxc0srK1ljUXUxcGtESnNheUxYK0pBY0VYZ0RjYUlEYktlCktmSjAxeVgrcXVGcUdiTGdIZDh5LzlaWmpQbW9rcGhoTnBZSVY3d09xdXp3Myt4MFNKUjBuQlBUUlZGejBvZnEKMWE4bnlmNUIyQlVyTUVhSldCUS9TUG52aURWWlNvYytxZzkwaTNCcTc3VXhpUXRVZU04VGQ1U2t1ZExqLzhabQpNNHo4WWpGWGJ2TmtCT05hdm9pOUlHUSsycGh2ZW1VNmkvdWFwRHdueVNpaHRodHR1WGQ3d1lIckdEaWJQejJ3CldPSjVQdk1OWVUxdG1WNFVuZTdGOVJQOFVlZU12VmpNRCtLd0pBZHhudCtaa3hJUU1xRmpQd1VRUmIxWHEydGEKY0d4cXJkRURWTElHRmlHLzhwZW1YcDU4clY3MzVwMDN2ZGsybFFJREFRQUJBb0lCQVFDRkU1SERXT2pHOWRoOQpPdENMOVE3dlB3UkdKVCtyL3RYTUVMRTR0VjJOYko1ZnpJK1NqSHkwdDg4M01xd1k2WERycWYrOUdtVDlwVzVDCmF1L0Y4ZGlFTjlBSkdxdll4M0xZclN6aTFaQkpjdDVvNzdET3VPcDZjMXd4VlZEcjZLdmdoZTA5aW15b0RCazcKR21ycGRsVzI4ZFgvZk9SZmRCbTNMTWc2TDdJd3NWUWUzZlg5VVFLY29ydXFYSlZzMDRpSis2TmxEWkRQRjRnbApYajRlTXFWMEEvbi9jdU9WRnVPMGhQWml5eS9iek9ZbGJIWmYyOEVyb1FHQ1ZyMmRYbCthbW5Rc2FkUTltQjVWCjFDVjFaWGk5M09QeENGemNFRUg3cjJWc0pYUGlVbEN6V0FNcFF2OHVtbk9GNUdHNkdRRmdOdWZseHc2VHZnVS8KUFdkcFc0akJBb0dCQU9MUW5UbnRtS1RDdHlOZ2c3UnBMcWU3RjNtczZXeDByY21ZZ0tVZGFFUEtyQlZDb1pibwptT0xOS0ZXREhkRWZmSWs4Rm5sbEZRZGdjQU1laDBqVTh1M0E2NCtwMDZUeFVmalZvZHZOdzd1bU9sWUZrSEZLCm5BamZrcnB2UDZPZzBLbTlqT3BwM0pTOGxKRllNR1I5YXZ2SitmS3hwWEhkQ09YdHR4MWdHSU5aQW9HQkFNUlEKd1M0RFNCKzRNNWU5cFVPaFFYaXJsZ2xXTmN2VVBxWEdrNVVjOXg5NDQwLzMwR1NNSUdGWXp0QWEzbjlVeUcrbgozN3A5STh0Q2FsZ1ZERUNweEpYQ2tOV3U2U0xTL3lqc3ZHZXdRSVNWRGJRZStEdE4wTzA4VWc1OElOKzd5OUN3CmJQaHE3TXRkbzFJSXpRZjlj...
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    org: apigeex-poc
  name: apigee-remote-service-envoy
  namespace: apigee

 


I registered the API (remote-service-client) on my Auth0 tenant and got a token by curling the token endpoint of my tenant.

But when i curl the envoy on localhost:8080 passing the Authentication header with the token, it's returned the 403 Forbidden error. I validated the token on jwt.io debugger and it's correct and valid.

I don't know if I'm missing something in the envoy or apigee remote service configuration.

So the question is: Is it possible to use a third party IdP integrated with the Apigee Envoy Adapter so that it provides the JWT token and public certs to validate the signature?
If yes, how to correctly configure it on apigee remote service proxy so that it manage to authenticate and authorize the calls passing through it?

Solved Solved
0 3 492
1 ACCEPTED SOLUTION

Hey Bruno, 

Can you add 

api_key_claim: azp 
in config.yaml auth section?
 
You also need to update audience  from "-remote-service-client " to the actual 
 
This should allow you to successfully make a call via envoy adapter.

View solution in original post

3 REPLIES 3

Hey Bruno, 

Can you add 

api_key_claim: azp 
in config.yaml auth section?
 
You also need to update audience  from "-remote-service-client " to the actual 
 
This should allow you to successfully make a call via envoy adapter.

Hi @mtalreja, I added the api_key_claim: azp and it worked like a charm, even I keeping the audience as remote-service-client. Thank you for your help.

Could you tell me if this approach work with other third-party IdPs (for example: CA API Management or even Azure AD)?

Yes it should , who is provider is irrelevant, as long as they are supporting oAuth...