Oauth 2.0 Single Sign-On with Backstage Navin Pai March 4, 2023

OAuth 2.0 Single Sign-On with Backstage

OpsVerse ONE,— built on top of the wonderful developer portal platform, Backstage aims to be the centralized location from which developers can access all the necessary documentation, resources, and tools for a particular platform or technology across any company. It enables developers to easily find what they need to build and integrate their services into the broader organization without having to search multiple sources or navigate through siloed sources of information elsewhere.

But when we first started working with Backstage, we found that Backstage documentation on securing access with custom OAuth2 authentication (which is something many of our customers consider critical to their developer portal setups) was lacking. While the documentation does mention OAuth2Proxy as a provider, we felt that the oauth2-proxy setup of having a middleman between all API calls was not necessary for us unless we had no other alternatives. It turned out we were right, and setting up OAuth2 authentication for Backstage is much easier—albeit with a few tricks.

Show me the Code!

Here’s how to configure OAuth2 authentication for Backstage:
In app-config.yaml add the following code:

        	clientId: "<Your ClientId>"
        	clientSecret: "<Your ClientSecret"
        	authorizationUrl: "<OAuth2 Authorization Endpoint>"
        	tokenUrl: "<OAuth2 Token Endpoint>"

Next, head over to packages/app/src/App.tsx and create a new ApiFactory and create a new ApiRef

import {
} from '@backstage/core-plugin-api';
import { OAuth2 } from '@backstage/core-app-api';

export const apis: AnyApiFactory[] = [
    // Add this at the end of the array
	api: opsverseAuthApiRef,
	deps: {
  	  discoveryApi: discoveryApiRef,
  	  oauthRequestApi: oauthRequestApiRef,
  	  configApi: configApiRef,
	factory: ({ discoveryApi, oauthRequestApi, configApi }) =>
    	defaultScopes: ['offline'], // Set scopes here
    	environment: configApi.getOptionalString('auth.environment'), // Set environment if needed here

export const opsverseAuthApiRef: ApiRef<
  OAuthApi &
	OpenIdConnectApi &
	ProfileInfoApi &
	BackstageIdentityApi &
> = createApiRef({
  id: 'internal.auth.opsverse',

Now, we can just use this new ApiRef as a sign in provider for our app. So let’s head over to packages/app/src/App.tsx and create a new sign in provider.

import { apis, opsverseAuthApiRef } from './apis';
import { AlertDisplay, OAuthRequestDialog, SignInPage, SignInProviderConfig } from '@backstage/core-components';

const oauthProvider: SignInProviderConfig = {
  id: 'oauth-auth-provider',
  title: 'Sign In',
  message: 'Sign in using OAuth2',
  apiRef: opsverseAuthApiRef,

const app = createApp({
  components: {
	SignInPage: props => (
  	<SignInPage {...props} auto={false} provider={oauthProvider} />
 bindRoutes({ bind }) {

And that’s it! When you try to access Backstage now, you’ll be greeted by the sign In page. Simply authenticate with your custom SSO backend and you’re good to go.

Backstage OAuth2 SignIn

OpsVerse ONE is a Developer Experience (DevEx) portal with micro services catalogs, docs, code quality, service dependencies, and more! Built on top of Backstage, OpsVerse One comes preconfigured with multiple plugins to provide engineering teams and managers end-to-end visibility into the delivery pipeline. If you’d like to try it out, head over to https://opsverse.io now!