Configure consul connect with OPA as an authorization service

Hi,

Envoy (v1.7.0+) supports an External Authorization filter which calls an authorization service to check if the incoming request is authorized or not and I can use OPA as an authorization service to enforce security policies over API requests received by Envoy.
In order to do this though I need to configure something similar to what I can do for Istio opa-envoy-plugin/quick_start.yaml at 2977de0ddbfc2b068c23fe4f9aae494b1c7c2113 · open-policy-agent/opa-envoy-plugin · GitHub

I was looking for ways to configure Envoy’s external_authz filter and hook in OPA through that but found nothing relevant.
Do you guys know if this is possible?

Thanks,
Bogdan

Hey Bogdan,

Just checking to see if you were able to make this work.

Hi, I didn’t had time yet to work on it. In 2 weeks I will get back and try to implement this: Connect - Envoy Integration | Consul by HashiCorp

I know it is experimental but I will test it to see if it works and also if it can be production ready.

Pretty interested in this too. It would seem that that is not possible at the moment? I’m following the getting started guide for consul connect and nomad. Here’s the HCL file I’m using:

job "countdash" {
  datacenters = ["dc1"]

  group "api" {
    network {
      mode = "bridge"
    }

    service {
      name = "count-api"
      port = "9001"

      connect {
        sidecar_service {  
        }
      }

      check {
        expose   = true
        type     = "http"
        name     = "api-health"
        path     = "/health"
        interval = "10s"
        timeout  = "3s"
      }
    }

    task "web" {
      driver = "docker"

      config {
        image = "hashicorpdev/counter-api:latest"
        auth_soft_fail = true
      }
    }
  }

  group "dashboard" {
    network {
      mode = "bridge"

      port "http" {
        static = 9002
        to     = 9002
      }
    }

    service {
      name = "count-dashboard"
      port = "http"

      connect {
        sidecar_service {
          proxy {
            upstreams {
              destination_name = "count-api"
              local_bind_port  = 8080
            }
          }
        }
      }
    }

    task "dashboard" {
      driver = "docker"

      env {
        COUNTING_SERVICE_URL = "http://${NOMAD_UPSTREAM_ADDR_count_api}"
      }

      config {
        image = "hashicorpdev/counter-dashboard:latest"
      }
    }
  }
}

By the way, the generated envoy config for the dashboard sidecar looks like this:

{
  "admin": {
    "access_log_path": "/dev/null",
    "address": {
      "socket_address": {
        "address": "127.0.0.2",
        "port_value": 19001
      }
    }
  },
  "node": {
    "cluster": "count-api",
    "id": "_nomad-task-1e27c4e6-cb81-3d0a-e8dd-7acf5ef6b768-group-api-count-api-9001-sidecar-proxy",
    "metadata": {
      "namespace": "default",
      "partition": "default"
    }
  },
  "layered_runtime": {
    "layers": [
      {
        "name": "base",
        "static_layer": {
          "re2.max_program_size.error_level": 1048576
        }
      }
    ]
  },
  "static_resources": {
    "clusters": [
      {
        "name": "local_agent",
        "ignore_health_on_host_removal": false,
        "connect_timeout": "1s",
        "type": "STATIC",
        "http2_protocol_options": {},
        "loadAssignment": {
          "clusterName": "local_agent",
          "endpoints": [
            {
              "lbEndpoints": [
                {
                  "endpoint": {
                    "address": {
                      "pipe": {
                        "path": "alloc/tmp/consul_grpc.sock"
                      }
                    }
                  }
                }
              ]
            }
          ]
        }
      }
    ]
  },
  "stats_config": {
  .... removed stats stuff here
  },
  "dynamic_resources": {
    "lds_config": {
      "ads": {},
      "resource_api_version": "V3"
    },
    "cds_config": {
      "ads": {},
      "resource_api_version": "V3"
    },
    "ads_config": {
      "api_type": "DELTA_GRPC",
      "transport_api_version": "V3",
      "grpc_services": {
        "initial_metadata": [
          {
            "key": "x-consul-token",
            "value": ""
          }
        ],
        "envoy_grpc": {
          "cluster_name": "local_agent"
        }
      }
    }
  }
}

I do not know how to ingegrate GitHub - open-policy-agent/opa-envoy-plugin: A plugin to enforce OPA policies with Envoy into this flow. What would be needed would be to inject this into the sidecar config somehow:

    filter_chains:
    - filters:
          http_filters:
          - name: envoy.ext_authz
            typed_config:
              "@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
              status_on_error:
                code: BadRequest
              transport_api_version: V3
              with_request_body:
                max_request_bytes: 8192
                allow_partial_message: true
              failure_mode_allow: false
              grpc_service:
                google_grpc:
                  target_uri: opa:8183
                  stat_prefix: ext_authz
                timeout: 0.5s

I can’t seem to find a way to do that. The link provided by @bmihaescu wouldn’t really work consul provides us to override the config does not allow us to inject filters that way.

If anyone has any pointers, it would be greatly appreciated