reverse-proxy icon indicating copy to clipboard operation
reverse-proxy copied to clipboard

Http Method Match in K8S Controller

Open adityamandaleeka opened this issue 3 years ago • 4 comments

Discussed in https://github.com/microsoft/reverse-proxy/discussions/1825

Originally posted by pinkfloydx33 August 13, 2022 I have a proxied endpoint that requires authorization based on the Http Method. For POST, the endpoint accepts anonymous requests; for everything else it requires authorization. It's something akin to a user endpoint where POST represents signing up to an application.

I can easily codify this in configuration-based routes using the route.Match.Methods property, plus either a higher priority Order for the POST endpoint or spelling out the remaining HTTP methods on the other. However, this doesn't seem possible to do when using the Ingress controller as it does not have an http-methods annotation.

If such an annotation were supported, this would require creating two Ingress resources with the same path and host. So far as I am aware, this is technically a valid thing to do per K8S. The Ingress Controller should be able to support such a case since it uses the Ingress name to construct the route's, so there'd be no conflict.

Is this something that could in theory be supported, or was it explicitly not considered? Or am I overlooking something that would prevent it?

adityamandaleeka avatar Aug 16 '22 18:08 adityamandaleeka

Transferred from discussions. Thanks @pinkfloydx33 for the suggestion.

adityamandaleeka avatar Aug 16 '22 18:08 adityamandaleeka

The Kubernetes Ingress resource doesn't have a concept of "HTTP Method", so AFAIK configuring two resources with the same host and path would be invalid.

I even looked at the newer Kubernetes Gateway API and that has the same limitation relating to HTTP methods.

Are you attempting to route a POST request to one backend and non-POST requests to another? Or are you trying to enforce auth at the ingress controller?

dpbevin avatar Aug 28 '22 01:08 dpbevin

Auth at the ingress controller. In our case YARP is acting as an API gateway and does authorization there.

K8s doesn't have a concept of HTTP method, you are correct. But that doesn't matter. It does support two Ingress resources with the same hosts and path. In what I am proposing, HTTP methods would be codified in the metadata.annotations with all the other YARP route configuration.

In my use case I would create three Ingress resources:

  • The first would have all my "normal" routes indicated by a series of paths (or a single path with a regex route pattern). Auth metadata via annotations would indicate I want YARP to use some authorization policy
  • The second Ingress would have a single path, authorization annotation and a hypothetical HTTP method annotation with a value of "get/put/delete/patch"
    • or a hypothetical Order annotation and no HTTP methods
  • The third Ingress would have a single path (the same one from the second bullet), no authorization annotation, and a hypothetical HTTP method annotation for "post"
    • and Order annotation if one were available and bullet two only used that

I could likely get this down to two Ingress resources with a bit of thinking. In any case, it's the second and third bullets that are of note. As far as K8S is concerned they'd have the same host, path and ingressClass which is a supported scenario. As different resources they'd have to have different names; the YARP ingress controller would treat them as distinct routes, as it should. Without any annotations/metadata this would be an issue as there would be two YARP routes with the exact same match configuration. If HTTP methods was a supported annotation this would work just fine as the two routes created on the YARP end would have different set of match criteria.

This is a supported scenario with Ingress resources managed by ingress-nginx (via metadata.annotations) as well as with Istio's VirtualService (via spec.http.match.method) and I'm sure others. I know the goal isn't parity, but figured I'd call these cases out.

I'm posting from my cell, but I can provide hypothetical Ingress examples later.

pinkfloydx33 avatar Aug 28 '22 11:08 pinkfloydx33