<p>I have an nginx-ingress calling a custom <code>auth-service</code> before sending requests to the backend service, using this simple ConfigMap and Ingress:</p>
<pre><code>apiVersion: v1
kind: ConfigMap
metadata:
  ...
data:
  global-auth-url: auth-service-url:8080/authenticate
  global-auth-method: GET
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: &quot;nginx&quot;
  ...
spec:
  rules:
  - host: host1
    http:
      paths:
      - backend:
          serviceName: backend-service
          servicePort: 8080 
</code></pre>
<p>Now I need something different.</p>
<p>How can I send requests, all with the same &quot;Host&quot; header, through different flows, one with auth-service and connected to <code>backend-service1</code> and the other without any authentication and connecting to <code>backend-service2</code>?</p>
<p>To be clear, and using the custom header &quot;Example-header: test&quot;</p>
<ol>
<li>If &quot;Example-header&quot; is &quot;test&quot;, authenticate via my <code>auth-service</code> before sending to <code>backend-service</code>, as it's done now.</li>
<li>If &quot;Example-header&quot; is not defined, I want to send requests to a different backend service and do not use <code>auth-service</code> in the process.</li>
</ol>
<p>I tried a couple of things, namely having 2 Ingresses, one with <code>global-auth-url</code> and the other with <code>nginx.ingress.kubernetes.io/enable-global-auth: &quot;false&quot;</code> but the auth-service is always called.</p>
<p>Can I do this with NGINX, or do I have to use Istio or Ambassador?</p>

<p>One way you can achieve this behavior is by abusing the <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary" rel="noreferrer">canary feature</a>.</p>
<p>For your <code>backend-service</code>, create a normal Ingress, e. g.</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-backend
spec:
  ingressClassName: nginx
  rules:
  - host: localhost
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: backend-service
            port:
              number: 80
</code></pre>
<p>Create a second Ingress for you <code>auth-service</code> with enabled canary and set the header name and value, e. g.</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: ingress-auth
  annotations:
    nginx.ingress.kubernetes.io/canary: &quot;true&quot;
    nginx.ingress.kubernetes.io/canary-by-header: Example-header
    nginx.ingress.kubernetes.io/canary-by-header-value: test
spec:
  ingressClassName: nginx
  rules:
  - host: localhost
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: auth-service
            port:
              number: 80
</code></pre>
<p>Now, every request with <code>Example-header: test</code> routes to <code>auth-service</code>. Any other value, e. g. <code>Example-header: some-value</code>, will <strong>not</strong> route to <code>auth-service</code> but rather go to your <code>backend-service</code>.</p>
