Allow AccessPolicy to Target Gateway Objects¶
Currently, the AccessPolicy resource is only allowed to target Backends.
This has scalability issues when a given Tool Authorization policy needs to be enforced for all the traffic managed by a Gateway object.
This proposal allows AccessPolicy to target Gateway objects, in addition to Backend objects with following restrictions:
-
A single
AccessPolicyobject targeting a Gateway and a Backend at the same time is NOT allowed. -
It is allowed to have
AccessPolicyobjects targeting aGatewayobject andAccessPolicyobjects targeting aBackendobject behind theGatewayobject. In this case, theAccessPolicyobjects targeting theGatewayobject will be evaluated first. Among theAccessPolicyobjects targeting theGatewayobject, the ones with earlier creationTimestamp will be evaluated first. For the policies with the same creationTimestamp, the ones appearing first in alphabetical order by{namespace}/{name}will be evaluated first.-
If any of the
AccessPolicyobjects targeting theGatewayobject denies the access, the HTTP request will be denied. TheAccessPolicyobjects targeting theBackendobject will NOT be evaluated in this case. -
If all the
AccessPolicyobjects targeting theGatewayobject allow the access, theAccessPolicyobjects targeting theBackendobject will be evaluated. Among theAccessPolicyobjects targeting theBackendobject, the ones with earlier creationTimestamp will be evaluated first. For the policies with the same creationTimestamp, the ones appearing first in alphabetical order by{namespace}/{name}will be evaluated first.-
if any of the
AccessPolicyobjects targeting theBackendobject denies the access, the HTTP request will be denied. -
if all the
AccessPolicyobjects targeting theBackendobject allow the access, the HTTP request will be allowed.
-
-
Example¶
Consider the following setup:
We have a Gateway, an HTTPRoute and a Backend:
- Gateway:
prod-gateway - HTTPRoute:
payment-route(attached toprod-gateway, routes topayment-service) - Backend:
payment-service
We also have the following AccessPolicies applied:
gateway-policy-audit(Targetsprod-gateway). Created at T1.gateway-policy-region(Targetsprod-gateway). Created at T2 (T1 < T2).backend-policy-admin(Targetspayment-service).
The graph shows the relationships between these resources:
graph TD
%% 1. Policies at the Top
subgraph PolicyLayer [Policy Attachments]
direction LR
GPA1(AccessPolicy: gateway-policy-audit)
GPR1(AccessPolicy: gateway-policy-region)
BPA1(AccessPolicy: backend-policy-admin)
end
%% 2. Infrastructure & Routing on the same line
%% We define the order here: Gateway <-> Route <-> Backend
GW(Gateway: prod-gateway)
Route(HTTPRoute: payment-route)
BE(Backend: payment-service)
%% Invisible links to force horizontal alignment
GW ~~~ Route ~~~ BE
%% 3. Vertical Arrows (Policies pointing DOWN)
GPA1 -. "TargetRefs" .-> GW
GPR1 -. "TargetRefs" .-> GW
BPA1 -. "TargetRefs" .-> BE
%% 4. Horizontal Arrows (Routing logic)
Route -- "ParentRefs" --> GW
Route -- "BackendRefs" --> BE
%% --- STYLING ---
classDef infra fill:#e3f2fd,stroke:#1565c0,stroke-width:2px;
classDef routing fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;
classDef policy fill:#fff3e0,stroke:#ef6c00,stroke-width:2px,stroke-dasharray: 5 5;
class GW,BE infra;
class Route routing;
class GPA1,GPR1,BPA1 policy;
style PolicyLayer fill:none,stroke:#ccc,stroke-dasharray: 5 5;
Evaluation Flow¶
When a request comes to payment-service through prod-gateway:
-
Gateway Level Checks:
- First,
gateway-policy-auditis evaluated (earlier creation timestamp). - Next,
gateway-policy-regionis evaluated. - Rule: ALL Gateway policies must allow the request. If
gateway-policy-auditdenies it, the request is rejected immediately, and subsequent policies are skipped.
- First,
-
Backend Level Checks:
- If (and only if) all Gateway policies allow the request,
backend-policy-adminis evaluated. - Rule: Backend policies must also allow the request.
- If (and only if) all Gateway policies allow the request,
Final Result: The request is allowed ONLY if it is allowed by all three policies.
API Changes¶
We will use +kubebuilder:validation:XValidation:rule markers to make sure that:
- A
targetRefmust be eitherGatewayorBackend. - All targetRefs must have the same kind.
// AccessPolicySpec defines the desired state of AccessPolicy.
type AccessPolicySpec struct {
// TargetRefs specifies the targets of the AccessPolicy.
// An AccessPolicy must target at least one resource.
// +required
// +kubebuilder:validation:MinItems=1
// +listType=atomic
// +kubebuilder:validation:XValidation:rule="self.all(x, (x.group == 'agentic.prototype.x-k8s.io' && x.kind == 'XBackend') || (x.group == 'gateway.networking.k8s.io' && x.kind == 'Gateway'))",message="TargetRef must have group agentic.prototype.x-k8s.io and kind XBackend, or group gateway.networking.k8s.io and kind Gateway"
// +kubebuilder:validation:XValidation:rule="self.all(ref, ref.kind == self[0].kind)",message="All targetRefs must have the same Kind"
TargetRefs []gwapiv1.LocalPolicyTargetReference `json:"targetRefs"`
}
Currently, the InlineTools type of AuthorizationRule supports a list of tool names, which works well for AccessPolicy targeting Backend objects. However, it does not work well for AccessPolicy targeting Gateway objects, because there could be tool name conflicts between different backends behind the same Gateway. We will address this in a separate proposal.
Support requirements in implementation¶
-
An implementation MUST support at least one of the following:
AccessPolicyobjects targetingGatewayobjectsAccessPolicyobjects targetingBackendobjects
-
If an implementation supports allowing
AccessPolicyto target bothGatewayandBackendobjects, it MUST support the evaluation flow described above.