Authentication in Backstage · Backstage Software Catalog and Developer Platform (2023)

The authentication system in Backstage serves two distinct purposes: sign-in andidentification of users, as well as delegating access to third-party resources. It is possible toconfigure Backstage to have any number of authentication providers, but onlyone of these will typically be used for sign-in, with the rest being used to provideaccess external resources.

Built-in Authentication Providers

Backstage comes with many common authentication providers in the core library:

  • Atlassian
  • Auth0
  • Azure
  • Bitbucket
  • Cloudflare Access
  • GitHub
  • GitLab
  • Google
  • Google IAP
  • Okta
  • OneLogin
  • OAuth2Proxy

These built-in providers handle the authentication flow for a particular serviceincluding required scopes, callbacks, etc. These providers are each added to aBackstage app in a similar way.

Configuring Authentication Providers

Each built-in provider has a configuration block under the auth section ofapp-config.yaml. For example, the GitHub provider:

auth: environment: development providers: github: development: clientId: ${AUTH_GITHUB_CLIENT_ID} clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}

See the documentation for a particular provider to see what configuration isneeded.

The providers key may have several authentication providers, if multipleauthentication methods are supported. Each provider may also have configurationfor different authentication environments (development, production, etc). Thisallows a single auth backend to serve multiple environments, such as running alocal frontend against a deployed backend. The provider configuration matchingthe local auth.environment setting will be selected.

Sign-In Configuration

NOTE: Identity management and the SignInPage in Backstage is NOT a methodfor blocking access for unauthorized users, that either requires additionalbackend implementation or a separate service like Google's Identity-AwareProxy. The identity system only serves to provide a personalized experienceand access to a Backstage Identity Token, which can be passed to backendplugins.

(Video) Hands on - Building developer portals with Backstage

Using an authentication provider for sign-in is something you need to configureboth in the frontend app, as well as the auth backend plugin. For informationon how to configure the backend app, see Sign-in Identities and Resolvers.The rest of this section will focus on how to configure sign-in for the frontend app.

Sign-in is configured by providing a custom SignInPage app component. It willrendered before any other routes in the app and is responsible for providing theidentity of the current user. The SignInPage can render any number of pages andcomponents, or just blank space with logic running in the background. In the endhowever it must provide a valid Backstage user identity through the onSignInSuccesscallback prop, at which point the rest of the app is rendered.

If you want to, you can use the SignInPage component that is provided by @backstage/core-components,which takes either a provider or providers (array) prop of SignInProviderConfig definitions.

The following example for GitHub shows the additions needed to packages/app/src/App.tsx,and can be adapted to any of the built-in providers:

+ import { githubAuthApiRef } from '@backstage/core-plugin-api';+ import { SignInPage } from '@backstage/core-components'; const app = createApp({ apis,+ components: {+ SignInPage: props => (+ <SignInPage+ {...props}+ auto+ provider={{+ id: 'github-auth-provider',+ title: 'GitHub',+ message: 'Sign in using GitHub',+ apiRef: githubAuthApiRef,+ }}+ />+ ),+ }, bindRoutes({ bind }) {

You can also use the providers prop to enable multiple sign-in methods, for exampleallows allowing guest access:

 const app = createApp({ apis,+ components: {+ SignInPage: props => (+ <SignInPage+ {...props}+ providers={['guest', {+ id: 'github-auth-provider',+ title: 'GitHub',+ message: 'Sign in using GitHub',+ apiRef: githubAuthApiRef,+ }]}+ />+ ),+ }, bindRoutes({ bind }) {

Sign-In with Proxy Providers

Some auth providers are so-called "proxy" providers, meaning they're meant to be usedbehind an authentication proxy. Examples of these areAWS ALB, Cloudflare Access,GCP IAP, and OAuth2 Proxy.

When using a proxy provider, you'll end up wanting to use a different sign-in page, asthere is no need for further user interaction once you've signed in towards the proxy.All the sign-in page needs to do is to call the /refresh endpoint of the auth providersto get the existing session, which is exactly what the ProxiedSignInPage does. The onlything you need to do to configure the ProxiedSignInPage is to pass the ID of the provider like this:

(Video) What is Backstage? (Explainer Video)

const app = createApp({ ..., components: { SignInPage: props => <ProxiedSignInPage {...props} provider="awsalb" />, },});

A downside of this method is that it can be cumbersome to set up for local development.As a workaround for this, it's possible to dynamically select the sign-in page based onwhat environment the app is running in, and then use a different sign-in method for localdevelopment, if one is needed at all. Depending on the exact setup, one might choose toselect the sign-in method based on the process.env.NODE_ENV environment variable,by checking the hostname of the current location, or by accessing the configuration APIto read a configuration value. For example:

const app = createApp({ ..., components: { SignInPage: props => { const configApi = useApi(configApiRef); if (configApi.getString('auth.environment') === 'development') { return ( <SignInPage {...props} provider={{ id: 'google-auth-provider', title: 'Google', message: 'Sign In using Google', apiRef: googleAuthApiRef, }} /> ); } return <ProxiedSignInPage {...props} provider="gcpiap" />; }, },});

When using multiple auth providers like this, it's important that you configure the differentsign-in resolvers so that they resolve to the same identity regardless of the method used.

Scaffolder Configuration (Software Templates)

If you want to use the authentication capabilities of the Repository Picker inside your software templates you will need to configure the ScmAuthApi alongside your authentication provider. It is an API used to authenticate towards different SCM systems in a generic way, based on what resource is being accessed.

To set it up, you'll need to add an API factory entry to packages/app/src/apis.ts. The example below sets up the ScmAuthApi for an already configured GitLab authentication provider:

createApiFactory({ api: scmAuthApiRef, deps: { gitlabAuthApi: gitlabAuthApiRef, }, factory: ({ gitlabAuthApi }) => ScmAuth.forGitlab(gitlabAuthApi),});

In case you are using a custom authentication providers, you might need to add a custom ScmAuthApi implementation.

For Plugin Developers

The Backstage frontend core APIs provide a set of Utility APIs for plugin developersto use, both to access the user identity, as well as third party resources.

Identity for Plugin Developers

For plugin developers, there is one main touchpoint for accessing the user identity: theIdentityApi exported by @backstage/core-plugin-api via the identityApiRef.

(Video) Authentication and Backstage user identity - Backstage with OrkoHunter

The IdentityApi gives access to the signed-in user's identity in the frontend.It provides access to the user's entity reference, lightweight profile information, anda Backstage token that identifies the user when making authenticated calls within Backstage.

When making calls to backend plugins, we recommend that the FetchApi is used, whichis exported via the fetchApiRef from @backstage/core-plugin-api. The FetchApi willautomatically include a Backstage token in the request, meaning there is no needto interact directly with the IdentityApi.

Accessing Third Party Resources

A common pattern for talking to third party services in Backstage isuser-to-server requests, where short-lived OAuth Access Tokens are requested byplugins to authenticate calls to external services. These calls can be madeeither directly to the services or through a backend plugin or service.

By relying on user-to-server calls we keep the coupling between the frontend andbackend low, and provide a much lower barrier for plugins to make use of thirdparty services. This is in comparison to for example a session-based system,where access tokens are stored server-side. Such a solution would require a muchdeeper coupling between the auth backend plugin, its session storage, and otherbackend plugins or separate services. A goal of Backstage is to make it as easyas possible to create new plugins, and an auth solution based on user-to-serverOAuth helps in that regard.

The method with which frontend plugins request access to third party services isthrough Utility APIs for each service provider. Theseare all suffixed with *AuthApiRef, for example githubAuthApiRef. For afull list of providers, see the@backstage/core-plugin-api reference.

Custom Authentication Provider

There are generic authentication providers for OAuth2 and SAML. These can reducethe amount of code needed to implement a custom authentication provider thatadheres to these standards.

Backstage uses Passport under the hood, which hasa wide library of authentication strategies for different providers. SeeAdd authentication provider for details on adding a newPassport-supported authentication method.

(Video) Introduction to Spotify Backstage (OSS version) (Demo)

Custom ScmAuthApi Implementation

The default ScmAuthAPi provides integrations for github, gitlab, azure and bitbucket and is created by the following code in packages/app/src/apis.ts:

ScmAuth.createDefaultApiFactory();

If you require only a subset of these integrations, then you will need a custom implementation of the ScmAuthApi. It is an API used to authenticate different SCM systems generically, based on what resource is being accessed, and is used for example, by the Scaffolder (Software Templates) and Catalog Import plugins.

The first step is to remove the code that creates the default providers.

 import { ScmIntegrationsApi, scmIntegrationsApiRef,+ ScmAuth, } from '@backstage/integration-react'; export const apis: AnyApiFactory[] = [...+ ScmAuth.createDefaultApiFactory(),... ];

Then replace it with something like this, which will create an ApiFactory with only a github provider.

export const apis: AnyApiFactory[] = [ createApiFactory({ api: scmAuthApiRef, deps: { githubAuthApi: githubAuthApiRef, }, factory: ({ githubAuthApi }) => ScmAuth.merge( ScmAuth.forGithub(githubAuthApi), ), });

If you use any custom authentication integrations, a new provider can be added to the ApiFactory.

The first step is to create a new authentication ref, which follows the naming convention of xxxAuthApiRef. The example below is for a new GitHub enterprise integration which can be defined either inside the app itself if it's only used for this purpose or inside a common internal package for APIs, such as @internal/apis:

const gheAuthApiRef: ApiRef<OAuthApi & ProfileInfoApi & SessionApi> = createApiRef({ id: 'internal.auth.ghe', });

The new ref is then used to add a new provider to the ApiFactory:

(Video) Backstage Permissions Demo

createApiFactory({ api: scmAuthApiRef, deps: { gheAuthApi: gheAuthApiRef, githubAuthApi: githubAuthApiRef, }, factory: ({ githubAuthApi, gheAuthApi }) => ScmAuth.merge( ScmAuth.forGithub(githubAuthApi), ScmAuth.forGithub(gheAuthApi, { host: 'ghe.example.com', }), ),});

Finally, you also need to add and configure another provider to the auth-backend using the provider ID, which in this example is ghe:

import { providers } from '@backstage/plugin-auth-backend';// Add the following options to `createRouter` in packages/backend/src/plugins/auth.tsproviderFactories: { ghe: providers.github.create(),},

Videos

1. Using Backstage without the core plugins (Catalog, docs, templates) - Backstage with OrkoHunter
(OrkoHunter)
2. Backstage Service Catalog alpha (Live demo + feedback session, June 30, 2020 )
(Spotify R&D)
3. Software Catalog custom processors - Backstage with OrkoHunter
(OrkoHunter)
4. Speed developer onboarding with an Internal Developer Portal
(apiConnections)
5. Building an Internal Developer Platform with Backstage Plugins - Taras Mankovski
(CNCF [Cloud Native Computing Foundation])
6. LogRocket Meetup: Deep dive on backstage.Io
(LogRocket)
Top Articles
Latest Posts
Article information

Author: Kimberely Baumbach CPA

Last Updated: 02/09/2023

Views: 5826

Rating: 4 / 5 (41 voted)

Reviews: 80% of readers found this page helpful

Author information

Name: Kimberely Baumbach CPA

Birthday: 1996-01-14

Address: 8381 Boyce Course, Imeldachester, ND 74681

Phone: +3571286597580

Job: Product Banking Analyst

Hobby: Cosplaying, Inline skating, Amateur radio, Baton twirling, Mountaineering, Flying, Archery

Introduction: My name is Kimberely Baumbach CPA, I am a gorgeous, bright, charming, encouraging, zealous, lively, good person who loves writing and wants to share my knowledge and understanding with you.