AuthorizationPolicy for IPs + Keycloak on cookies

Hello there!
I want to achieve the following:
on a staging K8s cluster with Istio, we’d like to allow access

  • either to certain IPs
  • or if the IP is not whitelisted we want to login on Keycloak, if login is fine then authorize.

The Policies should run against hosts and not paths as we have multiple apps in there.
I was thinking that having

  • an ALLOW AuthorizationPolicy fot the IPs
  • a CUSTOM AuthorizationPolicy with Oauth2-proxy in the middle calling Keycloak

The issues are:

Which is not what I want:
I want ttat the IP policy (ALLOW) is verified first and if this pass then allow the request directly
Only if the IP policy Denies then go through KeyCloak.

So I came up with the AuthorizationPolicy below

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: oauth2-proxy-authorization-policy
  namespace: istio-system
spec:
  selector:
    matchLabels:
      app: istio-ingressgateway
  action: CUSTOM
  provider:
    name: oauth2-proxy
  rules:
    - from:
        - source:
            notRemoteIpBlocks: [ "1.2.3.4" ]
    - to:
        - operation:
            hosts: [ "app1.example.com" ]

The above from and to rules work independently, and not in a cascade

What do I mean:

  • If I remove the to section (but leave the from) and I am IP 1.2.3.4 then I am able to access without going through Keycloak
  • If I remove the to section (but leave the from) and I am NOT IP 1.2.3.4 all my apps will redirect to auth (and auth will enter an infinite redirect loop) but this is kinda expected
  • If I remove the from part (but leave the to) and I visit app1.example.com then I am able to see the auth page
  • If I remove the from part (but leave the to) and I visit app2.example.com then I don’t see the auth page

The 4 rules above work as expected.

But when I have both from and to all my apps will redirect to auth and auth will start an infinite redirect loop

So looks like from and to works more like an OR and not like an AND

Did anybody had such task before?
Can you give me any hint on how to achieve my goal?

Update:
I also tried the following without success:

  rules:
    - to:
        - operation:
            hosts: [ "app1.example.com" ]
    - when:
      - key: remote.ip
        notValues: [ "1.2.3.4" ]

Looks like I was lucky with

  rules:
    - when:
      - key: remote.ip
        notValues: [ "1.2.3.4" ]
      - key: request.headers[Host]
        values: [ "app1.example.com" ]

now it works, still… I’m questioning myself why the from to combination doesn’t apply as in documentation I’m using Istio v1.11.5 BTW.