Skip to content
Livestream: Spring Launch Event - The Next Era of Duende Identity Infrastructure. Register Now!

BFF Extensibility

Duende.BFF is designed to be extended at multiple layers. Most production applications will use the defaults, but each area has well-defined extension points for when you need to go beyond the defaults.

AreaWhat You Can CustomizeDetail Page
Management EndpointsLogin, logout, user info, back-channel logout, diagnostics, silent login processingManagement Endpoints
Session StoreWhere server-side session data is persisted (custom database, cache, etc.)Session Management
HTTP ForwarderCustom HTTP clients, request/response transformations for proxied callsHTTP Forwarder
Token ManagementToken storage backend, per-route token retrieval (delegation, impersonation)Token Management

Each BFF management endpoint has a corresponding interface that you can implement to customize its behavior. In v4, the pattern is to map a custom route at the same path and call the default endpoint implementation, allowing you to add logic before and after default processing.

EndpointDefault PathInterface (v4)Interface (v3)Detail
Login/bff/loginILoginEndpointILoginServiceLogin Extensibility
Logout/bff/logoutILogoutEndpointILogoutServiceLogout Extensibility
User/bff/userIUserEndpointIUserServiceUser Extensibility
Silent Login/bff/silent-loginISilentLoginEndpointISilentLoginServiceSilent Login Extensibility
Back-Channel Logout/bff/backchannelIBackchannelLogoutEndpointIBackchannelLogoutServiceBack-Channel Logout Extensibility
Diagnostics/bff/diagnosticsIDiagnosticsEndpointIDiagnosticsServiceDiagnostics Extensibility

All management endpoint customizations in v4 follow the same pattern:

Program.cs
var bffOptions = app.Services.GetRequiredService<IOptions<BffOptions>>().Value;
app.MapGet(bffOptions.LoginPath, async (HttpContext context, CancellationToken ct) =>
{
// Custom logic before the default processing
var endpoint = context.RequestServices.GetRequiredService<ILoginEndpoint>();
await endpoint.ProcessRequestAsync(context, ct);
// Custom logic after the default processing
});

By default, BFF uses either an in-memory store or Entity Framework Core for server-side sessions. To use a different storage backend (Redis, custom database, etc.), implement IUserSessionStore:

builder.Services.AddBff()
.AddServerSideSessions<MyCustomSessionStore>();

See Session Management Extensibility for the full interface and implementation guidance.

When using MapRemoteBffApiEndpoint, BFF uses a default HTTP client and a default set of request/response transformations. You can customize:

  • The HTTP client — implement IForwarderHttpClientFactory to use a proxy, custom certificates, etc.
  • Request/response transformations — add custom headers, modify paths, or replace the default transformer entirely.

See HTTP Forwarder Extensibility for details.

BFF’s token management (powered by Duende.AccessTokenManagement) can be extended in two ways:

  • Custom token store — implement IUserTokenStore to store tokens outside of the session cookie or server-side session.
  • Per-route token retrieval — implement IAccessTokenRetriever for scenarios like token exchange or impersonation, where different API routes need different tokens.
app.MapRemoteBffApiEndpoint("/api/delegated", new Uri("https://api.example.com"))
.WithAccessToken(RequiredTokenType.User)
.WithAccessTokenRetriever<DelegationTokenRetriever>();

See Token Management Extensibility for details.