api icon indicating copy to clipboard operation
api copied to clipboard

Add support for specifying `targetRef` namespace on authorization policies

Open solidDoWant opened this issue 3 months ago • 11 comments

Describe the feature request

When using the k8s gateway API (with Istio as a gateway controller), I'd like to be able to store authorization policies alongside applications, alongside HTTPRoutes and similar application-specific resources.

Today, it looks like the only way to target application-specific resources with AuthorizationPolicies when using the gateway API is to target the entire gateway, and then use a rule to filter the policy based on hosts/paths/etc. that match the application's HTTPRoute. While not ideal, this should in theory work.

However, because the AuthorizationPolicy does not support targeting gateways in other namespaces, the policy must live in either the default namespace (so it'll match gateways in all namespaces), or the gateway's namespace. This means moving application-specific resources away from the application, and away from all other related ingress configuration.

I'd like to be able to specify the namespace for the referenced gateway within the authorization policy so that I can place the policy in application namespaces, instead of gateway namespaces. It looks like work was already started on this here, but never completed.

Describe alternatives you've considered

Store the resource in the gateway namespace

Affected product area (please put an X in all that apply)

[ ] Configuration Infrastructure [ ] Docs [ ] Installation [x] Networking [ ] Performance and Scalability [x] Policies and Telemetry [x] Security [ ] Test and Release [ ] User Experience

Additional context

solidDoWant avatar Sep 22 '25 23:09 solidDoWant

I don't want to be too dismissive but I don't think we would ever do this. To achieve the use case I would think an HTTPRoute attached policy would be more appropriate; we have actually discussed this but implementation is tricky

howardjohn avatar Sep 22 '25 23:09 howardjohn

That'd be great and would be my preferred solution as well. I just figured given that the CRD and protobuf already has a namespace as a part of targetRef that this was something that was previously planned but forgotten/deprioritized.

solidDoWant avatar Sep 23 '25 01:09 solidDoWant

Ran into another place where a lack of targetRef support gateway API route resources (e.g. HTTPRoute) support has a really nasty edge. Apparently only one provider can be referenced via all authorization policies attached to a "workload". When attaching multiple providers, the controller marks them as "accepted" via the resource status, but the istiod process fails with:

2025-09-29T02:42:10.607186Z error authorization Processed authorization policy: failed to process CUSTOM action, will generate deny configs for the specified rules: only 1 provider can be used per workload, found multiple providers: [my-idp-no-upstream-headers my-idp]

This is a problem because the provider config controls what headers are sent from the external authorizer to both the upstream and downstream. If an application requires different settings here (for example, it seems like apache tomcat gets upset with either too many headers or too large headers), then the application will need a different provider, and therefore also a different auth policy. Because the provider is technically different (they're backed by the same actual service but the headers are different), supporting today means that I need to deploy an entire additional gateway, use an additional LB service, public IP, DNS records, etc.

Let me know if this should be filed as a separate issue for tracking and I'll take care of it.

solidDoWant avatar Sep 29 '25 03:09 solidDoWant

As I understand it this also goes against the intent gateway API model, because it requires application-specific gateways (a "cluster operator" resources) rather than just routes (an "application developer" resource).

solidDoWant avatar Sep 29 '25 03:09 solidDoWant

@howardjohn RBAC, jwt authn, and ext authz all have per route configs. Is there something more fundamental blocking this?

keithmattix avatar Sep 29 '25 03:09 keithmattix

@keithmattix per-route is extremely tricky and not what it seems on the surface.

Consider this setup and the 'obvious' implementation Image.

The behavior I would expect, is that no matter what if Route2 is used for selecting a backend, pol3 is applied. This is not the case!

Envoy does not follow a linear request processing flow of applying each filter, then selecting routes, then applying each route filter. Instead, it ~guesses the route and starts applying the per-route rules. The filter can change the route selection, causing a different route to be selected, bypassing the policy.

howardjohn avatar Sep 29 '25 16:09 howardjohn

But the per-route rules are only used once the filter is executed right? As long as the route-changing filter comes after the policy's filter, the policy would be applied. So in your scenario, if we put the rbac/ext-authz/jwt filter before any request mutation filters, it would get executed. If traffic is denied, then we stop processing. If something later in the filter chain changes the route, the filter-chain gets executed again but with different per route config. So, IIUC, we could apply both policies

keithmattix avatar Sep 29 '25 17:09 keithmattix

That is not my understanding of how it works. If i have, for example, an ext-authz policy as those pol1/pol2/pol3, you can hit route2 without applying pol3 ext_authz

howardjohn avatar Sep 29 '25 17:09 howardjohn

Ah you're right; I misread a config dump and had ChatGPT explain it to me. So yeah any changes to the route would be effectively broken regardless of ordering. That really sounds like an Envoy problem

keithmattix avatar Sep 29 '25 18:09 keithmattix

Is this something that I should try to chase down upstream? I'm not very familiar with Envoy and most of this is over my head, so doing this myself may do more harm than good.

solidDoWant avatar Sep 29 '25 18:09 solidDoWant

Ran into yet another issue related to this today. Would appreciate any advice on how to proceed.

I've got several applications that I'd like to use a CUSTOM auth provider for, so I've deployed a pretty simple policy for them:

---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: my-idp-auth
spec:
  targetRef:
    kind: Gateway
    group: gateway.networking.k8s.io
    name: my-gateway
  action: CUSTOM
  provider:
    name: my-idp
  rules:
    - to:
        - operation:
            hosts:
              - app1.${SECRET_PUBLIC_DOMAIN_NAME}
              - app2.${SECRET_PUBLIC_DOMAIN_NAME}
              - appN.${SECRET_PUBLIC_DOMAIN_NAME}

This worked great until I added a C# app that uses SignalR, which sends CORS preflight requests. I then ran into this prematurely bot-closed issue, but for the external auth provider instead of an envoy filter. To work around this, it seems like I need to add the below policy to explicitly allow HTTP OPTIONS requests to bypass the auth requirement:

---
apiVersion: security.istio.io/v1
kind: AuthorizationPolicy
metadata:
  name: my-idp-auth-allow-options-requests
spec:
  targetRef:
    kind: Gateway
    group: gateway.networking.k8s.io
    name: my-gateway
  action: ALLOW
  rules:
    - to:
        - operation:
            hosts:
              - app1.${SECRET_PUBLIC_DOMAIN_NAME}
              - app2.${SECRET_PUBLIC_DOMAIN_NAME}
              - appN.${SECRET_PUBLIC_DOMAIN_NAME}
            methods:
              - OPTIONS

The problem is that I have several other applications attached to the same gateway that handle auth within the application. These should completely bypass the custom external auth provider, as they'll talk to the backing service (my IdP) directly. However, because the allow policy targets the gateway instead of individual HTTPRoute resources, this allow policy now blocks access to all of the other services!

I really, really don't want to create another network-namespaced auth policy that explicitly targets all of the other apps not using the custom provider. Is there any way around this?

solidDoWant avatar Oct 01 '25 22:10 solidDoWant