API
Manage APIs with Traefik Hub.
Introduction
APIs, or Application Programming Interfaces, serve as the foundational components of contemporary technology and business frameworks. Essentially, an API functions as a software intermediary facilitating communication between two distinct applications. This communication spans various connections: between servers themselves, applications and servers, between end-users and servers. Traefik Hub API management provides a set of tools and processes for managing these APIs effectively and at scale.
The implementation of an API is served by a Kubernetes Service and exposed by a Kubernetes Ingress, HTTPRoute, (or Traefik IngressRoute) object, which allows broad access to the API. However, most APIs require more precise control over access and usage. API owners need to regulate who can use their API and how much they can utilize it. They also need tools to monitor usage, identify patterns, and effectively manage the API's lifecycle.
In such cases, the API can be elevated to a managed status.
This is achieved by creating an API object, which is then linked to the API exposure object (Ingress, IngressRoute or HTTPRoute).
Once promoted, the API can be controlled through other objects:
- APIPlan to control usage limits, regulating how much of the API can be utilized.
- APIBundle to group one or more APIs together, enabling efficient management through plans.
- APIVersion to manage multiple versions of the API.
- Managed Subscription to allow API managers to grant access to APIs for specific applications based on pre-negotiated agreements with API consumers.
When your backend APIs require specific authentication credentials, you can implement upstream authentication patterns using Traefik Hub middlewares to automatically inject the required authentication headers or parameters.
The API Object
The API object serves as the foundation for managing an API. It defines the specification or the versions of your API. Since APIs can evolve and sometimes require multiple versions, API objects are categorized into two groups:
- Standalone API: Contains the definition of a single version.
- Versioned API: References APIVersion objects, each providing the definition of a separate version.
The definition of an API is provided by its OpenAPI specification document. This document is served either by the Kubernetes Service or at a remote location. When configured, the specification is used by the APIPortal for displaying the documentation of the API and used for advance access management.
Traefik Hub regularly fetches your OpenAPI specification to ensure that your definition remains aligned with your implementation.
The APIPortal dynamically renders documentation based on your API specification.
When testing endpoints via the "Send API Request" button, the call is made in accordance with the OpenAPI servers field specified in your API specification.
You have the option to override this value within the API object by providing a new list of servers in the override field:
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: hello-api
namespace: apps
spec:
openApiSpec:
path: /openapi.yaml
override:
servers:
- url: https://api.example.com/hello
The OpenAPI specification can be omitted when no such document exists. In this case, some of the Traefik Hub features won't be available.
The resource defining the API specification (API or APIVersion object) is then linked to the resource responsible for exposing the API's implementation. This link is established by adding an annotation to the Ingress object, as shown in the following section.
Once an API becomes managed by Traefik Hub, application access needs to be granted using a Managed Subscription object or a Self Service Subscription.
Middlewares can be added to Ingress, IngressRoute, and HTTPRoute in a similar manner as in Traefik.
API authentication occurs prior to the execution of any configured middlewares. Advanced operation filtering is performed after all the configured middlewares have been executed.
Standalone API
This example presents how an existing API exposed by an Ingress can be promoted into a managed API:
- Ingress
- IngressRoute
- HTTPRoute
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-api-ingress
namespace: apps
spec:
rules:
- host: api.example.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: hello-api-service
port:
number: 8080
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: hello-api-ingress
namespace: apps
spec:
routes:
- match: Host(`api.example.com`)
kind: Rule
services:
- name: hello-api-service
port: 8080
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: hello-api-httproute
namespace: apps
spec:
parentRefs:
- name: your-gateway
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: "/"
backendRefs:
- name: hello-api-service
port: 8080
Let's promote this API. The first thing to do is to create a new API object:
- Local OpenAPI specification
- Remote OpenAPI specification
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: hello-api
namespace: apps
spec:
openApiSpec:
# This is the path, within the hello-api-service, where Hub can find the Open API specification
path: /openapi.yaml
This path indicates where to find the OpenAPI specification document. The Kubernetes Service referenced in the Ingress object where the API is attached will be called on this exact path. It directly accesses the Service without considering any middlewares defined on the Ingress object. If the Ingress object includes multiple rules, only the Kubernetes Service defined in the first rule will be accessed.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: hello-api
namespace: apps
spec:
openApiSpec:
# This is the remote URL where Hub can find the OpenAPI specification
url: https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.yaml
Finally, we can complete the promotion by linking the API object to the Ingress, IngressRoute or HTTPRoute, object. This is done using
the hub.traefik.io/api annotation.
- Ingress
- IngressRoute
- HTTPRoute
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-api-ingress
namespace: apps
annotations:
hub.traefik.io/api: hello-api # Name of the API object
spec:
rules:
- host: api.example.com
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: hello-api-service
port:
number: 8080
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: hello-api-ingress
namespace: apps
annotations:
hub.traefik.io/api: hello-api # Name of the API object
spec:
routes:
- match: Host(`api.example.com`)
kind: Rule
services:
- name: hello-api-service
port: 8080
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: hello-api-httproute
namespace: apps
annotations:
hub.traefik.io/api: hello-api # Name of the API object
spec:
parentRefs:
- name: your-gateway
hostnames:
- "api.example.com"
rules:
- matches:
- path:
type: PathPrefix
value: "/"
backendRefs:
- name: hello-api-service
port: 8080
Please note that the API was created in the same namespace as the Ingress. It's possible to reference an API that is in a different namespace using the following syntax:
annotations:
hub.traefik.io/api: api-name@api-namespace # In our example it would be "hello-api@apps"
Cross-namespace reference support depends on the Ingress object used and therefore depends on the Traefik providers enabled:
- Ingress object, controlled by the Traefik provider
kubernetesIngress, supports cross-namespace, this capability can't be turned off. - IngressRoute object, controlled by the Traefik provider
kubernetesCRD, supports cross-namespace but the capability needs to be enabled. - HTTPRoute object, controlled by the Traefik provider
kubernetesGateway, supports cross-namespace references as per Gateway API specifications.
You can enable cross-namespace support on IngressRoute resources using the following install configuration:
- Helm Values
- Install Configuration
providers:
kubernetesCRD:
enabled: true
allowCrossNamespace: true
providers:
kubernetesCRD:
allowCrossNamespace: true
Versioned API
To configure a versioned API, please refer to the documentation page for APIVersion.
Title & Description
The API object supports title and description fields. These fields are shown in the API portal and override the corresponding values in the OpenAPI specification.
This is especially useful for adding custom content to the API portal that may differ from the default content provided by the API specification.
To add full Markdown pages or navigation links next to the API's Documentation tab in the portal, for example
a tutorial or a changelog, use a ContentItem resource.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: hello-api
namespace: apps
spec:
title: "Hello API"
description: "A simple API for greeting users."
openApiSpec:
path: /openapi.yaml
Operation Filtering
If you version your APIs with the APIVersion CRD, you only need to configure operation filtering there.
Operation filtering is a way to restrict user groups to a specific set of OpenAPI operations.
Imagine you have an API with the following use case:
- Only members of the
admingroup are allowed to delete customers. - Only members of the
admingroup are allowed to retrieve customer statistics - Members of the
supportgroup are allowed to retrieve a list with all customers
Configuring operation filtering is done in two steps.
You have to configure operationSets on your APIs, and reference these in your Managed Subscription &
API Catalog Item.
OperationSets
An operationSet is a named entity that selects one or many OpenAPI operations using matchers. These can then be referenced in ManagedSubscription
to grant access to specific operations to some user groups.
- Path
- Path Prefix
- Path Regex
- Only HTTP Method(s)
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: pets-operations # The name that will be used when referenced
matchers:
- path: /pets # The matcher `path` option defines the exact path of the spec operations to select
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: pets-operations # The name that will be used when referenced
matchers:
- pathPrefix: /pets # The matcher `pathPrefix` option defines the path prefix of the spec operations to select
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: pets-operations # The name that will be used when referenced
matchers:
- pathRegex: "/customers/.*/address" # The matcher `pathRegex` option defines the path regex of the matching spec operations to select
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: read-only # The name that will be used when referenced
matchers:
methods: # All operations with the following methods will be selected
- GET
- POST
- Only one of the following path settings is allowed:
path,pathPrefix, orpathRegex. - You can use the
methodsoption without using a path setting (path,pathPrefix, orpathRegex). - It is possible to combine a path setting with the
methodsoption. - The
pathRegexmust match both the OpenAPI specification and the request. For example, the request to/customers/:idshouldn't be expressed by/customers/[0-9]+but by/customers/.+to satisfy both/customers/{flightID}in the OAS specification and/customers/2in the actual request made by the user.
Please be aware that the difference between configuring one matcher with multiple options or configuring multiple matchers is subtle. The examples below show the difference in the syntax.
- One Matcher
- Two Matchers
operationSets:
- name: read-pets
matchers:
- pathPrefix: /pets
methods:
- GET
operationSets:
- name: read-or-path
matchers:
- pathPrefix: /pets
- methods:
- GET
Without a Defined HTTP Method
The following shows an API CRD using an operation matcher with pathPrefix, without any HTTP method defined.
This allows all operations on the /pets path prefix.
For example, GET /pets, GET /pets/{id}, POST /pets, PUT /pets/{id}.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: pets-operations
matchers:
- pathPrefix: /pets
Every Matcher Option Must Align
The following example shows an API CRD using one matcher with two options.
One doing path prefix filtering and one doing method filtering.
Both options must be fulfilled.
Setting a matcher with two options, such as pathPrefix and methods (acts as a logical AND).
This allows GET for all operations matching the /pets path prefix.
For example, GET /pets, GET /pets/{id}, GET /pets/findByStatus.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: read-pets
matchers:
- pathPrefix: /pets
methods:
- GET
One of the Two Matchers Must Match
The following example shows an API CRD using a combination of two matchers.
One doing path prefix filtering and one doing method filtering.
One of the matchers must fulfil.
Setting two matchers, one with pathPrefix and the other with methods (act as a logical OR).
This allows all operations on the /pets path prefix.
This allows GET operations on all endpoints of the API.
For example, GET /pets, GET /pets/{id}, GET /pets/findByStatus, POST /pets, PUT /pets, DELETE /pets/{id}, GET /dogs, GET /dogs/{id}.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
spec:
openApiSpec:
path: /api/v3/openapi.json
operationSets:
- name: read-or-path
matchers:
- pathPrefix: /pets
- methods:
- GET
validateRequestMethodAndPath
By default, when you expose an API, all endpoints of your Kubernetes Service are available, even if they are not mentioned in your OpenAPI specification. This can lead to possible security concerns or “zombie” endpoints.
To prevent requests from reaching paths or methods that are not defined in the OpenAPI
specification, you can set the validateRequestMethodAndPath option to true in the API’s
openApiSpec section. When this field is set,
any request to an undefined path or method results in a 404 Not Found status code.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: hello-api
namespace: apps
spec:
openApiSpec:
path: /openapi.yaml
validateRequestMethodAndPath: true
Global Install Configuration
You can also enable or disable this feature globally in the install configuration. However, any per-API configuration takes precedence:
- Install Configuration
- CLI
hub:
apiManagement:
openApi:
validateRequestMethodAndPath: true
--hub.apiManagement.openApi.validateRequestMethodAndPath=true
When validateRequestMethodAndPath is set to true, it overrides the global default behavior. If you do not define it (or set it to false), Traefik Hub refers to the global install configuration.
By default, the global setting is false.
validateRequestBodySchema
When an API defines a JSON schema for its request body in the OpenAPI specification,
you can enforce that incoming requests conform to this schema by setting validateRequestBodySchema to true.
Traefik Hub validates request payloads against the schema defined for the matching content type,
checking for required fields, correct value types, and format constraints.
When validation fails, the request is rejected with a 400 Bad Request status code.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: hello-api
namespace: apps
spec:
openApiSpec:
path: /openapi.yaml
validateRequestBodySchema: true
Global Install Configuration
You can also enable or disable this feature globally in the install configuration. However, any per-API configuration takes precedence:
- Install Configuration
- CLI
hub:
apiManagement:
openApi:
validateRequestBodySchema: true
--hub.apiManagement.openApi.validateRequestBodySchema=true
When validateRequestBodySchema is explicitly set, it overrides the global default behavior.
If you do not define it, Traefik Hub refers to the global install configuration.
By default, the global setting is false.
OpenAPI Validation and the Middleware Chain
OpenAPI validation (both validateRequestMethodAndPath and validateRequestBodySchema) is performed by an internal middleware that runs
after all user-defined middlewares in the request chain. The following points describe how this affects the request lifecycle:
- Validation sees the post-rewrite path. If your
IngressRouteincludes path-rewriting middlewares such asreplacePathRegexorstripPrefix, validation receives the rewritten path that the upstream service will see, not the original client-facing path. - The OpenAPI specification must describe the upstream view of the API. The combination of
pathsand the prefix declared inservers[0].urlin your specification must match the post-rewrite path. Theoverride.serversfield on theAPIresource only adjusts how the API is presented in the API Portal; it does not transform the request before validation. - Body validation requires path resolution. Even when
validateRequestMethodAndPathisfalse, enablingvalidateRequestBodySchemastill requires Traefik Hub to locate the matching operation in the specification to retrieve its body schema. A request whose path is not present in the specification is rejected with400 Bad Request, regardless of payload correctness. - Unknown request body fields are accepted by default. OpenAPI Schema's default for
additionalPropertiesistrue. To reject payloads that contain undocumented fields, setadditionalProperties: falseon the relevant schema.
If you need the externally exposed path and the upstream path to differ, declare the upstream-facing path in the OpenAPI specification
(in paths or as the prefix of servers[0].url), and rely on path-rewriting middlewares to map the external path onto it.
CORS
If your API is accessed from a different domain (for instance, when the API Portal resides on a separate domain), you may need to enable Cross-Origin Resource Sharing (CORS).
Traefik Hub offers built-in support for CORS through the cors field in the API resource.
When the cors field is absent, no CORS headers are applied.
- API With CORS
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: my-api
namespace: default
spec:
openApiSpec:
path: /openapi.yaml
cors:
allowHeadersList:
- "*"
allowOriginsList:
- "*"
allowMethodsList:
- "*"
exposeHeadersList:
- "*"
addVaryHeader: true
allowCredentials: true
allowOriginListRegex:
- ".*"
maxAge: 86400
