Skip to content

For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.

Page as Markdown

AgentgatewayPolicy resources

Learn how policies in AgentgatewayPolicy resources are inherited and overridden along the route delegation chain.

Verified Code examples on this page have been automatically tested and verified.

Learn how policy inheritance and overrides work for AgentgatewayPolicy resources in a route delegation setup.

Want to learn more about policy inheritance and overrides for Kubernetes Gateway API-native policies, such as timeouts and retries? See Native Gateway API policies.

About policy inheritance

The following policy inheritance and override rules apply for AgentgatewayPolicy resources.

  • Policies that are defined in an AgentgatewayPolicy and applied to a parent HTTPRoute are automatically inherited by all child and grandchild HTTPRoutes along the route delegation chain.
  • If an AgentgatewayPolicy is applied to a child or grandchild HTTPRoute and defines a policy that is also set on the parent, the policy on the child takes precedence and overrides the parent’s. For example, if the parent defines a transformation policy and the child defines a different transformation policy, the child’s transformation is applied.
  • If an AgentgatewayPolicy is applied to a child or grandchild HTTPRoute and defines a different policy type than the parent, both policies are merged and applied. For example, if the parent applies a rate limit and the child applies a transformation, both apply.
  • Authorization policies are an exception. They merge across the entire delegation chain rather than overriding. Allow rules from any policy in the chain can grant access, and Require rules from every policy in the chain must all match for the request to be allowed.

In short, for most policy types the child’s policy overrides the parent’s. If the child does not define a particular policy, the child inherits the parent’s policy. Authorization rules are an exception, and merge across the chain.

Configuration overview

In this guide, you walk through two route delegation examples.

  1. Transformation and rate limit: A parent AgentgatewayPolicy defines both a transformation and a local rate limit. The child AgentgatewayPolicy defines only a transformation. You verify that the child’s transformation overrides the parent’s, but the parent’s rate limit still applies because the child does not define one.
  2. Authorization merge: A parent AgentgatewayPolicy and a child AgentgatewayPolicy each define a Require authorization rule. You verify that both rules must match for the request to be allowed.

The following image illustrates the route delegation hierarchy:

parent HTTPRoute:

  • Delegates traffic on the /anything/team1 prefix to HTTPRoutes in the team1 namespace.

child-team1 HTTPRoute:

  • Matches incoming traffic for the /anything/team1/foo prefix path and routes that traffic to the httpbin app in the team1 namespace.

Before you begin

  1. Follow the Get started guide to install agentgateway.

  2. Follow the Sample app guide to create the agentgateway-proxy Gateway with an HTTP listener.

  3. Get the external address of the agentgateway proxy and save it in an environment variable.

    export INGRESS_GW_ADDRESS=$(kubectl get svc -n agentgateway-system agentgateway-proxy -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}")
    echo $INGRESS_GW_ADDRESS

  4. Create the namespaces for team1 and team2.

    kubectl create namespace team1
    kubectl create namespace team2
  5. Deploy the httpbin app into both namespaces. The httpbin app exposes endpoints such as /anything/..., /headers, and /delay/N that are useful for verifying routing and policy behavior.

    curl -sL https://raw.githubusercontent.com/kgateway-dev/kgateway/main/examples/httpbin.yaml \
      | awk 'BEGIN{skip=0} /^kind: Namespace$/{skip=1} skip==0{print} /^---$/{skip=0}' \
      | sed 's/namespace: httpbin/namespace: team1/g' \
      | kubectl apply -f -
    
    curl -sL https://raw.githubusercontent.com/kgateway-dev/kgateway/main/examples/httpbin.yaml \
      | awk 'BEGIN{skip=0} /^kind: Namespace$/{skip=1} skip==0{print} /^---$/{skip=0}' \
      | sed 's/namespace: httpbin/namespace: team2/g' \
      | kubectl apply -f -
  6. Verify that the httpbin apps are up and running.

    kubectl get pods -n team1
    kubectl get pods -n team2

    Example output:

    NAME                       READY   STATUS    RESTARTS   AGE
    httpbin-6bc5b79755-xlvjf   3/3     Running   0          7s
    NAME                       READY   STATUS    RESTARTS   AGE
    httpbin-6bc5b79755-twxq9   3/3     Running   0          6s

Set up the routes

  1. Create the parent HTTPRoute that matches incoming traffic on the delegation.example domain and delegates to HTTPRoutes in the team1 namespace.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: parent
      namespace: agentgateway-system
    spec:
      parentRefs:
      - name: agentgateway-proxy
      hostnames:
      - "delegation.example"
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /anything/team1
        backendRefs:
        - group: gateway.networking.k8s.io
          kind: HTTPRoute
          name: child-team1
          namespace: team1
    EOF
  2. Create the child-team1 HTTPRoute in the team1 namespace that matches traffic on the /anything/team1/foo prefix and routes traffic to the httpbin app.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: child-team1
      namespace: team1
    spec:
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /anything/team1/foo
        backendRefs:
        - name: httpbin
          port: 8000
    EOF

Transformation override and rate limit inheritance

In this section, you attach an AgentgatewayPolicy to the parent and a different AgentgatewayPolicy to the child. The parent policy defines both a transformation and a local rate limit. The child policy defines only a transformation. The child’s transformation overrides the parent’s. The child does not define a rate limit, so the parent’s rate limit is inherited.

  1. Create an AgentgatewayPolicy that targets the parent HTTPRoute. The policy adds an x-parent-policy header to requests and limits requests to 1 per minute.

    kubectl apply -f- <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayPolicy
    metadata:
      name: parent-policy
      namespace: agentgateway-system
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: parent
      traffic:
        transformation:
          request:
            set:
            - name: x-parent-policy
              value: "'This policy is inherited from the parent.'"
        rateLimit:
          local:
          - requests: 1
            unit: Minutes
    EOF
  2. Create an AgentgatewayPolicy that targets the child-team1 HTTPRoute. The policy adds an x-child-policy header to requests. It does not define a rate limit.

    kubectl apply -f- <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayPolicy
    metadata:
      name: child-policy
      namespace: team1
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: child-team1
      traffic:
        transformation:
          request:
            set:
            - name: x-child-policy
              value: "'This is the child-team1 policy.'"
    EOF
  3. Verify that both policies are accepted.

    kubectl get agentgatewaypolicy parent-policy -n agentgateway-system
    kubectl get agentgatewaypolicy child-policy -n team1

    Example output:

    NAME            ACCEPTED   ATTACHED   AGE
    parent-policy   True       True       3s
    NAME           ACCEPTED   ATTACHED   AGE
    child-policy   True       True       3s
  4. Send a request to the delegation.example domain along the /anything/team1/foo path. Verify that the response includes the X-Child-Policy header but not the X-Parent-Policy header. The child’s transformation overrides the parent’s because both define the same transformation policy.

    curl -s http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo -H "host: delegation.example"

    Example output (truncated):

    {
      "headers": {
        "Host": ["delegation.example"],
        "X-Child-Policy": ["This is the child-team1 policy."]
      }
    }
  5. Send a second request to the same path within one minute. Verify that you get a 429 HTTP response, because the child inherits the parent’s rate limit of 1 request per minute.

    curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo -H "host: delegation.example"

    Example output:

    HTTP/1.1 429 Too Many Requests
    content-type: text/plain
    server: agentgateway
    
    local_rate_limited
  6. Delete both policies before continuing to the next section.

    kubectl delete agentgatewaypolicy parent-policy -n agentgateway-system
    kubectl delete agentgatewaypolicy child-policy -n team1

Authorization merging

In this section, you attach a Require authorization rule to the parent and a different Require authorization rule to the child. Authorization policies merge across the delegation chain, so both rules must be satisfied for the request to be allowed.

  1. Create an AgentgatewayPolicy that targets the parent HTTPRoute. The policy requires the x-parent-required: true request header.

    kubectl apply -f- <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayPolicy
    metadata:
      name: parent-authz
      namespace: agentgateway-system
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: parent
      traffic:
        authorization:
          action: Require
          policy:
            matchExpressions:
            - 'request.headers["x-parent-required"] == "true"'
    EOF
  2. Create an AgentgatewayPolicy that targets the child-team1 HTTPRoute. The policy requires the x-child-required: true request header.

    kubectl apply -f- <<EOF
    apiVersion: agentgateway.dev/v1alpha1
    kind: AgentgatewayPolicy
    metadata:
      name: child-authz
      namespace: team1
    spec:
      targetRefs:
      - group: gateway.networking.k8s.io
        kind: HTTPRoute
        name: child-team1
      traffic:
        authorization:
          action: Require
          policy:
            matchExpressions:
            - 'request.headers["x-child-required"] == "true"'
    EOF
  3. Send a request without either header. Verify that you get a 403 HTTP response, because both Require rules must match.

    curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo -H "host: delegation.example"

    Example output:

    HTTP/1.1 403 Forbidden
    content-type: text/plain
    server: agentgateway
  4. Send a request with only the parent’s required header. Verify that you still get a 403 HTTP response, because the child’s Require rule is not satisfied.

    curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \
      -H "host: delegation.example" \
      -H "x-parent-required: true"

    Example output:

    HTTP/1.1 403 Forbidden
    content-type: text/plain
    server: agentgateway
  5. Send a request with only the child’s required header. Verify that you still get a 403 HTTP response, because the parent’s Require rule is not satisfied.

    curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \
      -H "host: delegation.example" \
      -H "x-child-required: true"

    Example output:

    HTTP/1.1 403 Forbidden
    content-type: text/plain
    server: agentgateway
  6. Send a request with both required headers. Verify that you get a 200 HTTP response, because both the parent’s and child’s Require rules match.

    curl -i http://$INGRESS_GW_ADDRESS:8080/anything/team1/foo \
      -H "host: delegation.example" \
      -H "x-parent-required: true" \
      -H "x-child-required: true"

    Example output:

    HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    content-type: application/json; encoding=utf-8
    server: agentgateway

Cleanup

You can remove the resources that you created in this guide.
kubectl delete agentgatewaypolicy parent-authz -n agentgateway-system --ignore-not-found
kubectl delete agentgatewaypolicy child-authz -n team1 --ignore-not-found
kubectl delete agentgatewaypolicy parent-policy -n agentgateway-system --ignore-not-found
kubectl delete agentgatewaypolicy child-policy -n team1 --ignore-not-found
kubectl delete httproute parent -n agentgateway-system
kubectl delete httproute child-team1 -n team1
kubectl delete namespaces team1 team2
Was this page helpful?
Agentgateway assistant

Ask me anything about agentgateway configuration, features, or usage.

Note: AI-generated content might contain errors; please verify and test all returned information.

Tip: one topic per conversation gives the best results. Use the + button in the chat header to start a new conversation.

Switching topics? Starting a new conversation improves accuracy.
↑↓ navigate select esc dismiss

What could be improved?

Your feedback helps us improve assistant answers and identify docs gaps we should fix.

Need more help? Join us on Discord: https://discord.gg/y9efgEmppm

Want to use your own agent? Add the Solo MCP server to query our docs directly. Get started here: https://search.solo.io/.