Swagger UI in a BFF World: Making Swagger UI Work Natively With BFF Architectures
This article introduces a Swagger UI plugin that integrates natively with BFFs using the Swagger UI extension mechanism.
Join the DZone community and get the full member experience.
Join For FreeThis article introduces a Swagger UI plugin designed specifically for Backend-for-Frontend (BFF) architectures, along with working demos (with and without OIDC) that validate the approach end to end.
The Rise (and Return) of the BFF
Modern web security has shifted away from storing "tokens in the browser." XSS attacks, stricter browser privacy policies, and evolving OAuth recommendations have made Backend-for-Frontend (BFF) architectures the gold standard for secure web apps.
Interestingly, the BFF approach is not new. Many “old-school” web applications naturally separated browser-facing frontends from backend services using server-mediated sessions and cookies. Over time, the rise of single-page applications (SPAs) and direct API calls pushed the industry toward exposing access tokens to the browser. While convenient, this approach increased the attack surface and introduced subtle security risks. Today, organizations are coming back to BFF-style architectures, leveraging the lessons of the past with modern standards.
Industry authorities reinforce this trend:
- The IETF (Internet Engineering Task Force) highlights in its latest OAuth 2.0 guidance that using a BFF to issue secure, HttpOnly cookies is the best way to prevent token exfiltration.
- Okta recommends the BFF model to centralize token management on a trusted server, stating that it "centralizes all token management on a single, trusted server, reducing the attack surface and making the entire system more resilient to client-side attacks."
- Auth0 notes in their BFF overview that the pattern is essential to mitigate risks inherent in handling access tokens from public clients.
Why Swagger UI and BFFs Clash
In a BFF architecture, the back-end component is a confidential client that owns:
- HTTP sessions and HttpOnly cookies
- CSRF protection
- Token handling (when OIDC is used)
Because the BFF is a confidential client, we can often use the Authorization Code flow without PKCE, as the client secret is securely managed on the server.
Swagger UI, on the other hand, assumes a “public client” mindset:
- It makes direct API calls from the browser.
- It expects to inject Bearer tokens into headers (which a secure BFF should reject).
- It bypasses cookies and CSRF tokens required for security.
- It assumes pure SPA frontend-style authentication flows, often requiring PKCE with the Authorization Code flow.
This mismatch creates friction when trying to use Swagger UI in secure BFF setups.
A Different Approach: Swagger UI as a First-Class Frontend
Instead of compromising security to accommodate our documentation, this project treats Swagger UI as just another frontend client. Using Swagger UI’s official extension (plugin) mechanism, the UI is adapted to:
- Communicate only with the BFF (rather than direct API calls).
- Rely on cookies and sessions already established by the browser.
- Respect CSRF protection by including necessary headers.
- Require no OpenAPI spec changes.
- No proxying is needed.
To the best of my knowledge, this is the first fully working Swagger UI plugin built specifically to bridge this architectural gap.
What the Repository Demonstrates
The associated repository provides two complete, runnable environments:
1. Fully Working BFF Applications
- BFF without OIDC: Standard session/cookie handling.
- BFF with OIDC: Full token management on the server side.
Both demos showcase real session handling and CSRF protection in action.
2. A BFF-Enabled Swagger UI Extension
The extension is backend-agnostic. Although the demos use Java and Spring, the plugin can be reused with any stack — .NET, Python, Go, or Node.js — that utilizes Swagger UI.
This project has been tested with Swagger UI versions 5.30.1 through 5.31.0.
By default, the build uses the latest specified Swagger UI version. However, you can override this using a system property when running Maven. For example:
mvn clean package -Pfullbuild -Deffective-sw.ui.version=5.31.0
You can use any version number listed under the path bff\swagger-files, namely any one of the following: 5.30.1, 5.30.2, 5.30.3, 5.31.0.
What This Does Not Do
To keep the architecture clean, this solution avoids:
- OpenAPI spec mediation: The specification remains the "source of truth" and stays untouched.
- Back-end proxy layers: No custom Java/C# code is needed to "fix" the requests; the change happens at the UI level.
- Swagger UI forks: We use the official plugin API to ensure compatibility with future versions.
The OpenAPI specification remains untouched. Only Swagger UI behavior changes.
What’s Not Included (Yet)
This demo focuses on the handshake and communication. It does not currently coordinate:
- HTTP session timeouts
- Access and Refresh token lifetimes
Aligning these values — for example, an Access Token (60 mins) vs. a Refresh Token (90 days) — depends heavily on your specific security posture and UX requirements.
Who This Is For
This approach is ideal if you are:
- Moving toward a “No Tokens in the Browser” policy.
- Using a BFF architecture with cookies, sessions, and CSRF protection.
- Wanting Swagger UI to behave like a real frontend client without breaking security.
Closing Thoughts
Swagger UI is extensible by design, but that extensibility is rarely used to address architectural shifts like the BFF. This project proves that you can integrate cleanly with modern browser security models without compromising your development workflow.
The repository https://github.com/teq-niq/bff contains complete demos and detailed setup instructions for further exploration.
Opinions expressed by DZone contributors are their own.
Comments