> ## Documentation Index
> Fetch the complete documentation index at: https://tyk.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes Gateway API Reference

> How Tyk Operator translates Kubernetes Gateway API resources into Tyk OAS APIs: API identity, listeners, matches, backends, filters, lifecycle, status conditions and troubleshooting.

## Introduction

This page lists the parts of the [Kubernetes Gateway API](https://gateway-api.sigs.k8s.io/) that Tyk Operator supports, from `Gateway` listeners to `HTTPRoute` matches, backends and filters. It then describes how Tyk Operator translates routes into Tyk OAS APIs, how it manages them, and how it reports problems.

For an introduction, see the [Overview](https://tyk.io/docs/product-stack/tyk-operator/gateway-api/overview.md). The information on this page applies to Tyk Operator 1.6.0.

## Gateways and Listeners

### Gateway Address

Tyk Operator doesn't deploy Tyk Gateways or load balancers. It reports the address of the `Gateway` from the Kubernetes Service named in `dataPlane.serviceRef`:

| Service | Address in `status.addresses` |
| :- | :- |
| `LoadBalancer` with an ingress | The hostname, or the IP address, of each ingress entry |
| `LoadBalancer` with no ingress yet | None. `Programmed` is `False` with the reason `AddressNotAssigned`. |
| `ExternalName` | The external name |
| Other types | The cluster IP. For a headless Service, `<service>.<namespace>.svc.cluster.local`. |

Tyk Operator ignores `spec.addresses` on the `Gateway`.

### Listeners

Each listener must:

* use the `HTTP` or `HTTPS` protocol
* use a port that the Kubernetes Service of the data plane exposes, unless the Service has no ports (`ExternalName`)
* not conflict with another listener on the same port, by protocol or hostname

Tyk Operator uses the listener port only to check it against the Service. It doesn't change the ports that Tyk Gateway listens on.

### TLS Certificates

For an `HTTPS` listener, each entry in `tls.certificateRefs` must refer to a Kubernetes Secret of type `kubernetes.io/tls` that holds a matching certificate and key. To refer to a Secret in another namespace, the owner of that namespace must create a `ReferenceGrant`.

Tyk Operator uploads the certificates to the [Tyk Certificate Store](https://tyk.io/docs/api-management/certificates.md#tyk-certificate-store), and attaches them to the APIs of routes that have an [effective hostname](#api-identity).

> [!NOTE]
>
> Tyk Operator doesn't delete certificates from the Tyk Certificate Store when you remove them from a listener.

## Matches

| Match | Support |
| :- | :- |
| `path` with `type: PathPrefix` | Supported. If you don't set `type`, Tyk Operator uses `PathPrefix`. |
| `path` with `type: Exact` or `RegularExpression` | Not supported |
| `method` | Supported for the methods that OpenAPI defines, such as `GET` and `POST`. Not supported for other methods, such as `CONNECT`. |
| `headers` | Not supported |
| `queryParams` | Not supported |

To make Tyk Gateway match paths by segment, so that `/orders` doesn't also match `/orders-archive`, set [`http_server_options.enable_strict_routes`](https://tyk.io/docs/tyk-oss-gateway/configuration#http_server_options-enable_strict_routes) to `true` on your Tyk Gateways.

## Backends

| Backend Reference | Support |
| :- | :- |
| A Kubernetes `Service`, with `port` set | Supported |
| Several Services in one rule | Supported. Tyk Gateway balances the load across them by `weight`. If you don't set `weight`, Tyk Operator uses `1`. It leaves out Services with a `weight` of `0`. |
| A headless Service | Supported. Tyk Operator uses the addresses of its pods as the targets. |
| A Service in another namespace | Supported if the owner of that namespace creates a `ReferenceGrant` |
| Any other kind or group, or no `port` | Not supported. `ResolvedRefs` is `False` with the reason `InvalidKind`. |
| `filters` on a backend reference | Not supported |

Tyk Gateway sends requests to upstream services over plain HTTP, using the cluster DNS name of the Service. The Tyk Gateways must be able to resolve `*.svc.cluster.local`.

> [!WARNING]
>
> If Tyk Operator can't resolve a backend reference, it still creates the API, with the upstream URL `http://unresolved.backend.invalid`. The API then responds with `500 Internal Server Error`. Check the `ResolvedRefs` condition of the route.

## Filters

| Filter | Support |
| :- | :- |
| `RequestHeaderModifier` | `set` and `remove` are supported. `add` is not supported, because Tyk Gateway holds one value for each header name. Use `set` to replace the value. |
| `ResponseHeaderModifier` | `set` and `remove` are supported. `add` is not supported. |
| `URLRewrite` with `path.type: ReplacePrefixMatch` | Supported. Tyk Operator puts the replacement in the upstream URL in place of the matched path. To remove the matched path, set `replacePrefixMatch` to `/`. |
| `URLRewrite` with `path.type: ReplaceFullPath` | Supported. Tyk Gateway rewrites the path and keeps the query string. The replacement can't contain `$` followed by a digit. |
| `URLRewrite` with `hostname` | Not supported |
| `RequestRedirect` | Supported if the redirect is the same for every request: `hostname` is set, `path.type` is `ReplaceFullPath`, and the scheme and port are set or are the same on every listener that admits the route. Tyk Gateway responds with the redirect, by default `302 Found`, without authentication. |
| `RequestMirror` | Not supported |
| `CORS` | Not supported |
| `ExternalAuth` | Not supported |
| `ExtensionRef` | Not supported |

Tyk Gateway applies its middleware in a fixed order, so the order of the filters in a rule has no effect.

## Unsupported Features

Tyk Operator rejects any part of a route that it can't translate, and reports the reason in the route status. These rule fields are not supported:

* `timeouts`
* `retry`
* `sessionPersistence`

Rules that match the same path must use the same backends and, for overlapping methods, the same filters. If they don't, Tyk Operator rejects them.

How Tyk Operator reports a rejection depends on how much of the route it can still serve:

* If it can serve none of the route, `Accepted` is `False` with the reason `UnsupportedValue`.
* If it can serve some paths, `Accepted` is `True`, and `PartiallyInvalid` is `True` with the reason `UnsupportedValue`. The message lists the rules that it dropped.

The message names the field and the reason, for example `spec.rules[1].retry: ...`.

## How Routes Become APIs

### API Identity

Tyk Operator creates one Tyk OAS API for each combination of:

* parent `Gateway` (from `parentRefs`)
* effective hostname
* path value in the route matches

The effective hostname is the intersection of the hostnames of the route and the hostname of the listener. If neither sets a hostname, the API has no custom domain.

The ID of each API is `gwapi-` followed by 20 hexadecimal characters. Tyk Operator derives it from the namespace and name of the route, the path, the parent `Gateway` and the hostname. The ID doesn't depend on the order of the rules, so you can reorder rules without changing it.

Rules that match the same path become one API, with one operation for each HTTP method that they match. Requests with a method that no rule matches receive `404 Not Found`.

### API Configuration

Each API gets this configuration. The settings are in the Tyk Vendor Extension (`x-tyk-api-gateway`), except where the table says otherwise.

| Tyk OAS API Setting | Value |
| :- | :- |
| `info.title` (OpenAPI description) | The ID of the API |
| `info.id` | The ID of the API |
| `info.name` | The ID of the API, so the API appears in Tyk Dashboard under that name |
| `info.state.active` | `true` |
| `server.listenPath` | The path value of the match, with `strip` set to `true`. Tyk Operator adds the path back to the upstream URL, so the upstream service receives the full request path. |
| `server.customDomain` | The effective hostname. A wildcard such as `*.example.com` becomes `{h:.+}.example.com`. |
| `server.gatewayTags` | The `dataPlane.tags` of the OperatorContext of the `Gateway` |
| `upstream.url` | `http://<service>.<namespace>.svc.cluster.local:<port>`, from the backend reference, followed by the path value of the match. A `URLRewrite` filter changes the path. See [Filters](#filters). |
| `upstream.loadBalancing` | The backend references and their weights, if the rule has more than one |
| `upstream.preserveHostHeader` | `true` |
| `server.authentication` | Not set. The API has no authentication. |

To add authentication and other settings, see [Secure and Extend Routes](https://tyk.io/docs/product-stack/tyk-operator/gateway-api/secure-and-extend-routes.md).

## Lifecycle

### Gateways Without a Data Plane Context

If a `Gateway` has no `infrastructure.parametersRef`, Tyk Operator still creates APIs for its routes, but the APIs have no Gateway tags. The `Gateway` reports `Programmed` as `False` with the reason `UnsupportedAddress`.

> [!WARNING]
>
> Always set `infrastructure.parametersRef` on a `Gateway`, and set `dataPlane.tags` in its OperatorContext. Otherwise, every Tyk Gateway that isn't [segmented](https://tyk.io/docs/api-management/api-sharding.md) loads the APIs of its routes, including Tyk Gateways that you didn't intend to serve them.

### Updating and Deleting Routes

Tyk Operator updates the APIs of a route when you change the route.

Tyk Operator adds a finalizer to each `HTTPRoute`. When you delete a route, Tyk Operator deletes its APIs from Tyk Dashboard, then removes the finalizer.

If Tyk Operator can't delete the APIs, for example because Tyk Dashboard is unreachable, it keeps the finalizer and tries again. The route stays in the `Terminating` state until the APIs are deleted. Tyk Operator reports the problem as an event on the route.

If you disable Kubernetes Gateway API support in Tyk Operator while `HTTPRoute` resources exist, Tyk Operator can't delete them. Delete your routes before you disable it.

## Status and Troubleshooting

Tyk Operator reports the result of each resource in its `status.conditions`. To see them, run:

```bash theme={null}
kubectl get httproute <name> -n <namespace> -o yaml
```

### GatewayClass Conditions

| Condition | Status | Reason | Meaning |
| :- | :- | :- | :- |
| `Accepted` | `True` | `Accepted` | Tyk Operator manages the class. |
| `Accepted` | `False` | `InvalidParameters` | The `parametersRef` is wrong. It must refer to an OperatorContext (`group: tyk.tyk.io`, `kind: OperatorContext`) with a `namespace`. The OperatorContext must set `env` or `secretRef`, and the Secret must exist. |

You can't delete a `GatewayClass` while `Gateway` resources use it.

### Gateway Conditions

| Condition | Status | Reason | Meaning |
| :- | :- | :- | :- |
| `Accepted` | `True` | `ListenersNotValid` | Some listeners are not valid. Tyk Operator uses the valid listeners. Check the listener conditions. |
| `Accepted` | `False` | `ListenersNotValid` | No listeners are valid. Check the listener conditions. |
| `Accepted` and `Programmed` | `False` | `Invalid` | Tyk Operator can't read the OperatorContext of the `GatewayClass`, or the OperatorContext in `infrastructure.parametersRef`. |
| `Programmed` | `False` | `UnsupportedAddress` | The `Gateway` has no `infrastructure.parametersRef`, its OperatorContext has no `dataPlane.serviceRef`, or the Service doesn't exist. |
| `Programmed` | `False` | `AddressNotAssigned` | The `LoadBalancer` Service has no ingress address yet. |

Tyk Operator reports the conditions of each listener in `status.listeners`:

| Reason | Meaning |
| :- | :- |
| `UnsupportedProtocol` | The protocol is not `HTTP` or `HTTPS`. |
| `PortUnavailable` | The Service of the data plane doesn't expose the port. |
| `ProtocolConflict`, `HostnameConflict` | The listener conflicts with another listener on the same port. |
| `InvalidCertificateRef` | A certificate reference doesn't refer to a valid `kubernetes.io/tls` Secret. |
| `RefNotPermitted` | A certificate reference refers to another namespace, and no `ReferenceGrant` allows it. |
| `InvalidRouteKinds` | The listener allows a route kind other than `HTTPRoute`. |

### HTTPRoute Conditions

Tyk Operator reports the conditions for each parent `Gateway` in `status.parents`:

| Condition | Status | Reason | Meaning |
| :- | :- | :- | :- |
| `Accepted` | `True` | `Accepted` | Tyk Operator has created the APIs for this parent. |
| `Accepted` | `False` | `NoMatchingParent` | Tyk Operator can't use the parent `Gateway`. The `Gateway` doesn't exist, belongs to another controller, or its `GatewayClass` or OperatorContext can't be read. Or no listener matches the parent reference. |
| `Accepted` | `False` | `NotAllowedByListeners` | The `allowedRoutes` of the listeners don't admit the route. |
| `Accepted` | `False` | `NoMatchingListenerHostname` | The hostnames of the route don't match the hostname of any listener. |
| `Accepted` | `False` | `UnsupportedValue` | The route uses a feature that Tyk Operator doesn't support. See [Unsupported Features](#unsupported-features). |
| `Accepted` | `False` | `EnvironmentUnresolved` | Tyk Operator can't read the Tyk Dashboard connection of the `GatewayClass`. Check its OperatorContext and Secret. |
| `Accepted` | `False` | `TranslationFailed` | Tyk Operator couldn't create or update the APIs in Tyk Dashboard. The message gives the error. |
| `Accepted` | `False` | `AttachmentConflict` | The attached Tyk OAS API definition conflicts with the route. See [Conflicts with the Route](https://tyk.io/docs/product-stack/tyk-operator/gateway-api/secure-and-extend-routes.md#conflicts-with-the-route). |
| `Accepted` | `False` | `BaseDocumentUnresolved` | Tyk Operator can't read the ConfigMap of the attached definition. It keeps using the last definition that it read. |
| `Accepted` | `False` | `BaseDocumentInvalid` | The attached definition isn't valid. |
| `Accepted` | `False` | `DataPlaneShared` | Another parent `Gateway` already serves this route on the same hostname and data plane. |
| `PartiallyInvalid` | `True` | `UnsupportedValue` | Tyk Operator serves part of the route. The message lists the rules that it dropped. |
| `ResolvedRefs` | `False` | `InvalidKind` | A backend reference is not a Kubernetes Service with a port. |
| `ResolvedRefs` | `False` | `RefNotPermitted` | A backend reference refers to another namespace, and no `ReferenceGrant` allows it. |
| `ResolvedRefs` | `False` | `BackendNotFound` | The Service doesn't exist. |

Tyk Operator also reports some problems as Kubernetes events on the route, such as `CertUploadFailed`, `DeletionFailed` and `CleanupBlocked`. To see them, run `kubectl describe httproute <name> -n <namespace>`.

### TykOasApiDefinition Conditions

Tyk Operator reports the result of an attached definition in the `Accepted` condition of the `TykOasApiDefinition`:

| Status | Reason | Meaning |
| :- | :- | :- |
| `True` | `Attached` | The definition applies to its target. |
| `False` | `NotAttached` | The target doesn't exist. |
| `False` | `BaseDocumentUnresolved` | The ConfigMap doesn't exist. |
| `False` | `DocumentInvalid` | `tykOAS.configmapRef` or its key is missing, the definition has no `x-tyk-api-gateway` object, or it sets a setting that comes from the route. |
| `False` | `AttachmentConflict` | Another definition that targets the same route or `Gateway` takes precedence, so this one has no effect. |
| `False` | `UnsupportedTarget` | `targetRefs` refers to a kind that isn't supported. |
| `Unknown` | `GatewayAPIUnavailable` | Kubernetes Gateway API support isn't enabled in Tyk Operator. |
