Offline Self-Service
This feature is currently in early access.
By default, an offline Traefik Hub gateway runs without any connection to the platform, which means the API Portal cannot offer self-service applications, self-service subscriptions, or API key management.
Offline Self-Service closes that gap. By deploying the Traefik Hub Manager alongside the gateway and backing it with a self-hosted PostgreSQL database, you keep the gateway fully offline while still letting portal users create applications, subscribe to APIs, and manage API keys themselves.
Offline Self-Service is available for Kubernetes deployments of Traefik Hub API Management. Any Kubernetes gateway with an offline license token
can enable it by deploying Traefik Hub Manager and setting --hub.platformURL. See the installation steps for details.
How It Works
In Offline Self-Service mode, the gateway no longer talks to hub.traefik.io. Instead, it points at a Traefik Hub Manager service running in your cluster.
Traefik Hub Manager exposes a restricted API surface that only handles self-service objects, and persists them in PostgreSQL.
Every other resource — APIs, API plans, catalog items, portals, managed applications and subscriptions — is still defined as a Kubernetes CRD, exactly like in standard offline mode.
Prerequisites
- License Requirement: Offline Self-Service is a licensed feature. Access must be granted by the Traefik Labs sales team.
- License Token: Your token must include the
offlineclaim. - Kubernetes Cluster with
kubectland Helm v3. - A PostgreSQL instance reachable from the cluster.
- An OIDC identity provider or LDAP directory for the API Portal (see APIPortalAuth).
Components
| Component | Purpose |
|---|---|
| Traefik Hub Gateway | Routes traffic, enforces authentication, and forwards self-service calls to the Traefik Hub Manager. |
| Traefik Hub Manager | Manages self-service applications, subscriptions, and API keys, persisting them in PostgreSQL. Deployed via the hub-manager Helm chart. |
| PostgreSQL | Persists applications, API keys, and self-service subscriptions. API keys are encrypted at rest using an AES key you provide. |
Installation
The walkthrough below sets up a complete Offline Self-Service stack in a single traefik namespace.
Step 1: Create the Namespace and Secrets
Create the namespace, the license secret, and the secret that the Traefik Hub Manager uses for the PostgreSQL connection string and the API-key encryption key.
kubectl create namespace traefik
# License token
kubectl create secret generic traefik-hub-license \
--namespace traefik \
--from-literal=token='YOUR-OFFLINE-LICENSE-TOKEN'
# Example Postgres connection string and a 32-byte base64-encoded encryption key
kubectl create secret generic hub-manager-config \
--namespace traefik \
--from-literal=postgres-encryption-key="$(openssl rand -base64 32)"
postgres-encryption-key is used to encrypt API keys at rest. Store it securely, for example in your secret manager. Encrypted data is tied to the key it was created with, so losing the key makes existing API keys unrecoverable.
Step 2: Deploy PostgreSQL
Traefik Hub Manager requires a PostgreSQL instance reachable from the cluster. The example below uses the in-cluster Bitnami PostgreSQL chart with a default installation.
helm install traefik-hub-postgresql \
oci://registry-1.docker.io/bitnamicharts/postgresql \
--namespace traefik \
--set auth.postgresPassword=CHANGEME
Wait for the traefik-hub-postgresql-0 pod to be Ready before continuing:
kubectl rollout status statefulset/traefik-hub-postgresql --namespace traefik --timeout=3m
Step 3: Install Traefik Hub Manager
Add the Traefik Helm repository and install the hub-manager chart. The chart runs a pre-install Job that creates the PostgreSQL schema, then deploys
the Traefik Hub Manager service on port 80.
helm repo add --force-update traefik https://traefik.github.io/charts
helm install hub-manager traefik/hub-manager \
--namespace traefik \
--set token=traefik-hub-license \
--set postgres.uri=hub-manager-config \
--set postgres.encryptionKey=hub-manager-config
The three values reference Kubernetes Secret names — not their values. We've created them in a previous step. Traefik Hub Manager reads the following keys from those Secrets:
| Helm value | Secret key it looks up |
|---|---|
token | token |
postgres.uri | postgres-uri |
postgres.encryptionKey | postgres-encryption-key |
Verify Traefik Hub Manager is ready:
kubectl rollout status deployment/hub-manager --namespace traefik --timeout=2m
Step 4: Install Traefik Hub Gateway
Install the Traefik Hub Gateway with API Management and Offline Mode both enabled, and point it at the in-cluster Traefik Hub Manager service with --hub.platformURL.
- CLI
- Helm Values
helm install traefik traefik/traefik \
--namespace traefik \
--set hub.token=traefik-hub-license \
--set hub.offline=true \
--set hub.apimanagement.enabled=true \
--set "additionalArguments={--hub.platformURL=http://hub-manager.traefik.svc.cluster.local/agent}"
hub:
token: traefik-hub-license
offline: true
apimanagement:
enabled: true
additionalArguments:
- "--hub.platformURL=http://hub-manager.traefik.svc.cluster.local/agent"
Install with:
helm install traefik traefik/traefik \
--namespace traefik \
-f traefik-values.yaml
--hub.platformURLThis flag is only accepted when the license carries the offline claim. With an online license it returns a startup error; with an offline license but no --hub.platformURL the gateway runs in standard offline mode (no self-service).
Step 5: Configure the API Portal
Offline self-service requires the API Portal to authenticate consumers against an OIDC identity provider or LDAP directory. Create an APIPortalAuth and an
APIPortal, then expose the portal with an IngressRoute. The example below uses OIDC; see APIPortalAuth for the full
OIDC and LDAP reference.
- Secret
- APIPortalAuth
- APIPortal
- IngressRoute
apiVersion: v1
kind: Secret
metadata:
name: portal-oidc
namespace: traefik
stringData:
clientId: my-portal-client
clientSecret: my-portal-secret
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: portal-auth
namespace: traefik
spec:
oidc:
issuerUrl: https://auth.example.com/
secretName: portal-oidc
scopes:
- openid
- profile
- email
claims:
groups: groups
email: email
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortal
metadata:
name: portal
namespace: traefik
spec:
title: My Portal
trustedUrls:
- https://portal.example.com
auth:
name: portal-auth
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: portal
namespace: traefik
annotations:
hub.traefik.io/api-portal: portal@traefik
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`portal.example.com`)
services:
- name: apiportal
port: 9903
Step 6: Publish an API for Self-Service
Define an API, an APIAuth to protect it, an APIPlan, and an APICatalogItem. The APIPlan reference on the catalog item makes the API available for
self-service subscription in the portal.
- Backend
- OpenAPI Spec
- API
- APIAuth
- APIPlan
- APICatalogItem
- IngressRoute
apiVersion: apps/v1
kind: Deployment
metadata:
name: whoami
namespace: traefik
spec:
replicas: 1
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: traefik/whoami:v1.12.0
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: traefik
spec:
selector:
app: whoami
ports:
- port: 80
targetPort: 80
Since v1.12.0, whoami serves its own OpenAPI specification at GET /openapi.yaml. The gateway fetches
it directly from the whoami Service, so no separate spec server or internet egress is needed.
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: whoami-api
namespace: traefik
spec:
title: Whoami API
openApiSpec:
url: http://whoami.traefik.svc/openapi.yaml
apiVersion: hub.traefik.io/v1alpha1
kind: APIAuth
metadata:
name: default-auth
namespace: traefik
spec:
isDefault: true
apiKey: {}
apiVersion: hub.traefik.io/v1alpha1
kind: APIPlan
metadata:
name: default
namespace: traefik
spec:
title: "Default unlimited plan"
apiVersion: hub.traefik.io/v1alpha1
kind: APICatalogItem
metadata:
name: whoami-catalog
namespace: traefik
spec:
everyone: true
apis:
- name: whoami-api
apiPlan:
name: default
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: whoami
namespace: traefik
annotations:
hub.traefik.io/api: whoami-api
spec:
entryPoints:
- web
routes:
- kind: Rule
match: Host(`whoami.example.com`)
services:
- name: whoami
port: 80
Step 7: Subscribe and Test
-
Open the API Portal (
https://portal.example.com) and sign in with your OIDC provider or LDAP credentials. -
Create an Application.
-
Subscribe the Application to the Whoami API.
-
Generate an API key from the Application detail page and copy it.
-
Call the protected API:
# Without a key — deniedcurl -i https://whoami.example.com# HTTP/1.1 401 Unauthorized# With the generated key — allowedcurl -i -H "Authorization: Bearer YOUR-API-KEY" https://whoami.example.com# HTTP/1.1 200 OK
The application, the subscription, and the API key are now stored in PostgreSQL via Traefik Hub Manager. The gateway never reaches out to hub.traefik.io.
Configuration Options
Traefik Hub Manager Helm values
| Key | Type | Default | Description |
|---|---|---|---|
token | string | "" | Name of a Secret with key token set to a valid offline license token. |
postgres.uri | string | "" | Name of a Secret with key postgres-uri set to a PostgreSQL connection string. |
postgres.encryptionKey | string | "" | Name of a Secret with key postgres-encryption-key set to a base64-encoded AES key (16, 24, or 32 bytes after decoding). Generate it with, for example, openssl rand -base64 32 |
image.registry | string | "ghcr.io" | Image registry. |
image.repository | string | "traefik/hub-manager" | Image repository. |
image.tag | string | nil | Defaults to the chart's appVersion. |
logs.level | string | "INFO" | One of TRACE, DEBUG, INFO, WARN, ERROR, FATAL, PANIC. |
deployment.replicas | int | 1 | Number of Traefik Hub Manager replicas. Multiple replicas are supported. |
autoscaling.enabled | bool | false | Create an HPA for Traefik Hub Manager. |
tracing.address | string | "" | OTLP/HTTP endpoint for traces. |
tracing.insecure | bool | true | Use HTTP instead of HTTPS when sending traces. |
tracing.probability | string | "0.0" | Probability (0.0–1.0) of sampling a trace. |
Gateway flags
| Flag | Required | Description |
|---|---|---|
--hub.offline=true | Yes | Enables offline mode. Must match the offline claim on the license. |
--hub.apiManagement | Yes | Enables API Management features. |
--hub.platformURL | Yes | URL of the in-cluster Traefik Hub Manager service, including the /agent path (e.g. http://hub-manager.traefik.svc.cluster.local/agent). Only accepted with an offline license. |
Limitations
The following table shows what is available in each offline mode:
| Feature | Standard Offline | Offline Self-Service |
|---|---|---|
| APIs, APIPlans, APICatalogItems via CRDs | ✅ | ✅ |
| Managed Applications and Subscriptions via CRDs | ✅ | ✅ |
| API Portal authentication (OIDC or LDAP) | ✅ | ✅ |
| Self-service applications from the portal | ❌ | ✅ |
| Self-service subscriptions from the portal | ❌ | ✅ |
| API key generation from the portal | ❌ | ✅ |
| Identity provider sync (user attribute sync) | ❌ | ❌ |
| Workspace-level auth (local Hub Platform UI) | ❌ | ❌ |
| Multi-cluster dashboard (local dashboard still available) | ❌ | ❌ |
- Anonymous usage and version checks are turned off. Like standard offline mode, the gateway does not send telemetry, logs, or version checks to the platform.
- License renewal is local. A lapsed license gets a 30-day grace period to renew and rotate a new token before it turns off. Offline gateways can't check this; update the
tokenSecret only when rotating a new token. - Traefik Hub Manager is stateless. All state lives in PostgreSQL. You can scale it horizontally with
deployment.replicasorautoscaling.enabled.
Troubleshooting
The gateway logs endpoint /agent/<path> is not available in offline mode
The gateway is attempting to use a feature that is not supported in Offline Self-Service mode. For example, this can happen if the portal configuration relies on online-only identity provider synchronization. Check the Limitations table for what is and isn't available in this mode.
The gateway exits at startup with the --platform-url is only available with an offline license
--hub.platformURL only takes effect with an offline license. Either remove the flag, or obtain a license with the offline claim. Online licenses must not set this flag.
The gateway exits with offline mode configuration mismatch
The offline claim on the license must match --hub.offline. Set hub.offline=true in Helm values when the license is offline, and remove it when it isn't.
Traefik Hub Manager pod stays in CrashLoopBackOff with invalid license: token is not an offline token
The token in the token Secret is valid but does not carry the offline claim — usually an online token pasted by mistake. Re-copy the offline token from the Hub dashboard and recreate the Secret.
Traefik Hub Manager pod stays in CrashLoopBackOff with invalid license: extracting claims: ...
The token in the token Secret fails signature verification — it is malformed or was not issued by Traefik Hub. Re-copy the offline token from the Hub dashboard and recreate the Secret.
Portal forms hang or return a 500 when submitting
The portal forwards self-service requests through the gateway to Traefik Hub Manager. If Traefik Hub Manager or PostgreSQL is unreachable, the request times out and the portal returns a generic 500. Check:
kubectl get pods -n traefik: PostgreSQL andhub-managerpods should beRunning.kubectl logs deployment/hub-manager -n traefik: look for PostgreSQL connection errors.
Migration job fails with FATAL: unrecognized configuration parameter (SQLSTATE 42704)
The postgres-uri value must be a plain libpq-style connection string. DSN parameters prefixed with pool_ are not supported. Use a connection string in the form postgresql://user:password@host:5432/dbname?sslmode=require.
Related Content
- Learn more about Offline Mode in its dedicated section.
- Learn more about the APIPortal in its dedicated section.
- Learn more about the APIPortalAuth in its dedicated section.
- Learn more about Self-Service Subscriptions in its dedicated section.
- Learn more about the APIAuth in its dedicated section.
