Skip to content
You are viewing the documentation for Solo Enterprise for Istio, formerly known as Gloo Mesh (OSS APIs).

Egress gateway

Alpha
Page as Markdown

Use agentgateway as an egress waypoint to enforce Layer 7 policies on traffic leaving your ambient mesh.

The agentgateway waypoint feature is in the alpha state. Alpha features are likely to change, are not fully tested, and are not supported for production. For more information, see Solo feature maturity.

You can deploy Solo Enterprise for agentgateway as an egress waypoint to apply L7 policies to traffic leaving your ambient mesh. This guide covers cases in which your application manages its own credentials and you want to control which service accounts are allowed to make outbound calls to an external API. The agentgateway waypoint enforces allow/deny policy on the traffic, but does not inject credentials or perform provider-aware routing.

If you want agentgateway to manage API credentials and perform provider-aware routing to LLM backends (the east-west equivalent of the standalone Solo Enterprise for agentgateway LLM provider guides), see the AI provider backends with agentgateway waypoint guide instead.

The pattern mirrors the community egress with a waypoint proxy method, with two differences:

  • Uses the enterprise-agentgateway-waypoint GatewayClass instead of istio-waypoint
  • Always uses istio.io/waypoint-for: all because ServiceEntries are not Kubernetes-native services

Before you begin

Install the Solo Enterprise for agentgateway control plane and GatewayClass by following the Install guide. Complete the Install Solo Enterprise for agentgateway section only. You do not need to complete the Deploy the waypoint section, because this guide creates a separate egress waypoint Gateway.

Deploy an egress waypoint

  1. Set the workload namespace where your workloads run. All resources in this guide are created in this namespace.

    export NAMESPACE=<ns>
  2. Create a Gateway resource for the egress waypoint. Because egress targets are represented as ServiceEntries rather than Kubernetes Services, you must use istio.io/waypoint-for: all.

    kubectl apply -f - <<EOF
    apiVersion: gateway.networking.k8s.io/v1
    kind: Gateway
    metadata:
      name: egress-waypoint
      namespace: ${NAMESPACE}
      labels:
        istio.io/waypoint-for: all
    spec:
      gatewayClassName: enterprise-agentgateway-waypoint
      listeners:
      - name: mesh
        port: 15008
        protocol: HBONE
    EOF
  3. Verify that the egress waypoint pod is running and the Gateway is programmed.

    kubectl get pods -n ${NAMESPACE} -l gateway.networking.k8s.io/gateway-name=egress-waypoint
    kubectl get gateway egress-waypoint -n ${NAMESPACE}

    Example output:

    NAME                               READY   STATUS    RESTARTS   AGE
    egress-waypoint-757fdbb564-44nz2   1/1     Running   0          11s
    
    NAME              CLASS                              ADDRESS         PROGRAMMED   AGE
    egress-waypoint   enterprise-agentgateway-waypoint   172.20.235.25   True         23s

Register the external AI API

  1. Create a ServiceEntry for the external AI API, such as the OpenAI API.

    kubectl apply -f - <<EOF
    apiVersion: networking.istio.io/v1
    kind: ServiceEntry
    metadata:
      name: openai-api
      namespace: ${NAMESPACE}
    spec:
      hosts:
      - api.openai.com
      ports:
      - number: 443
        name: https
        protocol: HTTPS
      resolution: DNS
      location: MESH_EXTERNAL
    EOF
  2. Label the ServiceEntry to route traffic through the egress waypoint.

    kubectl label serviceentry openai-api \
      -n ${NAMESPACE} \
      istio.io/use-waypoint=egress-waypoint

Restrict which agents can call the API

Apply an EnterpriseAgentgatewayPolicy to allow only specific service accounts to make calls to the external AI API. The policy denies all traffic by default, so any workload not listed in matchExpressions receives a 403 directly from the waypoint — before the request reaches OpenAI. This 403 (rather than a 401 from the upstream API) confirms the waypoint is intercepting and enforcing policy on the traffic.

  1. Set the service account of your agent workload.

    export AGENT_SERVICE_ACCOUNT=<your_agent_sa>
  2. Apply an EnterpriseAgentgatewayPolicy. The following example allows POST requests from a single agent service account.

    kubectl apply -f - <<EOF
    apiVersion: enterpriseagentgateway.solo.io/v1alpha1
    kind: EnterpriseAgentgatewayPolicy
    metadata:
      name: openai-allow-agent-only
      namespace: ${NAMESPACE}
    spec:
      targetRefs:
      - kind: ServiceEntry
        group: "networking.istio.io"
        name: openai-api
      traffic:
        authorization:
          action: Allow
          policy:
            matchExpressions:
            - 'source.identity.namespace == "${NAMESPACE}" && source.identity.serviceAccount == "${AGENT_SERVICE_ACCOUNT}" && request.method == "POST"'
    EOF

    To allow multiple agents, add an expression for each service account.

            matchExpressions:
            - 'source.identity.namespace == "${NAMESPACE}" && source.identity.serviceAccount == "agent-a" && request.method == "POST"'
            - 'source.identity.namespace == "${NAMESPACE}" && source.identity.serviceAccount == "agent-b" && request.method == "POST"'
  3. Deploy an unauthorized test pod that runs under the default service account.

    kubectl run curl-unauth -n ${NAMESPACE} --image=curlimages/curl --restart=Never -- sleep 3600
  4. Deploy an authorized test pod that runs under the agent service account.

    kubectl run curl-auth -n ${NAMESPACE} --image=curlimages/curl \
      --restart=Never --overrides="{\"spec\":{\"serviceAccountName\":\"${AGENT_SERVICE_ACCOUNT}\"}}" \
      -- sleep 3600
  5. Verify that the waypoint enforces the policy by sending a request from the unauthorized pod. The waypoint returns a 403 before the request reaches OpenAI.

    kubectl exec -n ${NAMESPACE} curl-unauth -- \
      curl -s -o /dev/null -w "%{http_code}" https://api.openai.com/v1/models
  6. Confirm that the authorized pod can reach OpenAI.

    kubectl exec -n ${NAMESPACE} curl-auth -- \
      curl -s -o /dev/null -w "%{http_code}" https://api.openai.com/v1/models
  7. Verify that the in-mesh segment of the traffic (from your workload to the egress waypoint) uses mTLS. For more information about this command, see the CLI reference.

    istioctl ztunnel-config connections --namespace ${NAMESPACE}

    The PROTOCOL column shows HBONE for inbound connections to the egress waypoint pod, confirming that workload-to-waypoint traffic is mutually authenticated over HBONE.

    Example output:

    WORKLOAD                                          DIRECTION   LOCAL              REMOTE           REMOTE TARGET         PROTOCOL   CONN ID
    egress-waypoint-757fdbb564-44nz2.<ns>              Inbound     10.0.0.10:15008    10.0.0.3:54210   api.openai.com:443    HBONE      1a2b3c4d
To capture per-request observability, you can configure access logging for the agentgateway waypoint. Access logs are not enabled by default. For configuration steps, see the [Solo Enterprise for agentgateway documentation](https://docs.solo.io/agentgateway/latest/security/access-logging/).

Cleanup

If you no longer need them, you can remove all resources that you created in this guide.

kubectl delete pod curl-unauth curl-auth -n ${NAMESPACE}
kubectl delete enterpriseagentgatewaypolicy openai-allow-agent-only -n ${NAMESPACE}
kubectl delete serviceentry openai-api -n ${NAMESPACE}
kubectl delete gateway egress-waypoint -n ${NAMESPACE}

Authenticate to the AI API using workload identity

Rather than embedding API credentials in your workload, agentgateway can forward the source workload’s WIMSE WIT to the external API. Use backend.workloadIdentity.mode: SourceDelegation in an EnterpriseAgentgatewayPolicy to attach the inbound Workload-Identity-Token header to the outbound request. The external API can then verify the token directly.

apiVersion: enterpriseagentgateway.solo.io/v1alpha1
kind: EnterpriseAgentgatewayPolicy
metadata:
  name: openai-wit-forward
  namespace: ${NAMESPACE}
spec:
  targetRefs:
  - kind: ServiceEntry
    group: "networking.istio.io"
    name: openai-api
  backend:
    workloadIdentity:
      mode: SourceDelegation

For full WIT configuration details, including inbound policy with workload claims and the SelfIdentification mode, see Workload identity tokens (WIMSE).