<p>I know I can whitelist IPs for the entire ingress object, but is there a way to whitelist IPs for individual paths?  For example, if I only want to allow <code>/admin</code> to be accessed from <code>10.0.0.0/16</code>?</p>

<p><code>ingress.yml</code>:</p>

<pre><code>---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: frontend
  namespace: default
  labels:
    app: frontend
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    #nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/16"
spec:
  tls:
    - hosts:
        - frontend.example.com
      secretName: frontend-tls
  rules:
    - host: frontend.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: frontend
              servicePort: 80
          - path: /api
            backend:
              serviceName: api
              servicePort: 8000
          - path: /admin
            backend:
              serviceName: api
              servicePort: 8000
          - path: /staticfiles
            backend:
              serviceName: api
              servicePort: 80
</code></pre>

cclloyd
<p>If you would like to split it two Ingres, it would look like example below. First <code>Ingress</code> with <code>/admin</code> path and annotation and second <code>Ingress</code> with others <code>paths</code> allowed by any <code>IP</code>.</p>

<pre><code>apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: frontend-admin
  namespace: default
  labels:
    app: frontend
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/16"
spec:
  tls:
    - hosts:
        - frontend.example.com
      secretName: frontend-tls
  rules:
    - host: frontend.example.com
      http:
        paths:
          - path: /admin
            backend:
              serviceName: api
              servicePort: 8000
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: frontend-all
  namespace: default
  labels:
    app: frontend
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  tls:
    - hosts:
        - frontend.example.com
      secretName: frontend-tls
  rules:
    - host: frontend.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: frontend
              servicePort: 80
          - path: /api
            backend:
              serviceName: api
              servicePort: 8000
          - path: /staticfiles
            backend:
              serviceName: api
              servicePort: 80
</code></pre>

<p>Please keep in mind that annotation <code>nginx.ingress.kubernetes.io/whitelist-source-range: "10.0.0.0/16"</code> will override some of your config. As mentioned in <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#whitelist-source-range" rel="noreferrer">Nginx docs</a>:</p>

<blockquote>
  <p>Adding an annotation to an Ingress rule overrides any global restriction.</p>
</blockquote>

<p><br>
Another option is to use <code>ConfigMap</code> <a href="https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#whitelist-source-range" rel="noreferrer">whitelist-source-range</a>. Like mentioned in <a href="http://nginx.org/en/docs/http/ngx_http_access_module.html" rel="noreferrer">this example</a>, you can use <code>ngx_http_access_module</code>.</p>

<p>As in Nginx config, each <code>path</code> is saved as</p>

<pre><code>location / {
  ...
}

location /api {
  ...
}
</code></pre>

<p>you can add thoses restrictions there. Below example:</p>

<pre><code>location / {
    deny  192.168.1.1;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;
    deny  all;
}
</code></pre>
