Skip to content

Custom resources (CRDs)

This page describes the CRDs (Custom Resource Definitions) of Traefik Hub.


Custom Resource Definitions

See the detailed reference guide, below, to learn more about CRD configurations related to API management.

To apply/install the up-to-date Traefik Hub CRDs in your cluster, please use the following command:

kubectl apply -f "https://hub.traefik.io/install/crd"

API

This CRD binds and configures an API specification to a service that implements it.

Field Description Required
metadata.name Unique name of an API.
We recommend using kebab-case, for example, my-api.
Yes
metadata.labels Labels and Selectors are used by APIAccess and APICollection to select APIs respectively. No
spec.pathPrefix The path prefix of the API, for example /customers.
The path prefix will append the URL of the API Gateway.
Yes
spec.currentVersion Marks an API as "versioned" and specifies the default version of the API in the API Portal.
If spec.currentVersion is used, the Service must be defined in the APIversion CRD.
No
service.name Name for the Service, we recommend using kebab-case, for example, my-app. Yes
service.port.number The Service port where the API is reachable. Yes
service.openApiSpec.url URL, pointing to a valid OpenAPI file.
The file can be external (hosted anywhere).
The Portal should be able to connect without any kind of authentication.
No
service.openApiSpec.path YAML and JSON are supported file formats for OpenAPI files. No
service.openApiSpec.port.number In most cases, the same as service.port.number.
Required by internal path setting.
No
cors.allowCredentials The header tells browsers whether to expose the response to the frontend JavaScript code when the request's credentials mode (Request.credentials) is include.
Docs on MDN.
No
cors.allowOriginList The header indicates whether the response can be shared with requesting code from the given origin.
Docs on MDN.
No
cors.allowOriginListRegex Indicates whether a resource can be shared by returning different values.
It allows all origins that contain any match of a regular expression in the Access-Control-Allow-Origin list.
Docs on MDN.
No
cors.allowHeaders Used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request.
Docs on MDN.
No
cors.ExposeHeaders Indicates which headers are safe to expose to the API of a CORS API specification.
Docs on MDN.
No
cors.allowMethods HTTP defines a set of request methods to indicate the action to be performed for a given resource.
Docs on MDN.
No
cors.MaxAge The header indicates how long the results of a preflight request (that is, the information contained in the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers) can be cached.
Docs on MDN
No

The API resource will not work without service.openApiSpec.url or service.openApiSpec.path configured.

An API resource defining both, a service and a currentVersion is not valid.

If you version your APIs with the APIVersion CRD you only need to configure CORS there

See the examples below.

Example

---
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
  name: petstore-api
  namespace: apps
  labels:
    area: customers
    module: crm
spec:
  pathPrefix: "/petstore"
  service:
    name: petstore-app
    port:
      number: 3000
    openApiSpec:
      url: https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.yaml
---
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
  name: customer-api
  namespace: apps
  labels:
    area: customers
    module: crm
spec:
  pathPrefix: "/customers"
  service:
    name: customer-app
    port:
      number: 3000
    openApiSpec:
      path: /openapi.yaml
      port:
        number: 3000
---
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
  name: customer-api
  namespace: apps
  labels:
    area: customers
    module: crm
spec:
  pathPrefix: "/customers"
  currentVersion: customers-v2
  # The Service definition is part of the APIVersion CRD
---
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
  name: customer-api
  namespace: apps
  labels:
    area: customers
    module: crm
spec:
  pathPrefix: "/customers"
  service:
    openApiSpec:
      path: /openapi.yaml
      port:
        number: 3000
    name: customer-app
    port:
      number: 3000
  cors:
    allowCredentials: true
    allowOriginList:
      - "*"
    allowHeaders:
      - "Accept"
      - "Accept-Language"
      - "Content-Language"
      - "Content-Type"
      - "Authorization"
      - "X-TraefikLabs-User"
    allowMethods:
       - "GET"
       - "HEAD"
       - "POST"
       - "PUT"
       - "CONNECT"
       - "OPTIONS"
       - "TRACE"

APIAccess

This resource binds which APIs are made available, with who can access them.

Use Labels and Selectors to select APIs and API collections.

It is possible to combine apiCollectionSelector and apiSelector.

apiSelector and apiCollectionSelector basics

This won't select any APIs.

spec:
  // no apiSelector

This will select all APIs.

spec:
  apiSelector: {}

This will select all APIs with a label key equals to value.

spec:
  apiSelector:
    key: value
Field Description Required
groups Name of the user group(s) with permissions for the API(s).
Requires apiSelector.matchLabels, apiSelector.matchExpressions or a combination of both to select APIs.
Yes
apis.name Select APIs based on names
You can combine it with apiSelector.matchLabels and apiSelector.matchExpressions.
See Labels and Selectors.
No
apis.namespace Name of the Kubernetes Namespace used by the API(s) defined in apis.name.
This is required for apis.name
No
apiSelector.matchLabels Select APIs based on label matching: Equality-Based Requirements. No
apiSelector.matchExpressions Select APIs based on advanced labels expressions: Set-Based Requirements. No
apiCollectionSelector.matchLabels Select API Collections based on label matching: Equality-Based Requirements. No
apiCollectionSelector.matchExpressions Select API Collections based on advanced labels expressions: Set-Based Requirements. No

Example

The examples show different configuration options from configuring access by group to using a combination from API names, matchLables and matchExpressions.

---
apiVersion: hub.traefik.io/v1alpha1
kind: APIAccess
metadata:
  name: customer-support
spec:
  groups:
    - support
  apiSelector:
    matchLabels:
      area: customers
---
apiVersion: hub.traefik.io/v1alpha1
kind: APIAccess
metadata:
  name: customer-support
spec:
  groups:
    - support
  apis:
    - name: my-api-1
      namespace: my-ns
    - name: my-api-2
      namespace: my-ns
---
apiVersion: hub.traefik.io/v1alpha1
kind: APIAccess
metadata:
  name: customer-support
spec:
  groups:
    - support
  apiSelector:
    matchLabels:
      area: customers
---
# Example of combing selecting APIs by `name`, `matchLabels` and `matchExpressions`.
# The selected APIs will be "my-api-1", "my-api-2" and all APIs with the area Label sets to "product" and audience either "dev" or "admin".
apiVersion: hub.traefik.io/v1alpha1
kind: APIAccess
metadata:
  name: admin-access
spec:
  groups:
    - support
  apis:
    - name: my-api-1
      namespace: my-ns
    - name: my-api-2
      namespace: my-ns
  apiSelector:
    matchLabels:
      area: product
    matchExpressions:
      - operator: in
        key: audience
        value: ["dev", "admin"]

APIGateway

This resource configures an end point where APIs provided by an API Access object should be available.

Traefik Hub uses APIGateway and APIPortal resources to configure APIs.

In Traefik Hub, an API Gateway is the main entry point to all your APIs. This is where you define the public domains for your APIs and which APIs and API Collections you want to expose via an API Access.

To publish an API, the API must be present in an API Access policy and have an API Gateway endpoint.

Field Description Required
apiAccesses List of allowed API Accesses for the Gateway. Yes
customDomains Configure a custom domain name for the API Gateway, for example api.example.com.
This is an optional setting, if not configured, Traefik Hub will generate a random domain under the traefikhub.io namespace.
No

Example

---
apiVersion: hub.traefik.io/v1alpha1
kind: APIGateway
metadata:
  name: my-gateway
  labels:
    area: crm
spec:
  apiAccesses:
    - customer-admin
    - crm-collections
    - crm-apis
    - custom-pick
  customDomains:
    - api.example.com
    - www.api.example.com

Production deployments

We highly recommend the use of custom domains for production deployments!

Domains generated by Traefik Hub will change with every redeployment, resulting in a new domain.


APIPortal

This resource configures an API portal in Traefik Hub.

Traefik Hub uses APIPortal and APIGateway resource to configure APIs.

In Traefik Hub, the API Portal is the landing page for consumers of APIs or API Collections. In the Portal, the consumer can view a representation of the OpenAPI specification and effortlessly interact and try out every API operation.

Field Description Required
title A title for the Portal, for example, your company name. No
description A short description of the Portal.
It will be displayed next to the title.
No
apiGateway Name of the APIGateway used by the Portal. Yes
customDomains Configure custom domain name for the API Portal, for example dev.example.com.
This is an optional setting, if not configured, Traefik Hub will generate a random domain under the traefikhub.io namespace.
No
ui.service Configuration for custom API Portals.
If not configured, the default Portal UI is used. If you use a custom Portal service, name and port are required. namespace is an optional setting.
No

Example

---
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortal
metadata:
  name: my-api-portal
spec:
  title: "The Portal"
  description: "The Ultimate Portal NG Digital Deluxe Edition"
  apiGateway: my-gateway
  customDomains:
    - "dev.example.com"
  ui:
    logoUrl: https://traefik.io/favicon.png
    service:
      name: hub-apiportal-ui
      namespace: default
      port: 8080

Production deployments

We highly recommend the use of custom domains for production deployments!

Domains generated by Traefik Hub will change with every redeployment, resulting in a new domain.


APICollection

This resource configures API Collections.

Collections are used to logically group APIs based on their labels.

Collections are API groupings

Field Description Required
pathPrefix PathPrefix used by the collection, for example /crm.
The PathPrefix will append the URL of the API Gateway.
This would make the API collection accessible under api.example.com/crm.
Only absolute paths are accepted for this setting.
No
apis.name Select APIs based on names
You can combine it with apiSelector.matchLabels and apiSelector.matchExpressions.
See Labels and Selectors.
No
apis.namespace Name of the Kubernetes Namespace used by the API(s) defined in apis.name.
This is required for apis.name.
No
apiSelector.matchLabels Select APIs based on label matching: Equality-Based Requirements. No
apiSelector.matchExpressions Select APIs based on advanced labels expressions: Set-Based Requirements. No

Example

apiVersion: hub.traefik.io/v1alpha1
kind: APICollection
metadata:
  name: crm-all
  labels:
    module: crm
spec:
  apis:
    - name: my-api-1
      namespace: my-ns
    - name: my-api-2
      namespace: my-ns
apiVersion: hub.traefik.io/v1alpha1
kind: APICollection
metadata:
  name: crm-all
  labels:
    module: crm
spec:
  pathPrefix: "/crm"
  apiSelector:
    matchLabels:
      module: crm
apiVersion: hub.traefik.io/v1alpha1
kind: APICollection
metadata:
  name: crm-all
  labels:
    module: crm
spec:
  pathPrefix: "/crm"
  apiSelector:
    matchExpressions:
      - key: area
        operator: In
        values:
          - flights
          - support

APIRateLimit

This resource configures rate limiting.

Read our detailed docs about rate limiting to learn more about how it works.

Field Description Required
limit Number of allowed requests per defined time period. Yes
period Time period can be seconds, minutes or hours (s/m/h). Default value is one second. No
anyGroups Using anyGroups will rate limit all groups which are defined with apiSelector.matchLabels or apiSelector.matchExpressions.
See the APIAccess reference for more information.
No
groups Name of the group(s) which will be rate limited.
See the user management reference for more information.
No
apis.name Select APIs based on names
You can combine it with apiSelector.matchLabels and apiSelector.matchExpressions.
See Labels and Selectors.
No
apis.namespace Name of the Kubernetes Namespace used by the API(s) defined in apis.name.
This is required for apis.name
No
apiSelector.matchLabels Select APIs based on label matching: Equality-Based Requirements. No
apiSelector.matchExpressions Select APIs based on advanced labels expressions: Set-Based Requirements. No

You must configure either anyGroups or groups for rate limiting.

Without setting one of them, rate limiting will not be applied.

See the examples below.

Examples

apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
  name: my-rate-limit

spec:
  # Rate limit configuration, this config allows 100 requests in one minute.
  limit: 100 # 100 requests
  period: 1m # One minute
  groups:
    - support
  apis:
    - name: my-api-1
      namespace: my-ns
    - name: my-api-2
      namespace: my-ns
apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
  name: my-rate-limit

spec:
  # Rate limit configuration, this config allows 100 requests in one minute.
  limit: 100 # 100 requests
  period: 1m # One minute

  groups:
    - support

  apiSelector:
    matchLabels:
      module: crm
apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
  name: my-rate-limit

spec:
  # Rate limit configuration, this config allows 100 requests in one minute.
  limit: 100 # 100 requests
  period: 1m # One minute

  groups:
    - support

  apiSelector:
    matchExpressions:
      - key: area
        operator: In
        values:
          - flights
          - tickets
          - employee
apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
  name: my-rate-limit

spec:
  # Rate limit configuration, this config allows 100 requests in one minute.
  limit: 100 # 100 requests
  period: 1m # One minute

  groups:
    - support
    - travel-agents

  apiSelector:
    matchExpressions:
      - key: area
        operator: In
        values:
          - flights
          - tickets
          - employee
apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
  name: my-rate-limit

spec:
  # Rate limit configuration, this config allows 100 requests in one minute.
  limit: 100 # 100 requests
  period: 1m # One minute

  anyGroups: true

  apiSelector:
    matchExpressions:
      - key: area
        operator: In
        values:
          - flights
          - tickets
          - employee

APIVersion

This resource configures API versioning.

Field Description Required
apiName Name of the API, see API CRD reference for more information. Yes
release Release number following SemVer (Semantic Versioning).
release isn't tied to the defined version matcher(s) of your API.
Yes
title Human friendly name of the release which will be displayed in the UI overview of an API. No
stripPathPrefix Remove prefixes from the URL path.
For example, if the pathPrefix is set to /v1.0, /v1.0 will be removed from the path when passing the request to the service.
No
routes[n].pathPrefix The URL prefix identifying the API version.
It is possible to use multiple pathPrefix and to use it together with headers and queryParams.
Check the advanced examples below.
No
routes[n].headers Set the version number using custom headers in requests and responses.
It is possible to use multiple headers and to use it together with pathPrefix and queryParams.
Check the advanced examples below for more info.
No
routes[n].queryParams Use query parameter for versioning.
It is possible to use multiple queryParams, for example, version:v2.0.0 and lang:fr.
queryParams can be used together with pathPrefix and headers.
See the examples below.
No
cors.allowCredentials The header tells browsers whether to expose the response to the frontend JavaScript code when the request's credentials mode (Request.credentials) is include.
Docs on MDN.
No
cors.allowOriginList The header indicates whether the response can be shared with requesting code from the given origin.
Docs on MDN.
No
cors.allowOriginListRegex Indicates whether a resource can be shared by returning different values.
It allows all origins that contain any match of a regular expression in the Access-Control-Allow-Origin list.
Docs on MDN.
No
cors.allowHeaders Used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request.
Docs on MDN.
No
cors.ExposeHeaders Indicates which headers are safe to expose to the API of a CORS API specification.
Docs on MDN.
No
cors.allowMethods HTTP defines a set of request methods to indicate the action to be performed for a given resource.
Docs on MDN.
No
cors.MaxAge The header indicates how long the results of a preflight request (that is, the information contained in the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers) can be cached.
Docs on MDN
No

If you don't configure routes[n].pathPrefix, routes[n].headers or routes[n].queryParams for versioning, APIs will still be reachable under the prefix configured in the API CRD but treated as non versioned.

Examples

See the following versioning examples:

---
# Example of versioning an API using `pathPrefix` for URI path.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
  name: my-flights-api-v2
  namespace: apps
spec:
  # The API this version is referencing (assumed to be in the same namespace).
  apiName: flight-api
  # SemVer of the release
  release: v2.0.0
  title: "An awesome title for this release, like a cheese name"
  routes:
    # The API will be available on one route using URI path for versioning.
    # Example: curl https://api.example.com/flights/v2.0.0
    - pathPrefix: "/v2.0.0"
  # The path prefix of the route will be removed and not forwarded with the request.
  stripPathPrefix: true
  service:
    name:  flights-svc-v2
    port:
      number: 8080
    openApiSpec:
      path: /api/v2/openapi.json
      port:
        number: 8080
---
# Example of versioning an API using `headers`.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
  name: my-flights-api-v2
  namespace: apps
spec:
  # The API this version is referencing (assumed to be in the same namespace).
  apiName: flight-api
  # SemVer of the release
  release: v2.0.0
  title: "An awesome title for this release, like a cheese name"
  routes:
    # The API will be available on one route using a custom header for versioning.
    # Example: curl -H "Version: v2.0.0" https://api.example.com/flights
    - headers:
        Version: "v2.0.0"
  service:
    name:  flights-svc-v2
    port:
      number: 8080
    openApiSpec:
      path: /api/v2/openapi.json
      port:
        number: 8080
---
# Example of versioning an API using a media type headers.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
  name: my-flights-api-v2
  namespace: apps
spec:
  # The API this version is referencing (assumed to be in the same namespace).
  apiName: flight-api
  # SemVer of the release
  release: v2.0.0
  title: "An awesome title for this release, like a cheese name"
  routes:
    # The API will be available on one route using a `media type` header for versioning.
    # Example: curl -H "Content: application/vnd.example.v2.0.0+json" https://api.example.com/flights
    - headers:
        Content: "application/vnd.example.v1+json"
  service:
    name:  flights-svc-v2
    port:
      number: 8080
    openApiSpec:
      path: /api/v2/openapi.json
      port:
        number: 8080
---
# Example of versioning an API using `queryParams` for query parameter versioning.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
  name: my-flights-api-v2
  namespace: apps
spec:
  # The API this version is referencing (assumed to be in the same namespace).
  apiName: flight-api
  # SemVer of the release
  release: v2.0.0
  title: "An awesome title for this release, like a cheese name"
  routes:
    # The API will be available at one route, using a version `query parameter`.
    # Example: curl https://api.example.com/flights?version=2.0.0
    - queryParams:
        version: "v2.0.0"
  service:
    name:  flights-svc-v2
    port:
      number: 8080
    openApiSpec:
      path: /api/v2/openapi.json
      port:
        number: 8080
---
# Example of versioning an API using two `queryParams`, version and language.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
  name: my-flights-api-v2
  namespace: apps
spec:
  # The API this version is referencing (assumed to be in the same namespace).
  apiName: flight-api
  # SemVer of the release
  release: v2.0.0
  title: "An awesome title for this release, like a cheese name"
  routes:
    # The API will be available at one route, both `queryParams` constraints must match.
    # Example: curl https://api.example.com/flights?version=2.0.0&lang=fr
    - queryParams:
        version: "v2.0.0"
        lang: "fr"
  service:
    name:  flights-svc-v2
    port:
      number: 8080
    openApiSpec:
      path: /api/v2/openapi.json
      port:
        number: 8080
---
# Example of versioning an API using `pathPrefix` for URI path and CORS.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
  name: my-flights-api-v2
  namespace: apps
spec:
  # The API this version is referencing (assumed to be in the same namespace).
  apiName: my-versioned-flights-api
  # SemVer of the release
  release: v2.0.0
  title: "An awesome title for this release, like a cheese name"
  routes:
    # The API will be available on one route using URI path for versioning.
    # Example: curl https://api.example.com/flights/v2.0.0
    - pathPrefix: "/v2.0.0"
  # The path prefix of the route will be removed and not forwarded with the request.
  stripPathPrefix: true
  service:
    name:  flights-svc-v2
    port:
      number: 8080
    openApiSpec:
      path: /api/v2/openapi.json
      port:
        number: 8080
  cors:
    allowCredentials: true
    allowOriginList:
      - "*"
    allowHeaders:
      - "Accept"
      - "Accept-Language"
      - "Content-Language"
      - "Content-Type"
      - "Authorization"
      - "X-TraefikLabs-User"
    allowMethods:
       - "GET"
       - "HEAD"
       - "POST"
       - "PUT"
Combining routes (Advanced)

It is possible to define multiple routes for API versions and Services.

  • An API can have a multiple version routes
  • An API can use multiple constraints on a route
  • It is possible to use different route types per API version

Be aware of the subtile configuration differences.

If you want to make an API available on different routes, for example versioning an API using pathPrefix OR header define one block per route.

routes:
  # The API will available at two routes.
  # 1. At the URI version path https://api.example.com/flights/v2.0.0
  - pathPrefix: "/v2.0.0"
  # 2. At the URI https://api.example.com/flights using a `header`.
  - headers:
      Content: "application/vnd.example.v2+json"

If you want to use a constraint that must match, for example, a pathPrefix AND a header, define the array item as a map.

routes:
  # The API will be available at one route and both constraints must match.
  # Example: curl -H "Content: application/vnd.example.v2+json" https://api.example.com/flights/v2.0.0
  - pathPrefix: "/v2.0.0"
    headers:
      Content: "application/vnd.example.v2+json"

See the following examples:

---
# Example of versioning an API using `pathPrefix` and `header`.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
  name: my-flights-api-v2
  namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: my-versioned-flights-api
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
  # The API will available at two routes.
  # 1. At the URI version path https://api.example.com/flights/v2.0.0
  - pathPrefix: "/v2.0.0"
  # 2. At the URI https://api.example.com/flights using a `header`.
  - headers:
      Content: "application/vnd.example.v2+json"
# The path prefix of the route will be removed and not forwarded with the request.
stripPathPrefix: true
service:
  name:  flights-svc-v2
  port:
    number: 8080
  openApiSpec:
    path: /api/v2/openapi.json
    port:
      number: 8080
---
# Example of versioning an API using a constraint of `pathPrefix` and `header`.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
  name: my-flights-api-v2
  namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: my-versioned-flights-api
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
  # The API will be available at one route and both constraints must match.
  # Example: curl -H "Content: application/vnd.example.v2+json" https://api.example.com/flights/v2.0.0
  - pathPrefix: "/v2.0.0"
    headers:
      Content: "application/vnd.example.v2+json"
# The path prefix of the route will be removed and not forwarded with the request.
stripPathPrefix: true
service:
  name:  flights-svc-v2
  port:
    number: 8080
  openApiSpec:
    path: /api/v2/openapi.json
    port:
      number: 8080

What's next