diff --git a/app-config.yaml b/app-config.yaml
index 9b059da216..df0fd153f8 100644
--- a/app-config.yaml
+++ b/app-config.yaml
@@ -399,6 +399,10 @@ auth:
scopes: ${AUTH_ATLASSIAN_SCOPES}
myproxy:
development: {}
+ guest:
+ development:
+ clientId: t123
+ clientSecret: test123
costInsights:
engineerCost: 200000
engineerThreshold: 0.5
diff --git a/packages/app-defaults/src/defaults/apis.ts b/packages/app-defaults/src/defaults/apis.ts
index 4e9e1a492c..3285b05dcf 100644
--- a/packages/app-defaults/src/defaults/apis.ts
+++ b/packages/app-defaults/src/defaults/apis.ts
@@ -35,6 +35,7 @@ import {
createFetchApi,
FetchMiddlewares,
VMwareCloudAuth,
+ GuestAuth,
} from '@backstage/core-app-api';
import {
@@ -58,6 +59,7 @@ import {
bitbucketServerAuthApiRef,
atlassianAuthApiRef,
vmwareCloudAuthApiRef,
+ guestAuthApiRef,
} from '@backstage/core-plugin-api';
import {
permissionApiRef,
@@ -277,6 +279,21 @@ export const apis = [
});
},
}),
+
+ createApiFactory({
+ api: guestAuthApiRef,
+ deps: {
+ discoveryApi: discoveryApiRef,
+ configApi: configApiRef,
+ },
+ factory: ({ discoveryApi, configApi }) => {
+ return GuestAuth.create({
+ configApi,
+ discoveryApi,
+ environment: configApi.getOptionalString('auth.environment'),
+ });
+ },
+ }),
createApiFactory({
api: permissionApiRef,
deps: {
diff --git a/packages/app/src/App.tsx b/packages/app/src/App.tsx
index 3d8bd45e5a..5357ad4d16 100644
--- a/packages/app/src/App.tsx
+++ b/packages/app/src/App.tsx
@@ -128,7 +128,7 @@ const app = createApp({
return (
diff --git a/packages/app/src/identityProviders.ts b/packages/app/src/identityProviders.ts
index 66f1460210..9f2ed58e8d 100644
--- a/packages/app/src/identityProviders.ts
+++ b/packages/app/src/identityProviders.ts
@@ -23,6 +23,7 @@ import {
oneloginAuthApiRef,
bitbucketAuthApiRef,
bitbucketServerAuthApiRef,
+ guestAuthApiRef,
} from '@backstage/core-plugin-api';
export const providers = [
@@ -74,4 +75,10 @@ export const providers = [
message: 'Sign In using Bitbucket Server',
apiRef: bitbucketServerAuthApiRef,
},
+ {
+ id: 'guest-auth-provider',
+ title: 'Guest',
+ message: 'Sign in as a guest',
+ apiRef: guestAuthApiRef,
+ },
];
diff --git a/packages/backend/package.json b/packages/backend/package.json
index e6102b69cf..989d64eeec 100644
--- a/packages/backend/package.json
+++ b/packages/backend/package.json
@@ -35,6 +35,7 @@
"@backstage/plugin-adr-backend": "workspace:^",
"@backstage/plugin-app-backend": "workspace:^",
"@backstage/plugin-auth-backend": "workspace:^",
+ "@backstage/plugin-auth-backend-module-guest-provider": "^0.0.0",
"@backstage/plugin-auth-node": "workspace:^",
"@backstage/plugin-azure-devops-backend": "workspace:^",
"@backstage/plugin-azure-sites-common": "workspace:^",
diff --git a/packages/backend/src/plugins/auth.ts b/packages/backend/src/plugins/auth.ts
index 0d92315f92..773d3f4270 100644
--- a/packages/backend/src/plugins/auth.ts
+++ b/packages/backend/src/plugins/auth.ts
@@ -141,6 +141,8 @@ export default async function createPlugin(
},
},
}),
+
+ guest: providers.guest.create(),
},
});
}
diff --git a/packages/core-app-api/src/apis/implementations/auth/guest/GuestAuth.ts b/packages/core-app-api/src/apis/implementations/auth/guest/GuestAuth.ts
new file mode 100644
index 0000000000..88d4612973
--- /dev/null
+++ b/packages/core-app-api/src/apis/implementations/auth/guest/GuestAuth.ts
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import {
+ AuthRequestOptions,
+ BackstageIdentityApi,
+ ProfileInfo,
+ ProfileInfoApi,
+ SessionApi,
+ SessionState,
+ BackstageIdentityResponse,
+} from '@backstage/core-plugin-api';
+import { Observable } from '@backstage/types';
+import { DirectAuthConnector } from '../../../../lib/AuthConnector';
+import { RefreshingAuthSessionManager } from '../../../../lib/AuthSessionManager';
+import { SessionManager } from '../../../../lib/AuthSessionManager/types';
+import { AuthApiCreateOptions } from '../types';
+
+type GuestSession = {
+ profile: ProfileInfo;
+ backstageIdentity: BackstageIdentityResponse;
+};
+
+const DEFAULT_PROVIDER = {
+ id: 'guest',
+ title: 'Guest',
+ icon: () => null,
+};
+
+/**
+ * Implements a guest auth flow.
+ *
+ * @public
+ */
+export default class GuestAuth
+ implements ProfileInfoApi, BackstageIdentityApi, SessionApi
+{
+ static create(options: AuthApiCreateOptions) {
+ const {
+ discoveryApi,
+ environment = 'development',
+ provider = DEFAULT_PROVIDER,
+ } = options;
+
+ const connector = new DirectAuthConnector({
+ discoveryApi,
+ environment,
+ provider,
+ });
+
+ const sessionManager = new RefreshingAuthSessionManager({
+ connector,
+ defaultScopes: new Set([]),
+ sessionScopes: (_: GuestSession) => new Set(),
+ sessionShouldRefresh: (session: GuestSession) => {
+ let min = Infinity;
+ if (session.backstageIdentity?.expiresAt) {
+ min = Math.min(
+ min,
+ (session.backstageIdentity.expiresAt.getTime() - Date.now()) / 1000,
+ );
+ }
+ return min < 60 * 5;
+ },
+ });
+
+ return new GuestAuth({ sessionManager });
+ }
+
+ sessionState$(): Observable {
+ return this.sessionManager.sessionState$();
+ }
+
+ private readonly sessionManager: SessionManager;
+
+ private constructor(options: {
+ sessionManager: SessionManager;
+ }) {
+ this.sessionManager = options.sessionManager;
+ }
+
+ async signIn() {
+ await this.getBackstageIdentity({});
+ }
+ async signOut() {
+ await this.sessionManager.removeSession();
+ }
+
+ async getBackstageIdentity(
+ options: AuthRequestOptions = {},
+ ): Promise {
+ const session = await this.sessionManager.getSession(options);
+ return session?.backstageIdentity;
+ }
+
+ async getProfile(options: AuthRequestOptions = {}) {
+ const session = await this.sessionManager.getSession(options);
+ return session?.profile;
+ }
+}
diff --git a/packages/core-app-api/src/apis/implementations/auth/guest/index.ts b/packages/core-app-api/src/apis/implementations/auth/guest/index.ts
new file mode 100644
index 0000000000..42db58cfe6
--- /dev/null
+++ b/packages/core-app-api/src/apis/implementations/auth/guest/index.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export { default as GuestAuth } from './GuestAuth';
diff --git a/packages/core-app-api/src/apis/implementations/auth/index.ts b/packages/core-app-api/src/apis/implementations/auth/index.ts
index e02e07961a..58db084760 100644
--- a/packages/core-app-api/src/apis/implementations/auth/index.ts
+++ b/packages/core-app-api/src/apis/implementations/auth/index.ts
@@ -26,4 +26,5 @@ export * from './bitbucket';
export * from './bitbucketServer';
export * from './atlassian';
export * from './vmwareCloud';
+export * from './guest';
export type { OAuthApiCreateOptions, AuthApiCreateOptions } from './types';
diff --git a/packages/core-plugin-api/src/apis/definitions/auth.ts b/packages/core-plugin-api/src/apis/definitions/auth.ts
index d89544cf68..b11352b373 100644
--- a/packages/core-plugin-api/src/apis/definitions/auth.ts
+++ b/packages/core-plugin-api/src/apis/definitions/auth.ts
@@ -469,3 +469,15 @@ export const vmwareCloudAuthApiRef: ApiRef<
> = createApiRef({
id: 'core.auth.vmware-cloud',
});
+
+/**
+ * Provides guest authentication support.
+ *
+ * @public
+ * @remarks
+ */
+export const guestAuthApiRef: ApiRef<
+ ProfileInfoApi & BackstageIdentityApi & SessionApi
+> = createApiRef({
+ id: 'core.auth.guest',
+});
diff --git a/plugins/auth-backend-module-guest-provider/.eslintrc.js b/plugins/auth-backend-module-guest-provider/.eslintrc.js
new file mode 100644
index 0000000000..e2a53a6ad2
--- /dev/null
+++ b/plugins/auth-backend-module-guest-provider/.eslintrc.js
@@ -0,0 +1 @@
+module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
diff --git a/plugins/auth-backend-module-guest-provider/README.md b/plugins/auth-backend-module-guest-provider/README.md
new file mode 100644
index 0000000000..65da015958
--- /dev/null
+++ b/plugins/auth-backend-module-guest-provider/README.md
@@ -0,0 +1,5 @@
+# backstage-plugin-auth-backend-module-guest-provider
+
+The guest-provider backend module for the auth plugin.
+
+_This plugin was created through the Backstage CLI_
diff --git a/plugins/auth-backend-module-guest-provider/package.json b/plugins/auth-backend-module-guest-provider/package.json
new file mode 100644
index 0000000000..c35162fd71
--- /dev/null
+++ b/plugins/auth-backend-module-guest-provider/package.json
@@ -0,0 +1,42 @@
+{
+ "name": "@backstage/plugin-auth-backend-module-guest-provider",
+ "description": "The guest-provider backend module for the auth plugin.",
+ "version": "0.0.0",
+ "main": "src/index.ts",
+ "types": "src/index.ts",
+ "license": "Apache-2.0",
+ "private": true,
+ "publishConfig": {
+ "access": "public",
+ "main": "dist/index.cjs.js",
+ "types": "dist/index.d.ts"
+ },
+ "backstage": {
+ "role": "backend-plugin-module"
+ },
+ "scripts": {
+ "start": "backstage-cli package start",
+ "build": "backstage-cli package build",
+ "lint": "backstage-cli package lint",
+ "test": "backstage-cli package test",
+ "clean": "backstage-cli package clean",
+ "prepack": "backstage-cli package prepack",
+ "postpack": "backstage-cli package postpack"
+ },
+ "dependencies": {
+ "@backstage/backend-common": "workspace:^",
+ "@backstage/backend-plugin-api": "workspace:^",
+ "@backstage/catalog-model": "workspace:^",
+ "@backstage/errors": "workspace:^",
+ "@backstage/plugin-auth-node": "workspace:^",
+ "passport-oauth2": "^1.7.0"
+ },
+ "devDependencies": {
+ "@backstage/backend-test-utils": "workspace:^",
+ "@backstage/cli": "workspace:^",
+ "express": "^4.18.2"
+ },
+ "files": [
+ "dist"
+ ]
+}
diff --git a/plugins/auth-backend-module-guest-provider/src/createGuestAuthFactory.ts b/plugins/auth-backend-module-guest-provider/src/createGuestAuthFactory.ts
new file mode 100644
index 0000000000..8331870528
--- /dev/null
+++ b/plugins/auth-backend-module-guest-provider/src/createGuestAuthFactory.ts
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2023 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { SignInResolverFactory } from '@backstage/plugin-auth-node';
+import type {
+ AuthProviderFactory,
+ ProfileTransform,
+ SignInResolver,
+} from '@backstage/plugin-auth-node';
+import { createGuestAuthRouteHandlers } from './createGuestAuthRouteHandlers';
+import { GuestInfo } from './types';
+import { guestResolver } from './resolvers';
+
+/** @public */
+export function createGuestAuthProviderFactory(options?: {
+ profileTransform?: ProfileTransform;
+ signInResolver?: SignInResolver;
+ signInResolverFactories?: Record<
+ string,
+ SignInResolverFactory
+ >;
+}): AuthProviderFactory {
+ return ctx => {
+ const signInResolver = options?.signInResolver ?? guestResolver();
+
+ if (!signInResolver) {
+ throw new Error(
+ `No sign-in resolver configured for guest auth provider '${ctx.providerId}'`,
+ );
+ }
+
+ return createGuestAuthRouteHandlers({
+ signInResolver,
+ baseUrl: ctx.baseUrl,
+ appUrl: ctx.appUrl,
+ config: ctx.config,
+ resolverContext: ctx.resolverContext,
+ profileTransform: options?.profileTransform,
+ });
+ };
+}
diff --git a/plugins/auth-backend-module-guest-provider/src/createGuestAuthRouteHandlers.ts b/plugins/auth-backend-module-guest-provider/src/createGuestAuthRouteHandlers.ts
new file mode 100644
index 0000000000..07d0d3e87a
--- /dev/null
+++ b/plugins/auth-backend-module-guest-provider/src/createGuestAuthRouteHandlers.ts
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2020 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import type { Request, Response } from 'express';
+import type { Config } from '@backstage/config';
+import {
+ AuthProviderRouteHandlers,
+ AuthResolverContext,
+ ClientAuthResponse,
+ ProfileTransform,
+ SignInResolver,
+ prepareBackstageIdentityResponse,
+ sendWebMessageResponse,
+} from '@backstage/plugin-auth-node';
+import { GuestInfo } from './types';
+
+/** @public */
+export interface GuestAuthRouteHandlersOptions {
+ config: Config;
+ baseUrl: string;
+ appUrl: string;
+ resolverContext: AuthResolverContext;
+ signInResolver: SignInResolver;
+ profileTransform?: ProfileTransform;
+}
+
+const DEFAULT_RESULT: GuestInfo = { name: 'Guest' };
+
+/** @public */
+export function createGuestAuthRouteHandlers(
+ options: GuestAuthRouteHandlersOptions,
+): AuthProviderRouteHandlers {
+ const { resolverContext, signInResolver, appUrl } = options;
+
+ const defaultTransform: ProfileTransform = async result => {
+ return {
+ profile: {
+ displayName: result.name,
+ },
+ };
+ };
+
+ const profileTransform = options.profileTransform ?? defaultTransform;
+ return {
+ async start(_, res): Promise {
+ res.redirect('handler/frame');
+ },
+
+ async frameHandler(_, res): Promise {
+ const { profile } = await profileTransform(
+ DEFAULT_RESULT,
+ resolverContext,
+ );
+ const response: ClientAuthResponse = {
+ profile,
+ providerInfo: {
+ name: 'Guest',
+ },
+ };
+ if (signInResolver) {
+ const identity = await signInResolver(
+ { profile, result: DEFAULT_RESULT },
+ resolverContext,
+ );
+ response.backstageIdentity = prepareBackstageIdentityResponse(identity);
+ }
+ // post message back to popup if successful
+ sendWebMessageResponse(res, appUrl, {
+ type: 'authorization_response',
+ response,
+ });
+ },
+
+ async refresh(this: never, _: Request, res: Response): Promise {
+ const { profile } = await profileTransform(
+ DEFAULT_RESULT,
+ resolverContext,
+ );
+
+ const identity = await signInResolver(
+ { profile, result: DEFAULT_RESULT },
+ resolverContext,
+ );
+
+ const response: ClientAuthResponse<{}> = {
+ profile,
+ providerInfo: {},
+ backstageIdentity: prepareBackstageIdentityResponse(identity),
+ };
+
+ res.status(200).json(response);
+ },
+
+ async logout(_, res) {
+ res.end();
+ },
+ };
+}
diff --git a/plugins/auth-backend-module-guest-provider/src/index.ts b/plugins/auth-backend-module-guest-provider/src/index.ts
new file mode 100644
index 0000000000..b1a89763b9
--- /dev/null
+++ b/plugins/auth-backend-module-guest-provider/src/index.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * The guest-provider backend module for the auth plugin.
+ *
+ * @packageDocumentation
+ */
+
+export { createGuestAuthProviderFactory } from './createGuestAuthFactory';
+export type { GuestInfo } from './types';
+export { authModuleGuestProvider as default } from './module';
diff --git a/plugins/auth-backend-module-guest-provider/src/module.ts b/plugins/auth-backend-module-guest-provider/src/module.ts
new file mode 100644
index 0000000000..c9fd3feea4
--- /dev/null
+++ b/plugins/auth-backend-module-guest-provider/src/module.ts
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {
+ coreServices,
+ createBackendModule,
+} from '@backstage/backend-plugin-api';
+import {
+ createOAuthProviderFactory,
+ commonSignInResolvers,
+ authProvidersExtensionPoint,
+} from '@backstage/plugin-auth-node';
+import { createGuestAuthProviderFactory } from './createGuestAuthFactory';
+
+export const authModuleGuestProvider = createBackendModule({
+ pluginId: 'auth',
+ moduleId: 'guest-provider',
+ register(reg) {
+ reg.registerInit({
+ deps: {
+ logger: coreServices.logger,
+ providers: authProvidersExtensionPoint,
+ },
+ async init({ providers }) {
+ providers.registerProvider({
+ providerId: 'guest',
+ factory: createGuestAuthProviderFactory(),
+ });
+ },
+ });
+ },
+});
diff --git a/plugins/auth-backend-module-guest-provider/src/resolvers.ts b/plugins/auth-backend-module-guest-provider/src/resolvers.ts
new file mode 100644
index 0000000000..47d340f013
--- /dev/null
+++ b/plugins/auth-backend-module-guest-provider/src/resolvers.ts
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { stringifyEntityRef } from '@backstage/catalog-model';
+import { createSignInResolverFactory } from '@backstage/plugin-auth-node';
+
+export const guestResolver = createSignInResolverFactory({
+ create() {
+ return async (_, ctx) => {
+ const userRef = stringifyEntityRef({
+ kind: 'user',
+ name: 'guest',
+ });
+ try {
+ return ctx.signInWithCatalogUser({ entityRef: userRef });
+ } catch (err) {
+ // We can't guarantee that a guest user exists in the catalog, so we issue a token directly,
+ return ctx.issueToken({
+ claims: {
+ sub: userRef,
+ ent: [userRef],
+ },
+ });
+ }
+ };
+ },
+});
diff --git a/plugins/auth-backend-module-guest-provider/src/types.ts b/plugins/auth-backend-module-guest-provider/src/types.ts
new file mode 100644
index 0000000000..9d0ace0a33
--- /dev/null
+++ b/plugins/auth-backend-module-guest-provider/src/types.ts
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { ProfileTransform } from '@backstage/plugin-auth-node';
+
+export type GuestInfo = {
+ name: string;
+};
+
+export interface GuestAuthenticator {
+ defaultProfileTransform: ProfileTransform;
+}
diff --git a/plugins/auth-backend/src/providers/guest/index.ts b/plugins/auth-backend/src/providers/guest/index.ts
new file mode 100644
index 0000000000..7b384798b0
--- /dev/null
+++ b/plugins/auth-backend/src/providers/guest/index.ts
@@ -0,0 +1,16 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+export { guest } from './provider';
diff --git a/plugins/auth-backend/src/providers/guest/provider.ts b/plugins/auth-backend/src/providers/guest/provider.ts
new file mode 100644
index 0000000000..7d3a9e724c
--- /dev/null
+++ b/plugins/auth-backend/src/providers/guest/provider.ts
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2024 The Backstage Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { createAuthProviderIntegration } from '../createAuthProviderIntegration';
+import { AuthHandler, SignInResolver } from '../types';
+import { createGuestAuthProviderFactory } from '@backstage/plugin-auth-backend-module-guest-provider';
+import { GuestInfo } from '@backstage/plugin-auth-backend-module-guest-provider';
+
+/**
+ * Auth provider integration for Google auth
+ *
+ * @public
+ */
+export const guest = createAuthProviderIntegration({
+ create(options?: {
+ /**
+ * The profile transformation function used to verify and convert the auth response
+ * into the profile that will be presented to the user.
+ */
+ authHandler?: AuthHandler;
+
+ /**
+ * Configure sign-in for this provider, without it the provider can not be used to sign users in.
+ */
+ signIn?: {
+ /**
+ * Maps an auth result to a Backstage identity for the user.
+ */
+ resolver: SignInResolver;
+ };
+ }) {
+ return createGuestAuthProviderFactory({
+ profileTransform: options?.authHandler,
+ signInResolver: options?.signIn?.resolver,
+ });
+ },
+});
diff --git a/plugins/auth-backend/src/providers/providers.ts b/plugins/auth-backend/src/providers/providers.ts
index 76ac51f662..d527bf8b13 100644
--- a/plugins/auth-backend/src/providers/providers.ts
+++ b/plugins/auth-backend/src/providers/providers.ts
@@ -30,6 +30,7 @@ import { oidc } from './oidc';
import { okta } from './okta';
import { onelogin } from './onelogin';
import { saml } from './saml';
+import { guest } from './guest';
import { bitbucketServer } from './bitbucketServer';
import { easyAuth } from './azure-easyauth';
import { AuthProviderFactory } from '@backstage/plugin-auth-node';
@@ -58,6 +59,7 @@ export const providers = Object.freeze({
onelogin,
saml,
easyAuth,
+ guest,
});
/**
@@ -83,4 +85,5 @@ export const defaultAuthProviderFactories: {
bitbucket: bitbucket.create(),
bitbucketServer: bitbucketServer.create(),
atlassian: atlassian.create(),
+ guest: guest.create(),
};
diff --git a/yarn.lock b/yarn.lock
index 73413df542..d1af60c782 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1,6 +1,3 @@
-# This file is generated by running "yarn install" inside your project.
-# Manual changes might be lost - proceed with caution!
-
__metadata:
version: 6
cacheKey: 8
@@ -4682,6 +4679,22 @@ __metadata:
languageName: unknown
linkType: soft
+"@backstage/plugin-auth-backend-module-guest-provider@^0.0.0, @backstage/plugin-auth-backend-module-guest-provider@workspace:plugins/auth-backend-module-guest-provider":
+ version: 0.0.0-use.local
+ resolution: "@backstage/plugin-auth-backend-module-guest-provider@workspace:plugins/auth-backend-module-guest-provider"
+ dependencies:
+ "@backstage/backend-common": "workspace:^"
+ "@backstage/backend-plugin-api": "workspace:^"
+ "@backstage/backend-test-utils": "workspace:^"
+ "@backstage/catalog-model": "workspace:^"
+ "@backstage/cli": "workspace:^"
+ "@backstage/errors": "workspace:^"
+ "@backstage/plugin-auth-node": "workspace:^"
+ express: ^4.18.2
+ passport-oauth2: ^1.7.0
+ languageName: unknown
+ linkType: soft
+
"@backstage/plugin-auth-backend-module-microsoft-provider@workspace:^, @backstage/plugin-auth-backend-module-microsoft-provider@workspace:plugins/auth-backend-module-microsoft-provider":
version: 0.0.0-use.local
resolution: "@backstage/plugin-auth-backend-module-microsoft-provider@workspace:plugins/auth-backend-module-microsoft-provider"
@@ -4838,6 +4851,7 @@ __metadata:
"@backstage/plugin-auth-backend-module-github-provider": "workspace:^"
"@backstage/plugin-auth-backend-module-gitlab-provider": "workspace:^"
"@backstage/plugin-auth-backend-module-google-provider": "workspace:^"
+ "@backstage/plugin-auth-backend-module-guest-provider": ^0.0.0
"@backstage/plugin-auth-backend-module-microsoft-provider": "workspace:^"
"@backstage/plugin-auth-backend-module-oauth2-provider": "workspace:^"
"@backstage/plugin-auth-backend-module-oauth2-proxy-provider": "workspace:^"
@@ -27446,6 +27460,7 @@ __metadata:
"@backstage/plugin-adr-backend": "workspace:^"
"@backstage/plugin-app-backend": "workspace:^"
"@backstage/plugin-auth-backend": "workspace:^"
+ "@backstage/plugin-auth-backend-module-guest-provider": ^0.0.0
"@backstage/plugin-auth-node": "workspace:^"
"@backstage/plugin-azure-devops-backend": "workspace:^"
"@backstage/plugin-azure-sites-common": "workspace:^"
@@ -37346,6 +37361,19 @@ __metadata:
languageName: node
linkType: hard
+"passport-oauth2@npm:1.x.x, passport-oauth2@npm:^1.1.2, passport-oauth2@npm:^1.4.0, passport-oauth2@npm:^1.6.0, passport-oauth2@npm:^1.6.1, passport-oauth2@npm:^1.7.0":
+ version: 1.7.0
+ resolution: "passport-oauth2@npm:1.7.0"
+ dependencies:
+ base64url: 3.x.x
+ oauth: 0.10.x
+ passport-strategy: 1.x.x
+ uid2: 0.0.x
+ utils-merge: 1.x.x
+ checksum: a9a80b968343c9c1906f74ef613b346ec2d6a6acfe17af81e673fd774779b436729252485755c3ce182f2cdba2434d75067418952d722404d65b93c0360ca02b
+ languageName: node
+ linkType: hard
+
"passport-oauth@npm:1.0.0, passport-oauth@npm:^1.0.0":
version: 1.0.0
resolution: "passport-oauth@npm:1.0.0"