diff --git a/src/app_charts/base/cloud/istio.yaml b/src/app_charts/base/cloud/istio.yaml index b295c515..1f4c167a 100644 --- a/src/app_charts/base/cloud/istio.yaml +++ b/src/app_charts/base/cloud/istio.yaml @@ -5,7 +5,7 @@ metadata: name: crc-gateway annotations: # Use standard K8s annotations for cloud-specific LB settings - networking.istio.io/service-type: LoadBalancer + networking.istio.io/service-type: LoadBalancer networking.istio.io/service-externalTrafficPolicy: Local spec: gatewayClassName: istio # Provisions Istio-managed LB infrastructure @@ -47,4 +47,103 @@ spec: requestRedirect: scheme: https statusCode: 301 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: crc-auth-gateway + annotations: + networking.istio.io/service-type: ClusterIP # only require internal cluster ip +spec: + gatewayClassName: istio # Provisions Istio-managed LB + listeners: + - name: http + hostname: {{ .Values.domain }} + protocol: HTTP + port: 8080 + allowedRoutes: + namespaces: + from: All +--- +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: crc-gateway-auth +spec: + targetRefs: # assoc this global auth policy on external crc-gateway + - kind: Gateway + group: gateway.networking.k8s.io + name: crc-gateway + action: CUSTOM + provider: + name: "crc-auth-gateway" # Must match name in meshConfig.extensionProviders exactly. + rules: + # targeting all paths. + # it is also possible to specify the relevant paths here, so that not all requests will be daisy-chained + - {} +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: crc-auth-catchall +spec: + parentRefs: + - name: crc-auth-gateway + namespace: default + sectionName: http + hostnames: + - {{ .Values.domain }} + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - name: explicit-allow-svc + namespace: default + port: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: explicit-allow-svc + labels: + app: explicit-allow-svc +spec: + replicas: 1 + selector: + matchLabels: + app: explicit-allow-svc + template: + metadata: + labels: + app: explicit-allow-svc + spec: + containers: + - name: nginx + image: nginxinc/nginx-unprivileged:1.30.1-alpine + ports: + - containerPort: 8080 + command: ["/bin/sh", "-c"] + args: + - | + echo 'server { + listen 8080; + location / { + add_header Content-Type text/plain; + return 200 "OK\n"; + } + }' > /etc/nginx/conf.d/default.conf && nginx -g 'daemon off;' +--- +apiVersion: v1 +kind: Service +metadata: + name: explicit-allow-svc +spec: + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + app: explicit-allow-svc {{- end}} diff --git a/src/app_charts/token-vendor/cloud/http-route.yaml b/src/app_charts/token-vendor/cloud/http-route.yaml index 78b52dec..0977d235 100644 --- a/src/app_charts/token-vendor/cloud/http-route.yaml +++ b/src/app_charts/token-vendor/cloud/http-route.yaml @@ -70,3 +70,62 @@ spec: - path: type: PathPrefix value: /apis/core.token-vendor/v1/token.oauth2 +--- +# NOTE: ReferenceGrant not needed if we deploy this HTTPRoutes +# in the same namespace as the token-vendor service (backendRef) +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: public-key-access-auth +spec: + hostnames: + - {{ .Values.domain }} + parentRefs: + - name: crc-auth-gateway + namespace: default + sectionName: http + rules: + - matches: + - path: + type: PathPrefix + value: /apis/core.token-vendor/v1/public-key.read + filters: + - type: URLRewrite + urlRewrite: + path: + type: ReplaceFullPath + replaceFullPath: /apis/core.token-vendor/v1/token.verify?robots=true + backendRefs: + - name: token-vendor + namespace: app-token-vendor + port: 80 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: public-key-manager-auth +spec: + hostnames: + - {{ .Values.domain }} + parentRefs: + - name: crc-auth-gateway + namespace: default + sectionName: http + rules: + - matches: + - path: + type: PathPrefix + value: /apis/core.token-vendor/v1/public-key.configure + - path: + type: PathPrefix + value: /apis/core.token-vendor/v1/public-key.publish + filters: + - type: URLRewrite + urlRewrite: + path: + type: ReplaceFullPath + replaceFullPath: /apis/core.token-vendor/v1/token.verify?robots=false + backendRefs: + - name: token-vendor + namespace: app-token-vendor + port: 80 diff --git a/third_party/istio/istio_operator.yaml b/third_party/istio/istio_operator.yaml index 17a6a33a..833383df 100644 --- a/third_party/istio/istio_operator.yaml +++ b/third_party/istio/istio_operator.yaml @@ -28,6 +28,18 @@ spec: accessLogFormat: | {"authority": "%REQ(:AUTHORITY)%", "start_time": "%START_TIME%", "bytes_received": "%BYTES_RECEIVED%", "bytes_sent": "%BYTES_SENT%", "downstream_local_address": "%DOWNSTREAM_LOCAL_ADDRESS%", "downstream_remote_address": "%DOWNSTREAM_REMOTE_ADDRESS%", "duration": "%DURATION%", "istio_policy_status": "%DYNAMIC_METADATA(istio.mixer:status)%", "method": "%REQ(:METHOD)%", "path": "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%", "protocol": "%PROTOCOL%", "request_id": "%REQ(X-REQUEST-ID)%", "requested_server_name": "%REQUESTED_SERVER_NAME%", "response_code": "%RESPONSE_CODE%", "response_flags": "%RESPONSE_FLAGS%", "route_name": "%ROUTE_NAME%", "start_time": "%START_TIME%", "upstream_cluster": "%UPSTREAM_CLUSTER%", "upstream_host": "%UPSTREAM_HOST%", "upstream_local_address": "%UPSTREAM_LOCAL_ADDRESS%", "upstream_service_time": "%RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)%", "upstream_transport_failure_reason": "%UPSTREAM_TRANSPORT_FAILURE_REASON%", "user_agent": "%REQ(USER-AGENT)%", "x_forwarded_for": "%REQ(X-FORWARDED-FOR)%", "x_icon_instance_name": "%REQ(x-icon-instance-name)%", "x_resource_instance_name": "%REQ(x-resource-instance-name)%"} + extensionProviders: + - name: "crc-auth-gateway" + envoyExtAuthzHttp: + service: "crc-auth-gateway-istio.default.svc.cluster.local" # crc-auth-gateway-istio k8s svc in default namespace + port: "8080" + includeRequestHeadersInCheck: + - "authorization" + - "x-forwarded-access-token" + - "x-auth-url" + headersToUpstreamOnAllow: + - "authorization" + components: base: enabled: true