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

Delegation via labels

Use labels to delegate traffic to child HTTPRoutes with the <key>=<value> syntax.

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

Use labels to delegate traffic to child HTTPRoutes. The parent HTTPRoute selects children by a label key and value, instead of by name.

About label-based selection

In agentgateway, the parent HTTPRoute encodes a label selector in the backendRefs.name field by using the <key>=<value> syntax. Agentgateway selects any child HTTPRoute in the target namespace whose metadata.labels[<key>] equals <value>.

Use the label-selector pattern when you want to add new child HTTPRoutes to the delegation chain without updating the parent’s backendRefs each time. New children only need the agreed-upon label.

The following image illustrates the route delegation hierarchy:

parent HTTPRoute:

  • Delegates traffic as follows:
    • /anything/team1 is delegated to HTTPRoutes in the team1 namespace that are labeled team: team1.
    • /anything/team2 is delegated to HTTPRoutes in the team2 namespace that are labeled team: team2.

child-team1 HTTPRoute:

  • Carries the team: team1 label and matches incoming traffic for the /anything/team1/foo prefix path. Routes traffic to the httpbin app in the team1 namespace.

child-team2 HTTPRoute:

  • Carries the team: team2 label and matches incoming traffic for the /anything/team2/bar exact path. Routes traffic to the httpbin app in the team2 namespace.
The label key and value are arbitrary. Pick a convention that makes sense for your environment, such as team, app, or tier. The parent and the children must agree on both the key and the value.

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

Setup

  1. Create the parent HTTPRoute that matches incoming traffic on the delegation.example domain. The HTTPRoute specifies two routes:

    • /anything/team1 delegates to HTTPRoutes in the team1 namespace that have the team: team1 label, by encoding team=team1 in the backendRefs.name field.
    • /anything/team2 delegates to HTTPRoutes in the team2 namespace that have the team: team2 label.
    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: team=team1
          namespace: team1
      - matches:
        - path:
            type: PathPrefix
            value: /anything/team2
        backendRefs:
        - group: gateway.networking.k8s.io
          kind: HTTPRoute
          name: team=team2
          namespace: team2
    EOF
  2. Create the child-team1 HTTPRoute in the team1 namespace. The HTTPRoute carries the team: team1 label and matches traffic on the /anything/team1/foo path prefix. Without that label, the parent does not select this child as a delegation target.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: child-team1
      namespace: team1
      labels:
        team: team1
    spec:
      rules:
      - matches:
        - path:
            type: PathPrefix
            value: /anything/team1/foo
        backendRefs:
        - name: httpbin
          port: 8000
    EOF
  3. Create the child-team2 HTTPRoute in the team2 namespace with the team: team2 label.

    kubectl apply -f- <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: HTTPRoute
    metadata:
      name: child-team2
      namespace: team2
      labels:
        team: team2
    spec:
      rules:
      - matches:
        - path:
            type: Exact
            value: /anything/team2/bar
        backendRefs:
        - name: httpbin
          port: 8000
    EOF
  4. Send a request to the delegation.example domain along the /anything/team1/foo path. Verify that you get a 200 HTTP response.

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

    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
  5. Send a request along the /anything/team2/bar path. Verify that you get a 200 HTTP response.

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

    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
  6. Optionally, verify that an unlabeled HTTPRoute in team1 does not receive traffic from the parent.

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

    Send a request to /anything/team1/baz and verify that you get a 404 HTTP response, because the route is missing the team: team1 label.

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

    Example output:

    HTTP/1.1 404 Not Found
    content-type: text/plain
    server: agentgateway

    Clean up the unlabeled route.

    kubectl delete httproute child-team1-unlabeled -n team1

Cleanup

You can remove the resources that you created in this guide.
kubectl delete httproute parent -n agentgateway-system
kubectl delete httproute child-team1 -n team1
kubectl delete httproute child-team2 -n team2
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/.