I am trying to setup a OAuth2 EnvoyFilter. I am using Istio 1.11.4 on gke 1.22.1 following this blog post: OAuth2-based authentication on Istio-powered Kubernetes clusters – Mariusz Strzelecki – Data Engineer - Toruń, Poland
When I access a protected url I am getting this error:
Jwt is not in the form of Header.Payload.Signature with two dots and 3 sections
This is the related config:
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
name: istio-controlplane
labels:
{{- include "istio-system.labels" . | nindent 4 }}
spec:
profile: default
meshConfig:
enableTracing: true
accessLogFile: /dev/stdout
accessLogEncoding: TEXT
accessLogFormat: |
traceID=%REQ(x-b3-traceid)% protocol=%PROTOCOL% upstream_service_time=%RESP(x-envoy-upstream-service-time)% upstream_local_address=%UPSTREAM_LOCAL_ADDRESS% duration=%DURATION% upstream_transport_failure_reason=%UPSTREAM_TRANSPORT_FAILURE_REASON% route_name=%ROUTE_NAME% downstream_local_address=%DOWNSTREAM_LOCAL_ADDRESS% user_agent=%REQ(USER-AGENT)% response_code=%RESPONSE_CODE% response_flags=%RESPONSE_FLAGS% start_time=%START_TIME% method=%REQ(:METHOD)% request_id=%REQ(X-REQUEST-ID)% upstream_host=%UPSTREAM_HOST% x_forwarded_for=%REQ(X-FORWARDED-FOR)% requested_server_name=%REQUESTED_SERVER_NAME% bytes_received=%BYTES_RECEIVED% istio_policy_status=- bytes_sent=%BYTES_SENT% upstream_cluster=%UPSTREAM_CLUSTER% downstream_remote_address=%DOWNSTREAM_REMOTE_ADDRESS% authority=%REQ(:AUTHORITY)% path=%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%"}
defaultConfig:
tracing:
sampling: 100
zipkin:
address: {{ .Values.tracing }}
components:
# Istio Gateway feature
egressGateways:
- name: istio-egressgateway
enabled: true
ingressGateways:
- name: istio-ingressgateway
enabled: false
- name: istio-private-ingressgateway
enabled: true
k8s:
serviceAnnotations:
cloud.google.com/load-balancer-type: "Internal"
external-dns.alpha.kubernetes.io/hostname: "{{ index .Values.domains.private 0 }}"
external-dns.alpha.kubernetes.io/ttl: "60"
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-private-ingressgateway
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
overlays:
- kind: HorizontalPodAutoscaler
name: istio-private-ingressgateway
patches:
- path: metadata.labels.app
value: istio-private-ingressgateway
- path: metadata.labels.version
value: v1
- path: spec.scaleTargetRef.name
value: istio-private-ingressgateway
- kind: Deployment
name: istio-private-ingressgateway
patches:
- path: metadata.labels.app
value: istio-private-ingressgateway
- path: metadata.labels.version
value: v1
- path: spec.selector.matchLabels.app
value: istio-private-ingressgateway
- path: spec.template.metadata.labels.app
value: istio-private-ingressgateway
- kind: Service
name: istio-private-ingressgateway
patches:
- path: metadata.labels.app
value: istio-private-ingressgateway
- path: metadata.labels.version
value: v1
- path: spec.selector.app
value: istio-private-ingressgateway
- name: istio-public-ingressgateway
enabled: true
k8s:
serviceAnnotations:
external-dns.alpha.kubernetes.io/hostname: "{{ index .Values.domains.public 0 }}"
external-dns.alpha.kubernetes.io/ttl: "60"
hpaSpec:
maxReplicas: 5
metrics:
- resource:
name: cpu
targetAverageUtilization: 80
type: Resource
minReplicas: 1
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: istio-public-ingressgateway
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 100m
memory: 128Mi
strategy:
rollingUpdate:
maxSurge: 100%
maxUnavailable: 25%
overlays:
- kind: HorizontalPodAutoscaler
name: istio-public-ingressgateway
patches:
- path: metadata.labels.app
value: istio-public-ingressgateway
- path: metadata.labels.version
value: v1
- path: spec.scaleTargetRef.name
value: istio-public-ingressgateway
- kind: Deployment
name: istio-public-ingressgateway
patches:
- path: metadata.labels.app
value: istio-public-ingressgateway
- path: metadata.labels.version
value: v1
- path: spec.selector.matchLabels.app
value: istio-public-ingressgateway
- path: spec.template.metadata.labels.app
value: istio-public-ingressgateway
- path: spec.template.metadata.labels.version
value: v1
- path: spec.template.spec.containers.[name:istio-proxy].volumeMounts[9]
value:
name: oauth2-ingress
mountPath: /etc/oauth2-ingress
- path: spec.template.spec.volumes[9]
value:
name: oauth2-ingress
configMap:
name: oauth2-ingress
- kind: Service
name: istio-public-ingressgateway
patches:
- path: metadata.labels.app
value: istio-public-ingressgateway
- path: metadata.labels.version
value: v1
- path: spec.selector.app
value: istio-public-ingressgateway
values:
global:
tracer:
zipkin:
address: {{ .Values.tracing }}
gateways:
istio-ingressgateway:
injectionTemplate: gateway
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: oauth2-ingress
labels:
{{- include "istio-system.labels" . | nindent 4 }}
spec:
workloadSelector:
labels:
app: istio-public-ingressgateway
configPatches:
- applyTo: CLUSTER
match:
cluster:
service: oauth
patch:
operation: ADD
value:
name: oauth
dns_lookup_family: V4_ONLY
type: LOGICAL_DNS
connect_timeout: 10s
lb_policy: ROUND_ROBIN
transport_socket:
name: envoy.transport_sockets.tls
typed_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
sni: oauth2.googleapis.com
load_assignment:
cluster_name: oauth
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: oauth2.googleapis.com
port_value: 443
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
subFilter:
name: "envoy.filters.http.jwt_authn"
patch:
operation: INSERT_BEFORE
value:
name: envoy.filters.http.oauth2
typed_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.oauth2.v3alpha.OAuth2
config:
token_endpoint:
cluster: oauth
uri: https://oauth2.googleapis.com/token
timeout: 3s
authorization_endpoint: https://accounts.google.com/o/oauth2/v2/auth
redirect_uri: "https://%REQ(:authority)%/oauth2/callback"
redirect_path_matcher:
path:
exact: /oauth2/callback
signout_path:
path:
exact: /logout
credentials:
client_id: xxx
token_secret:
name: token
sds_config:
path: "/etc/oauth2-ingress/token-secret.yaml"
hmac_secret:
name: hmac
sds_config:
path: "/etc/oauth2-ingress/hmac-secret.yaml"
forward_bearer_token: true
auth_scopes:
- profile
- openid
- email
---
apiVersion: v1
kind: ConfigMap
metadata:
name: oauth2-ingress
labels:
{{- include "istio-system.labels" . | nindent 4 }}
data:
token-secret.yaml: |-
resources:
- "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
name: token
generic_secret:
secret:
inline_string: "xxx"
hmac-secret.yaml: |-
resources:
- "@type": "type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.Secret"
name: hmac
generic_secret:
secret:
inline_bytes: "xxx"
---
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
name: oauth2-ingress
labels:
{{- include "istio-system.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
app: istio-public-ingressgateway
jwtRules:
- issuer: "https://accounts.google.com"
jwksUri: "https://www.googleapis.com/oauth2/v3/certs"
---
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: oauth2-ingress
labels:
{{- include "istio-system.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
app: istio-public-ingressgateway
action: ALLOW
rules:
- from:
- source:
requestPrincipals: ["*"]
Any idea how to debug this is appreciated.