Currently we're using an EnvoyFilter to add an authentication check. This filter makes use of the envoy ext_authz
filter.
We have a GraphQL endpoint that is used for both anonymus and authorised calls. Since the public calls don't need an auth check/filter I would like to be able to skip this filter based on a cookie. I tried searching for a solution online but wasn't able to find one.
See the configuration for the filter below:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: oathkeeper
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.ext_authz
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthz
failure_mode_allow: false
http_service:
path_prefix: /decisions
server_uri:
uri: http://oathkeeper-api.default.svc.cluster.local:4456
cluster: outbound|4456||oathkeeper-api.default.svc.cluster.local
timeout: 10s
authorization_request:
allowed_headers:
patterns:
- exact: accept
- exact: authorization
- exact: cookie
- exact: content-type
- exact: x-forwarded-for
- exact: x-forwarded-proto
- exact: x-forwarded-host
authorization_response:
allowed_upstream_headers:
patterns:
- exact: authorization
You could configure a second VirtualService
route for the endpoint that matches on missing cookie
[...]
http:
- name: secured-graph-ql-endpoint
match:
- headers:
cookie:
regex: <some-regex>
uri:
prefix: /graph-ql-endpoint
route:
- destination:
host: graph-ql-endpoint
port:
number: 8000
- name: public-graph-ql-endpoint
match:
- uri:
prefix: /graph-ql-endpoint
route:
- destination:
host: graph-ql-endpoint
port:
number: 8000
with a regex (<some-regex>
) depending on your cookie. You could also have a header like authenticated: true
and match on that, instead of a (missing) cookie.
Create an EnvoyFilter
to disable the ExtAuthz
for that route.
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: bypass-ext-authz
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: HTTP_ROUTE
match:
routeConfiguration:
vhost:
route:
#from virtual service http route name
name: public-graph-ql-endpoint
patch:
operation: MERGE
value:
name: custom.bypass_extauthz
typed_per_filter_config:
envoy.ext_authz:
"@type": type.googleapis.com/envoy.extensions.filters.http.ext_authz.v3.ExtAuthzPerRoute
disabled: true
You could also add the configPatch
to your existing EnvoyFilter
.
Having said that:
From a design/security perspective I would rather have a different application that is publicly exposed and that queries the secured GraphQL endpoint for the anonymous user. That gives you much more control over traffic like rate limiting for external user, easier dos protection, etc.