APIPortalAuth
Configure API Portal authentication with the APIPortalAuth
Resource.
Introduction
The APIPortalAuth
resource provides a declarative way to configure authentication for your API Portal in Traefik Hub API Management. This resource works in both online and offline environments, allowing you to manage portal
authentication settings through Kubernetes manifests.
APIPortalAuth
enables per-namespace portal authentication overrides, allowing you to run different portal authentication methods on the same gateway by placing portals in different namespaces.
Now your workspace settings act as a "global default" that you can override on a per-namespace basis with CRDs.
When defined, the CRD configuration takes precedence over workspace-level dashboard settings, providing Infrastructure as Code capabilities for API Portal authentication configuration and is essential for offline environments where connectivity to the Traefik Hub Online Dashboard is restricted or unavailable.
Example Use Case: You can now have a customer-facing portal in the public
namespace using Auth0 authentication, an internal developer portal in the internal
namespace using Azure AD authentication, and a partner portal
in the partners
namespace using Keycloak authentication - all on the same gateway!
APIPortalAuth
supports OpenID Connect (OIDC) authentication, which includes:
- Configurable JWT claim mappings to user attributes
- Flexible attribute synchronization from the OIDC provider (online mode only)
- Support for popular identity providers like Auth0, Azure AD, and Keycloak
How APIPortalAuth Works
APIPortalAuth
uses OpenID Connect (OIDC) to authenticate users accessing your API Portal. Each APIPortalAuth
resource is namespace-scoped and must be explicitly referenced by an APIPortal
resource in the same namespace.
Configuration Example
OIDC authentication provides secure user authentication using OpenID Connect protocol.
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: oidc-auth
namespace: apps
spec:
oidc:
issuerUrl: https://auth.example.com
secretName: oidc-credentials
claims:
groups: groups
userId: sub
email: email
firstname: given_name
lastname: family_name
scopes:
- openid
- profile
- email
- groups
Configuration Options
Field | Description | Required | Default |
---|---|---|---|
oidc | OIDC configuration object | Yes | - |
oidc.issuerUrl | OIDC provider issuer URL | Yes | - |
oidc.secretName | Name of Kubernetes Secret containing clientId and clientSecret | Yes | - |
oidc.claims | JWT claim mappings for user attributes | Yes | - |
oidc.claims.groups | JWT claim for user groups (required for authorization) | Yes | - |
oidc.claims.userId | JWT claim for user ID mapping | No | - |
oidc.claims.email | JWT claim for user email | No | - |
oidc.claims.firstname | JWT claim for user first name | No | - |
oidc.claims.lastname | JWT claim for user last name | No | - |
oidc.claims.company | JWT claim for user company | No | - |
oidc.scopes | OAuth2 scopes to request | No | - |
oidc.syncedAttributes | JWT claims to extract and sync to the Traefik Hub platform during authentication (online mode only). Each attribute must correspond to a configured claim. Valid values: groups , userId , firstname , lastname , email , company (max 6 items) | No | - |
- The
issuerUrl
must be a valid URL format - The
secretName
must be 253 characters or less - The
syncedAttributes
can contain at most 6 items and must be from the allowed values - Each attribute in
syncedAttributes
must correspond to a configured claim field
Client Secret Configuration
The APIPortalAuth
CRD requires a Kubernetes Secret containing the OIDC client credentials:
apiVersion: v1
kind: Secret
metadata:
name: oidc-credentials
namespace: apps
type: Opaque
data:
clientId: <base64-encoded-client-id>
clientSecret: <base64-encoded-client-secret>
Creating the Secret
- kubectl
- YAML
kubectl create secret generic oidc-client-secret \
--from-literal=clientId=your-client-id \
--from-literal=clientSecret=your-client-secret \
-n apps
apiVersion: v1
kind: Secret
metadata:
name: oidc-client-secret
namespace: apps
type: Opaque
data:
clientId: <base64-encoded-client-id>
clientSecret: <base64-encoded-client-secret>
Advanced Configuration
JWT Claim Mapping
Configure how JWT claims from your OIDC provider map to user attributes:
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: custom-claims
namespace: apps
spec:
oidc:
issuerUrl: https://auth.example.com
secretName: oidc-credentials
claims:
groups: https://example.com/groups # Custom groups claim
userId: user_id # Custom user ID claim
email: user_email # Custom email claim
company: organization # Custom company claim
firstname: first_name # Custom first name claim
lastname: last_name # Custom last name claim
OAuth2 Scopes
Configure the OAuth2 scopes requested during authentication:
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: scoped-auth
namespace: apps
spec:
oidc:
issuerUrl: https://auth.example.com
secretName: oidc-credentials
scopes:
- openid # Always required for OIDC
- profile # For basic profile information
- email # For email claim
- groups # For groups claim
claims:
groups: groups
email: email
Attribute Synchronization
Attribute synchronization configures which JWT claims should be extracted and stored by the Traefik Hub platform during OIDC authentication. These stored attributes are used for user management and portal functionality.
- Attribute synchronization requires online connectivity to the Traefik Hub platform. In offline mode, JWT claims are processed locally for authentication but are not synchronized to the platform.
- You can only synchronize attributes that you've also configured in the
claims
section. Each item insyncedAttributes
must correspond to a claim field you've defined.
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: synced-auth
namespace: apps
spec:
oidc:
issuerUrl: https://auth.example.com
secretName: oidc-credentials
claims:
groups: groups
userId: sub
email: email
firstname: given_name
lastname: family_name
syncedAttributes:
- groups # Synchronize group memberships
- email # Synchronize email addresses
- firstname # Synchronize first names
- lastname # Synchronize last names
In this example:
- The
claims
section maps JWT claims (groups
,sub
,email
, etc.) to user attributes - The
syncedAttributes
section specifies which of those mapped attributes should be sent to the Traefik Hub platform (online mode only) - When users authenticate in online mode, Traefik Hub will extract the
groups
,email
,given_name
, andfamily_name
values from their JWT tokens and store them
OAuth2 Provider Integration
Configure APIPortalAuth for popular OAuth2 providers:
- Auth0
- Azure AD
- Keycloak
- Okta
- Oracle OCI Identity
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: auth0-integration
namespace: apps
spec:
oidc:
issuerUrl: https://your-domain.auth0.com/
secretName: auth0-credentials
scopes:
- openid
- profile
- email
claims:
groups: https://your-domain.com/groups
userId: sub
email: email
firstname: given_name
lastname: family_name
---
apiVersion: v1
kind: Secret
metadata:
name: portal-oidc-secret
namespace: apps
type: Opaque
data:
clientId: <base64-encoded-client-id>
clientSecret: <base64-encoded-client-secret>
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: azure-ad-integration
namespace: apps
spec:
oidc:
issuerUrl: https://login.microsoftonline.com/your-tenant-id/v2.0
secretName: azure-ad-credentials
scopes:
- openid
- profile
- email
claims:
groups: groups
userId: oid
email: email
firstname: given_name
lastname: family_name
syncedAttributes:
- groups
- email
- firstname
- lastname
---
apiVersion: v1
kind: Secret
metadata:
name: azure-ad-credentials
namespace: apps
type: Opaque
data:
clientId: your-azure-app-id
clientSecret: your-azure-app-secret
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: keycloak-integration
namespace: apps
spec:
oidc:
issuerUrl: https://your-keycloak-domain.com/realms/your-realm
secretName: keycloak-credentials
scopes:
- openid
- profile
- email
claims:
groups: groups
userId: sub
email: email
firstname: given_name
lastname: family_name
syncedAttributes:
- email
---
apiVersion: v1
kind: Secret
metadata:
name: keycloak-credentials
namespace: apps
type: Opaque
data:
clientId: your-keycloak-client-id
clientSecret: your-keycloak-client-secret
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: okta-integration
namespace: apps
spec:
oidc:
issuerUrl: https://your-domain.okta.com # Tweak this to your custom auth server URL (if needed)
secretName: okta-credentials
scopes:
- openid
- profile
- email
- groups
claims:
groups: groups
userId: sub
email: email
firstname: given_name
lastname: family_name
syncedAttributes:
- groups
- email
- firstname
- lastname
---
apiVersion: v1
kind: Secret
metadata:
name: okta-credentials
namespace: apps
type: Opaque
data:
clientId: <base64-encoded-client-id>
clientSecret: <base64-encoded-client-secret>
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: oci-integration
namespace: apps
spec:
oidc:
issuerUrl: https://your-domain.identity.oraclecloud.com
secretName: oci-credentials
scopes:
- openid
- profile
- email
claims:
groups: groups
userId: sub
email: email
firstname: given_name
lastname: family_name
syncedAttributes:
- groups
- email
- firstname
- lastname
---
apiVersion: v1
kind: Secret
metadata:
name: oci-credentials
namespace: apps
type: Opaque
data:
clientId: <base64-encoded-client-id>
clientSecret: <base64-encoded-client-secret>
Integration with API Portal
- APIPortalAuth
- Secret
- APIPortal
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: portal-auth-config
namespace: apps
spec:
oidc:
issuerUrl: https://auth.company.com
secretName: portal-oidc-secret
scopes:
- openid
- profile
- email
- groups
claims:
groups: groups
userId: sub
email: email
firstname: given_name
lastname: family_name
company: organization
syncedAttributes:
- groups
- email
- firstname
- lastname
apiVersion: v1
kind: Secret
metadata:
name: portal-oidc-secret
namespace: apps
type: Opaque
data:
clientId: portal-client-id
clientSecret: portal-client-secret
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortal
metadata:
name: company-portal
namespace: apps
spec:
title: Company API Portal
description: "Official API documentation portal"
trustedUrls:
- https://portal.company.com
auth:
name: portal-auth-config # References APIPortalAuth resource
Validation
Use the Traefik Hub static analyzer to validate your APIPortalAuth configuration:
hub-static-analyzer lint --path [path/to/manifests] --offline
The analyzer will ensure all APIPortal
resources have an APIPortalAuth
attached.
Migration from Traefik Hub Online Dashboard Configuration
When migrating from online dashboard portal authentication to APIPortalAuth CRDs:
- Export Current Settings: Note your OIDC configuration from the online dashboard
- Create APIPortalAuth Resource: Convert dashboard settings to APIPortalAuth CRD format
- Create Client Secret: Store OIDC client credentials in Kubernetes Secret
- Update APIPortal: Reference the APIPortalAuth resource in your APIPortal
- Test Authentication: Verify portal authentication works correctly
Migration Example
Traefik Hub Online Dashboard OIDC configuration:
- Issuer:
https://auth.company.com
- Client ID:
portal-client
- Groups claim:
groups
- Email claim:
email
Equivalent APIPortalAuth CRD:
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortalAuth
metadata:
name: migrated-auth
namespace: apps
spec:
oidc:
issuerUrl: https://auth.company.com
secretName: migrated-oidc-secret
claims:
groups: groups
email: email
---
apiVersion: v1
kind: Secret
metadata:
name: migrated-oidc-secret
namespace: apps
type: Opaque
data:
clientId: portal-client
clientSecret: your-client-secret
Related Content
- Learn more about the APIAuth in its dedicated section.
- Learn more about the APIPortal in its dedicated section.
- Learn more about Offline Mode in its dedicated section.
- Learn more about Users and Groups in its dedicated section.