Merge remote-tracking branch 'origin/master' into reconfigure

This commit is contained in:
bnechyporenko
2022-06-21 14:23:24 +02:00
842 changed files with 28491 additions and 9828 deletions
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 82 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 18 KiB

+179 -98
View File
@@ -1,9 +1,113 @@
---
id: add-auth-provider
title: Adding authentication providers
description: Documentation on Adding authentication providers
title: Contributing New Providers
description: Documentation on adding new authentication providers
---
> NOTE: The primary audience for this documentation are contributors to the main
> Backstage project that want to add support for new authentication providers.
> While you can follow it to implement your own custom providers it is much
> more advanced than using our built-in providers.
## How Does Authentication Work?
The Backstage application can use various external authentication providers for
authentication. An external provider is wrapped using an
`AuthProviderRouteHandlers` interface for handling authentication. This
interface consists of four methods. Each of these methods is hosted at an
endpoint (by default) `/api/auth/[provider]/method`, where `method` performs a
certain operation as follows:
```
/auth/[provider]/start -> Initiate a login from the web page
/auth/[provider]/handler/frame -> Handle a finished authentication operation
/auth/[provider]/refresh -> Refresh the validity of a login
/auth/[provider]/logout -> Log out a logged-in user
```
The flow is as follows:
1. A user attempts to sign in.
2. A popup window is opened, pointing to the `auth` endpoint. That endpoint does
initial preparations and then re-directs the user to an external
authenticator, still inside the popup.
3. The authenticator validates the user and returns the result of the validation
(success OR failure), to the wrapper's endpoint (`handler/frame`).
4. The `handler/frame` rendered webpage will issue the appropriate response to
the webpage that opened the popup window, and the popup is closed.
5. The user signs out by clicking on a UI interface and the webpage makes a
request to logout the user.
## Implementing Your Own Auth Wrapper
The core interface of any auth wrapper is the `AuthProviderRouteHandlers`
interface. This interface has four methods corresponding to the API described in
the initial section. Any auth wrapper will have to implement this interface.
When initiating a login, a pop-up window is created by the frontend, to allow
the user to initiate a login. This login request is done to the `/start`
endpoint which is handled by the `start` method.
The `start` method re-directs to the external auth provider who authenticates
the request and re-directs the request to the `/frame/handler` endpoint, which
is handled by the `frameHandler` method.
The `frameHandler` returns an HTML response, containing a script that does a
`postMessage` to the frontend window, containing the result of the request.
The `WebMessageResponse` type is the message sent by the `postMessage` to the
frontend.
A `postMessageResponse` utility function wraps the logic of generating a
`postMessage` response that ensures that CORS is successfully handled. This
function takes an `express.Response`, a `WebMessageResponse` and the URL of the
frontend (`appOrigin`) as parameters and return an HTML page with the script and
the message.
There is a helper class for [OAuth2](https://oauth.net/2/) based authentication providers, [OAuthAdapter](../reference/plugin-auth-backend.oauthadapter.md). This class implements the `AuthProviderRouteHandlers` interface
for you, and instead requires you to implement [OAuthHandlers](../reference/plugin-auth-backend.oauthhandlers.md), which
is significantly easier.
### Auth Environment Separation
The concept of an `env` is core to the way the auth backend works. It uses an
`env` query parameter to identify the environment in which the application is
running (`development`, `staging`, `production`, etc). Each runtime can
simultaneously support multiple environments at the same time and the right
handler for each request is identified and dispatched to, based on the `env`
parameter.
`OAuthEnvironmentHandler` is a utility wrapper for an `OAuthHandlers` that
implements the `AuthProviderRouteHandlers` interface while supporting multiple
`env`s.
To instantiate OAuth providers (the same but for different environments), use
`OAuthEnvironmentHandler.mapConfig`. It's a helper to iterate over a
configuration object that is a map of environments to configurations. See one of
the existing OAuth providers for an example of how it is used.
Given the following configuration:
```yaml
development:
clientId: abc
clientSecret: secret
production:
clientId: xyz
clientSecret: supersecret
```
The `OAuthEnvironmentHandler.mapConfig(config, envConfig => ...)` call will
split the config by the top level `development` and `production` keys, and pass
on each block as `envConfig`.
For convenience, the `AuthProviderFactory` is a factory function that has to be
implemented which can then generate a `AuthProviderRouteHandlers` for a given
provider.
All of the supported providers provide an `AuthProviderFactory` that returns an
`OAuthEnvironmentHandler`, capable of handling authentication for multiple
environments.
## Passport
We chose [Passport](http://www.passportjs.org/) as our authentication platform
@@ -46,13 +150,13 @@ plugins/auth-backend/src/providers/providerA
**`plugins/auth-backend/src/providers/providerA/provider.ts`** defines the
provider class which implements a handler for the chosen framework.
#### Adding an OAuth based provider
### Adding an OAuth based provider
If we're adding an `OAuth` based provider we would implement the
[OAuthProviderHandlers](#OAuthProviderHandlers) interface. By implementing this
`OAuthHandlers` interface. By implementing this
interface we can use the `OAuthProvider` class provided by `lib/oauth`, meaning
we don't need to implement the full
[AuthProviderRouteHandlers](#AuthProviderRouteHandlers) interface that providers
`AuthProviderRouteHandlers` interface that providers
otherwise need to implement.
The provider class takes the provider's options as a class parameter. It also
@@ -65,7 +169,7 @@ export type ProviderAProviderOptions = OAuthProviderOptions & {
// extra options here
}
export class ProviderAAuthProvider implements OAuthProviderHandlers {
export class ProviderAAuthProvider implements OAuthHandlers {
private readonly _strategy: ProviderAStrategy;
constructor(options: ProviderAProviderOptions) {
@@ -87,13 +191,10 @@ export class ProviderAAuthProvider implements OAuthProviderHandlers {
}
```
#### Adding an non-OAuth based provider
_**Note**: We have prioritized OAuth-based providers and non-OAuth providers
should be considered experimental._
### Adding an non-OAuth based provider
An non-`OAuth` based provider could implement
[AuthProviderRouteHandlers](#AuthProviderRouteHandlers) instead.
`AuthProviderRouteHandlers` instead.
```ts
type ProviderAOptions = {
@@ -119,13 +220,19 @@ export class ProviderAAuthProvider implements AuthProviderRouteHandlers {
}
```
#### Factory function
#### Integration Wrapper
Each provider exports a factory function that instantiates the provider. The
factory should implement [AuthProviderFactory](#AuthProviderFactory), which
Each provider exports an object that provides a way to create new instances
of the provider, along with related utilities like predefined sign-in resolvers.
The object is created using `createAuthProviderIntegration`, with the most
important part being the `create` method that acts as the factory function
for our provider.
The factory should return an implementation of `AuthProviderFactory`, which
passes in a object with utilities for configuration, logging, token issuing,
etc. The factory should return an implementation of
[AuthProviderRouteHandlers](#AuthProviderRouteHandlers).
`AuthProviderRouteHandlers`.
The factory is what decides the mapping from
[static configuration](../conf/index.md) to the creation of auth providers. For
@@ -133,48 +240,70 @@ example, OAuth providers use `OAuthEnvironmentHandler` to allow for multiple
different configurations, one for each environment, which looks like this;
```ts
export const createOktaProvider: AuthProviderFactory = ({
globalConfig,
config,
tokenIssuer,
}) =>
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
// read options from config
const clientId = envConfig.getString('clientId');
const clientSecret = envConfig.getString('clientSecret');
export const okta = 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<OAuthResult>;
// instantiate our OAuthProviderHandlers implementation
const provider = new OktaAuthProvider({
audience,
clientId,
clientSecret,
callbackUrl,
});
/**
* 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<OAuthResult>;
};
}) {
return ({ providerId, globalConfig, config, resolverContext }) =>
OAuthEnvironmentHandler.mapConfig(config, envConfig => {
// read options from config
const clientId = envConfig.getString('clientId');
const clientSecret = envConfig.getString('clientSecret');
// Wrap the OAuthProviderHandlers with OAuthProvider, which implements AuthProviderRouteHandlers
return OAuthProvider.fromConfig(globalConfig, provider, {
providerId,
tokenIssuer,
});
});
// Use provided auth handler, or create a default one
const authHandler: AuthHandler<OAuthResult> = options?.authHandler
? options.authHandler
: async ({ fullProfile, params }) => ({
profile: makeProfileInfo(fullProfile, params.id_token),
});
// instantiate our OAuthHandlers implementation
const provider = new OktaAuthProvider({
audience,
clientId,
clientSecret,
callbackUrl,
authHandler,
signInResolver: options?.signIn?.resolver,
resolverContext,
});
// Wrap the OAuthHandlers with OAuthProvider, which implements AuthProviderRouteHandlers
return OAuthProvider.fromConfig(globalConfig, provider, {
providerId,
tokenIssuer,
});
});
},
resolvers: {
/**
* Looks up the user by matching their email local part to the entity name.
*/
emailLocalPartMatchingUserEntityName: () => commonByEmailLocalPartResolver,
// ... additional predefined resolvers
},
});
```
The purpose of the different environments is to allow for a single auth-backend
to serve as the authentication service for multiple different frontend
environments, such as local development, staging, and production.
The factory function for other providers can be a lot simpler, as they might not
have configuration for each environment. Looking something like this:
```ts
export const createProviderAProvider: AuthProviderFactory = ({ config }) => {
const a = config.getString('a');
const b = config.getString('b');
return new ProviderAAuthProvider({ a, b });
};
```
#### Verify Callback
> Strategies require what is known as a verify callback. The purpose of a verify
@@ -202,7 +331,7 @@ export { createProviderAProvider } from './provider';
**`plugins/auth-backend/src/providers/factories.ts`** When the `auth-backend`
starts it sets up routing for all the available providers by calling
`createAuthProviderRouter` on each provider. You need to import the factory
the factory function of each provider. You need to import the factory
function from the provider and add it to the factory:
```ts
@@ -232,51 +361,3 @@ You can `curl -i localhost:7007/api/auth/providerA/start` and which should
provide a `302` redirect with a `Location` header. Paste the URL from that
header into a web browser and you should be able to trigger the authorization
flow.
---
##### OAuthProviderHandlers
```ts
export interface OAuthProviderHandlers {
start(
req: express.Request,
options: Record<string, string>,
): Promise<RedirectInfo>;
handler(req: express.Request): Promise<{
response: AuthResponse<OAuthProviderInfo>;
refreshToken?: string;
}>;
refresh?(
refreshToken: string,
scope: string,
): Promise<AuthResponse<OAuthProviderInfo>>;
logout?(): Promise<void>;
}
```
##### AuthProviderRouteHandlers
```ts
export interface AuthProviderRouteHandlers {
start(req: express.Request, res: express.Response): Promise<any>;
frameHandler(req: express.Request, res: express.Response): Promise<any>;
refresh?(req: express.Request, res: express.Response): Promise<any>;
logout(req: express.Request, res: express.Response): Promise<any>;
}
```
##### AuthProviderFactory
```ts
export type AuthProviderFactoryOptions = {
globalConfig: AuthProviderConfig;
config: Config;
logger: Logger;
tokenIssuer: TokenIssuer;
};
export type AuthProviderFactory = (
options: AuthProviderFactoryOptions,
) => AuthProviderRouteHandlers;
```
-206
View File
@@ -1,206 +0,0 @@
---
id: auth-backend-classes
title: Auth backend classes
description: Documentation on Auth backend classes
---
## How Does Authentication Work?
The Backstage application can use various external authentication providers for
authentication. An external provider is wrapped using an
`AuthProviderRouteHandlers` interface for handling authentication. This
interface consists of four methods. Each of these methods is hosted at an
endpoint (by default) `/api/auth/[provider]/method`, where `method` performs a
certain operation as follows:
```
/auth/[provider]/start -> Initiate a login from the web page
/auth/[provider]/handler/frame -> Handle a finished authentication operation
/auth/[provider]/refresh -> Refresh the validity of a login
/auth/[provider]/logout -> Log out a logged-in user
```
The flow is as follows:
1. A user attempts to sign in.
2. A popup window is opened, pointing to the `auth` endpoint. That endpoint does
initial preparations and then re-directs the user to an external
authenticator, still inside the popup.
3. The authenticator validates the user and returns the result of the validation
(success OR failure), to the wrapper's endpoint (`handler/frame`).
4. The `handler/frame` rendered b´webpage will issue the appropriate response to
the webpage that opened the popup window, and the popup is closed.
5. The user signs out by clicking on a UI interface and the webpage makes a
request to logout the user.
There are currently two different classes for two authentication mechanisms that
implement this interface: an `OAuthAdapter` for [OAuth](https://oauth.net/2/)
based mechanisms and a `SAMLAuthProvider` for
[SAML](http://docs.oasis-open.org/security/saml/Post2.0/sstc-saml-tech-overview-2.0.html).
If you do not have an `OAuth2` or `SAML` based authentication provider, look in
the section [below](#implementing-your-own-auth-wrapper).
### OAuth Mechanisms
For more information on how these methods are used and for which purpose, refer
to the [OAuth documentation](oauth.md).
Currently OAuth is assumed to be the de facto authentication mechanism for
Backstage based applications.
Backstage comes with a "batteries-included" set of supported commonly used OAuth
providers: Okta, GitHub, Google, GitLab, and a generic OAuth2 provider. For a
list of available providers, look at the available wrappers in
`backstage/plugins/auth-backend/src/providers/`.
All of these use the **authorization flow** of OAuth2 to implement
authentication.
If your authentication provider is any of the above mentioned providers, you can
configure them by setting the right variables in `app-config.yaml` under the
`auth` section.
### SAML
The SAML Provider is currently under development. Additional validation and
profile handling is still required before use in production.
To configure the SAML Auth provider, look at the configuration parameters
supported by
[Passport-SAML](https://github.com/node-saml/passport-saml#config-parameter-details)
under the `auth.providers.saml` key
For security reasons, validate that the response from the IdP is indeed signed
by also providing the `cert` configuration.
### Configuration
Each authentication provider (except SAML) needs six parameters: an OAuth client
ID, a client secret, an authorization endpoint, a token endpoint, an optional
list of scopes (as a string separated by spaces) that may be required by the
OAuth2 Server to enable end-user sign-on, and an app origin. The app origin is
the URL at which the frontend of the application is hosted, and it is read from
the `app.baseUrl` config. This is required because the application opens a popup
window to perform the authentication, and once the flow is completed, the popup
window sends a `postMessage` to the frontend application to indicate the result
of the operation. Also this URL is used to verify that authentication requests
are coming from only this endpoint.
These values are configured via the `app-config.yaml` present in the root of
your app folder.
```
auth:
providers:
google:
development:
clientId: ${AUTH_GOOGLE_CLIENT_ID}
clientSecret: ${AUTH_GOOGLE_CLIENT_SECRET}
github:
development:
clientId: ${AUTH_GITHUB_CLIENT_ID}
clientSecret: ${AUTH_GITHUB_CLIENT_SECRET}
enterpriseInstanceUrl: ${AUTH_GITHUB_ENTERPRISE_INSTANCE_URL}
gitlab:
development:
clientId: ${AUTH_GITLAB_CLIENT_ID}
oauth2:
development:
clientId: ${AUTH_OAUTH2_CLIENT_ID}
clientSecret: ${AUTH_OAUTH2_CLIENT_SECRET}
authorizationUrl: ${AUTH_OAUTH2_AUTH_URL}
tokenUrl: ${AUTH_OAUTH2_TOKEN_URL}
scope: ${AUTH_OAUTH2_SCOPE}
saml:
entryPoint: ${AUTH_SAML_ENTRY_POINT}
issuer: ${AUTH_SAML_ISSUER}
...
```
## Implementing Your Own Auth Wrapper
The core interface of any auth wrapper is the `AuthProviderRouteHandlers`
interface. This interface has four methods corresponding to the API described in
the initial section. Any auth wrapper will have to implement this interface.
When initiating a login, a pop-up window is created by the frontend, to allow
the user to initiate a login. This login request is done to the `/start`
endpoint which is handled by the `start` method.
The `start` method re-directs to the external auth provider who authenticates
the request and re-directs the request to the `/frame/handler` endpoint, which
is handled by the `frameHandler` method.
The `frameHandler` returns an HTML response, containing a script that does a
`postMessage` to the frontend's window, containing the result of the request.
The `WebMessageResponse` type is the message sent by the `postMessage` to the
frontend.
A `postMessageResponse` utility function wraps the logic of generating a
`postMessage` response that ensures that CORS is successfully handled. This
function takes an `express.Response`, a `WebMessageResponse` and the URL of the
frontend (`appOrigin`) as parameters and return an HTML page with the script and
the message.
### OAuth Wrapping Interfaces.
Each OAuth external provider is supported by a corresponding
[Passport](https://github.com/jaredhanson/passport) strategy. For a generic
OAuth2 provider, passport has a `passport-oauth2` strategy. The strategy class
handles the implementation details of working with each provider.
Each strategy is wrapped by an `OAuthHandlers` interface.
This interface cannot be directly used as an Express HTTP request handler. To do
so, `OAuthHandlers` are wrapped in an `OAuthAdapter`, which implements the
`AuthProviderRouterHandlers` interface.
#### Env
The concept of an `env` is core to the way the auth backend works. It uses an
`env` query parameter to identify the environment in which the application is
running (`development`, `staging`, `production`, etc). Each runtime can
simultaneously support multiple environments at the same time and the right
handler for each request is identified and dispatched to, based on the `env`
parameter.
`OAuthEnvironmentHandler` is a utility wrapper for an `OAuthHandlers` that
implements the `AuthProviderRouteHandlers` interface while supporting multiple
`env`s.
To instantiate OAuth providers (the same but for different environments), use
`OAuthEnvironmentHandler.mapConfig`. It's a helper to iterate over a
configuration object that is a map of environments to configurations. See one of
the existing OAuth providers for an example of how it is used.
Given the following configuration:
```yaml
development:
clientId: abc
clientSecret: secret
production:
clientId: xyz
clientSecret: supersecret
```
The `OAuthEnvironmentHandler.mapConfig(config, envConfig => ...)` call will
split the config by the top level `development` and `production` keys, and pass
on each block as `envConfig`.
For convenience, the `AuthProviderFactory` is a factory function that has to be
implemented which can then generate a `AuthProviderRouteHandlers` for a given
provider.
All of the supported providers provide an `AuthProviderFactory` that returns an
`OAuthEnvironmentHandler`, capable of handling authentication for multiple
environments.
### OAuth2 Provider
The `oauth2` provider abstracts a generic **OAuth2 + OIDC** based authentication
provider. What this means is that after the application has been given
permission by the user, the `authorization code` will be exchanged for an
`access_token`, a `refresh_token` and an `id_token`. This `id_token` is used to
obtain an email id of the user, which is then used for creating the session.
+49 -2
View File
@@ -12,6 +12,37 @@ If you want to use an auth provider to sign in users, you need to explicitly con
it have sign-in enabled and also tell it how the external identities should
be mapped to user identities within Backstage.
## Quick Start
> See [providers](../reference/plugin-auth-backend.providers.md)
> for a full list of auth providers and their built-in sign-in resolvers.
Backstage projects created with `npx @backstage/create-app` come configured with a
sign-in resolver for GitHub guest access. This resolver makes all users share
a single "guest" identity and is only intended as a minimum requirement to quickly
get up and running. You can replace `github` for any of the other providers if you need.
This resolver should not be used in production, as it uses a single shared identity,
and has no restrictions on who is able to sign-in. Be sure to read through the rest
of this page to understand the Backstage identity system once you need to install
a resolver for your production environment.
The guest resolver can be useful for testing purposes too, and it looks like this:
```ts
signIn: {
resolver(_, ctx) {
const userRef = 'user:default/guest'
return ctx.issueToken({
claims: {
sub: userRef,
ent: [userRef],
},
}),
},
},
```
## Backstage User Identity
A user identity within Backstage is built up from two pieces of information, a
@@ -59,6 +90,11 @@ the given auth provider, as well as a context object that contains various helpe
for looking up users and issuing tokens. There are also a number of built-in sign-in
resolvers that can be used, which are covered a bit further down.
Note that while it possible to configure multiple auth providers to be used for sign-in,
you should take care when doing so. It is best to make sure that the different auth
providers either do not have any user overlap, or that any users that are able to log
in with multiple providers always end up with the same Backstage identity.
### Custom Resolver Example
Let's look at an example of a custom sign-in resolver for the Google auth provider.
@@ -210,6 +246,11 @@ is that it can be tricky to determine the ownership references, although it can
be achieved for example through a lookup to an external service. You typically
want to at least use the user itself as a lone ownership reference.
Because we no longer use the catalog as an allow-list of users, it is often important
that you limit what users are allowed to sign in. This could be a simple email domain
check like in the example below, or you might for example look up the GitHub organizations
that the user belongs to using the user access token in the provided result object.
```ts
import { DEFAULT_NAMESPACE, stringifyEntityRef, } from '@backstage/catalog-model';
@@ -220,8 +261,14 @@ async ({ profile }, ctx) => {
'Login failed, user profile does not contain an email',
);
}
// We again use the local part of the email as the user name.
const [localPart] = profile.email.split('@');
// Split the email into the local part and the domain.
const [localPart, domain] = profile.email.split('@');
// Next we verify the email domain. It is recommended to include this
// kind of check if you don't look up the user in an external service.
if (domain !== 'acme.org') {
throw new Error('Login failed, user email domain check failed');
}
// By using `stringifyEntityRef` we ensure that the reference is formatted correctly
const userEntityRef = stringifyEntityRef({
+18
View File
@@ -185,6 +185,24 @@ const app = createApp({
When using multiple auth providers like this, it's important that you configure the different
sign-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](../features/software-templates/writing-templates.md#the-repository-picker) inside your software templates you will need to configure the [`ScmAuthApi`](https://backstage.io/docs/reference/integration-react.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:
```ts
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](./index.md#custom-scmauthapi-implementation).
## For Plugin Developers
The Backstage frontend core APIs provide a set of Utility APIs for plugin developers
+21 -18
View File
@@ -6,7 +6,7 @@ description: Adding OAuth2Proxy as an authentication provider in Backstage
---
The Backstage `@backstage/plugin-auth-backend` package comes with an
`oauth2proxy` authentication provider that can authenticate users by using a
`oauth2Proxy` authentication provider that can authenticate users by using a
[oauth2-proxy](https://github.com/oauth2-proxy/oauth2-proxy) in front of an
actual Backstage instance. This enables to reuse existing authentications within
a cluster. In general the `oauth2-proxy` supports all OpenID Connect providers,
@@ -21,17 +21,17 @@ The provider configuration can be added to your `app-config.yaml` under the root
```yaml
auth:
providers:
oauth2proxy: {}
oauth2Proxy: {}
```
Right now no configuration options are supported, but the empty object is needed
to enable the provider in the auth backend.
To use the `oauth2proxy` provider you must also configure it with a sign-in resolver.
To use the `oauth2Proxy` provider you must also configure it with a sign-in resolver.
For more information about the sign-in process in general, see the
[Sign-in Identities and Resolvers](../identity-resolver.md) documentation.
For the `oauth2proxy` provider, the sign-in result is quite different than other providers.
For the `oauth2Proxy` provider, the sign-in result is quite different than other providers.
Because it's a proxy provider that can be configured to forward information through
arbitrary headers, the auth result simply just gives you access to the HTTP headers
of the incoming request. Using these you can either extract the information directly,
@@ -40,19 +40,22 @@ or grab ID or access tokens to look up additional information and/or validate th
A simple sign-in resolver might for example look like this:
```ts
providers.oauth2Proxy.create({
signIn: {
async resolver({ result }, ctx) {
const name = result.getHeader('x-forwarded-user');
if (!name) {
throw new Error('Request did not contain a user')
}
return ctx.signInWithCatalogUser({
entityRef: { name },
});
providerFactories: {
...defaultAuthProviderFactories,
oauth2Proxy: providers.oauth2Proxy.create({
signIn: {
async resolver({ result }, ctx) {
const name = result.getHeader('x-forwarded-user');
if (!name) {
throw new Error('Request did not contain a user')
}
return ctx.signInWithCatalogUser({
entityRef: { name },
});
},
},
},
}),
}),
},
```
## Adding the provider to the Backstage frontend
@@ -65,7 +68,7 @@ installed in `packages/app/src/App.tsx` like this:
const app = createApp({
components: {
+ SignInPage: props => <ProxiedSignInPage {...props} provider="oauth2proxy" />,
+ SignInPage: props => <ProxiedSignInPage {...props} provider="oauth2Proxy" />,
```
See the [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) section for more information.
See [Sign-In with Proxy Providers](../index.md#sign-in-with-proxy-providers) for pointers on how to set up the sign-in page to also work smoothly for local development.
-62
View File
@@ -1,62 +0,0 @@
---
id: helm
title: Deploying with Helm
description: How to deploy Backstage with Helm and Kubernetes
sidebar_label: Helm
---
An example Backstage app can be deployed in Kubernetes using the
[Backstage Helm charts](https://github.com/backstage/backstage/tree/master/contrib/chart/backstage).
First, choose a DNS name where Backstage will be hosted, and create a YAML file
for your custom configuration.
```yaml
appConfig:
app:
baseUrl: https://backstage.mydomain.com
title: Backstage
backend:
baseUrl: https://backstage.mydomain.com
cors:
origin: https://backstage.mydomain.com
lighthouse:
baseUrl: https://backstage.mydomain.com/lighthouse-api
techdocs:
storageUrl: https://backstage.mydomain.com/api/techdocs/static/docs
requestUrl: https://backstage.mydomain.com/api/techdocs
```
Then use it to run:
```bash
git clone https://github.com/backstage/backstage.git
cd backstage/contrib/chart/backstage
helm dependency update
helm install -f backstage-mydomain.yaml backstage .
```
This command will deploy the following pieces:
- Backstage frontend
- Backstage backend with scaffolder and auth plugins
- (optional) a PostgreSQL instance
- lighthouse plugin
- ingress
After a few minutes Backstage should be up and running in your cluster under the
DNS specified earlier.
Make sure to create the appropriate DNS entry in your infrastructure. To find
the public IP address run:
```bash
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
backstage-ingress * 123.1.2.3 80 17m
```
> **NOTE**: this is not a production ready deployment.
For more information on how to customize the deployment check the
[README](https://github.com/backstage/backstage/tree/master/contrib/chart/backstage/README.md).
+1 -3
View File
@@ -29,9 +29,7 @@ This method is covered in [Building a Docker image](docker.md) and
There is also an example of deploying on [Heroku](heroku.md), which only
requires the first two steps.
An example of deploying Backstage with a [Helm chart](helm.md), a common pattern
in AWS, is also available. There is also a contrib guide to deploying Backstage
with
There is also a contrib guide to deploying Backstage with
[AWS Fargate and Aurora PostgreSQL](https://github.com/backstage/backstage/blob/master/contrib/docs/tutorials/aws-fargate-deployment.md).
Please consider contributing other deployment guides if you get Backstage set up
+5 -1
View File
@@ -33,10 +33,14 @@ const serviceEntityPage = (
<EntityLayout>
{/* other tabs... */}
<EntityLayout.Route path="/kubernetes" title="Kubernetes">
<EntityKubernetesContent />
<EntityKubernetesContent refreshIntervalMs={30000} />
</EntityLayout.Route>
```
**Notes:**
- The optional `refreshIntervalMs` property on the `EntityKubernetesContent` defines the interval in which the content automatically refreshes, if not set this will default to 10 seconds.
That's it! But now, we need the Kubernetes Backend plugin for the frontend to
work.
+4 -4
View File
@@ -18,7 +18,7 @@ If you haven't setup Backstage already, start
```bash
# From your Backstage root directory
yarn add --cwd packages/app @backstage/plugin-search
yarn add --cwd packages/app @backstage/plugin-search @backstage/plugin-search-react
```
Create a new `packages/app/src/components/search/SearchPage.tsx` file in your
@@ -33,7 +33,7 @@ import {
SearchResult,
DefaultResultListItem,
SearchFilter,
} from '@backstage/plugin-search';
} from '@backstage/plugin-search-react';
import { CatalogResultListItem } from '@backstage/plugin-catalog';
export const searchPage = (
@@ -213,7 +213,7 @@ apiRouter.use('/search', await search(searchEnv));
### Frontend
The Search Plugin exposes several default filter types as static properties,
The Search Plugin web library (`@backstage/plugin-search-react`) exposes several default filter types as static properties,
including `<SearchFilter.Select />` and `<SearchFilter.Checkbox />`. These allow
you to provide values relevant to your Backstage instance that, when selected,
get passed to the backend.
@@ -237,7 +237,7 @@ If you have advanced filter needs, you can specify your own filter component
like this (although new core filter contributions are welcome):
```tsx
import { useSearch, SearchFilter } from '@backstage/plugin-search';
import { useSearch, SearchFilter } from '@backstage/plugin-search-react';
const MyCustomFilter = () => {
// Note: filters contain filter data from other filter components. Be sure
+25
View File
@@ -102,6 +102,31 @@ import { Client } from '@elastic/elastic-search';
const client = searchEngine.newClient(options => new Client(options));
```
#### Set custom index template
The elasticsearch engine gives you the ability to set a custom index template if needed.
> Index templates define settings, mappings, and aliases that can be applied automatically to new indices.
```typescript
// app/backend/src/plugins/search.ts
const searchEngine = await ElasticSearchSearchEngine.initialize({
logger: env.logger,
config: env.config,
});
searchEngine.setIndexTemplate({
name: '<name-of-your-custom-template>',
body: {
index_patterns: ['<your-index-pattern>'],
template: {
mappings: {},
settings: {},
},
},
});
```
## Example configurations
### AWS
@@ -55,6 +55,7 @@ metadata:
- url: https://admin.example-org.com
title: Admin Dashboard
icon: dashboard
type: admin-dashboard
spec:
type: website
lifecycle: production
@@ -83,7 +84,8 @@ This is the same entity as returned in JSON from the software catalog API:
{
"url": "https://admin.example-org.com",
"title": "Admin Dashboard",
"icon": "dashboard"
"icon": "dashboard",
"type": "admin-dashboard"
}
],
"tags": ["java"],
@@ -353,6 +355,7 @@ Fields of a link are:
| `url` | String | [Required] A `url` in a standard `uri` format (e.g. `https://example.com/some/page`) |
| `title` | String | [Optional] A user friendly display name for the link. |
| `icon` | String | [Optional] A key representing a visual icon to be displayed in the UI. |
| `type` | String | [Optional] An optional value to categorize links into specific groups. |
_NOTE_: The `icon` field value is meant to be a semantic key that will map to a
specific icon that may be provided by an icon library (e.g. `material-ui`
@@ -362,6 +365,8 @@ Backstage integrator will ultimately be left to provide the appropriate icon
component mappings. A generic fallback icon would be provided if a mapping
cannot be resolved.
The semantics of the `type` field are undefined. The adopter is free to define their own set of types and utilize them as they wish. Some potential use cases can be to utilize the type field to validate certain links exist on entities or to create customized UI components for specific link types.
## Common to All Kinds: Relations
The `relations` root field is a read-only list of relations, between the current
@@ -33,8 +33,8 @@ tracked in source control, or use some existing open source or commercial
software.
A component can implement APIs for other components to consume. In turn it might
depend on APIs implemented by other components, or resources that are attached
to it at runtime.
consume APIs implemented by other components, or directly depend on components or
resources that are attached to it at runtime.
### API
@@ -353,6 +353,19 @@ to `scm-only`, the plugin will only take into account files stored in source
control (e.g. ignoring generated code). If set to `enabled`, all files covered
by a coverage report will be taken into account.
### vault.io/secrets-path
```yaml
# Example:
metadata:
annotations:
vault.io/secrets-path: test/backstage
```
The value of this annotation contains the path to the secrets of the entity in
Vault. If not present when the Vault plugin is in use, a message will be shown
instead, letting the user know what is missing in the `catalog-info.yaml`.
## Deprecated Annotations
The following annotations are deprecated, and only listed here to aid in
@@ -397,6 +397,29 @@ There's also the ability to pass additional scopes when requesting the `oauth`
token from the user, which you can do on a per-provider basis, in case your
template can be published to multiple providers.
Note, that you will need to configure an [authentication provider](../../auth/index.md#configuring-authentication-providers), alongside the
[`ScmAuthApi`](../../auth/index.md#scaffolder-configuration-software-templates) for your source code management (SCM) service to make this feature work.
### Accessing the signed-in users details
Sometimes when authoring templates, you'll want to access the user that is running the template, and get details from the profile or the users `Entity` in the Catalog.
If you have enabled a sign in provider and have a [sign in resolver](../../auth/identity-resolver.md) that points to a user in the Catalog, then you can use the `${{ user.entity }}` templating expression to access the raw entity from the Catalog.
This can be particularly useful if you have processors setup in the Catalog to write `spec.profile.email` of the `User Entities` to reference them and pass them into actions like below:
```yaml
steps:
action: publish:github
...
input:
...
gitAuthorName: ${{ user.entity.metadata.name }}
gitAuthorEmail: ${{ user.entity.spec.profile.email }}
```
You also have access to `user.entity.metadata.annotations` too, so if you have some other additional information stored in there, you reference those too.
### The Owner Picker
When the scaffolder needs to add new components to the catalog, it needs to have
+1 -1
View File
@@ -95,7 +95,7 @@ See [TechDocs Architecture](architecture.md) to get an overview of where the bel
[techdocs/frontend-library]: https://github.com/backstage/backstage/blob/master/plugins/techdocs-react
[techdocs/backend]: https://github.com/backstage/backstage/blob/master/plugins/techdocs-backend
[techdocs/container]: https://github.com/backstage/techdocs-container
[techdocs/cli]: https://github.com/backstage/techdocs-cli
[techdocs/cli]: https://github.com/backstage/backstage/blob/master/packages/techdocs-cli
## Get involved
+13 -15
View File
@@ -164,27 +164,25 @@ Open `packages/app/src/App.tsx` and below the last `import` line, add:
```typescript
import { githubAuthApiRef } from '@backstage/core-plugin-api';
import { SignInProviderConfig, SignInPage } from '@backstage/core-components';
const githubProvider: SignInProviderConfig = {
id: 'github-auth-provider',
title: 'GitHub',
message: 'Sign in using GitHub',
apiRef: githubAuthApiRef,
};
```
Search for `const app = createApp({` in this file, and below `apis,` add:
```typescript
components: {
SignInPage: props => (
<SignInPage
{...props}
auto
provider={githubProvider}
/>
),
},
SignInPage: props => (
<SignInPage
{...props}
auto
provider={{
id: 'github-auth-provider',
title: 'GitHub',
message: 'Sign in using GitHub',
apiRef: githubAuthApiRef,
}}
/>
),
},
```
> Since [v1.1.0](https://github.com/backstage/backstage/releases/tag/v1.1.0-next.3), you must provide an [explicit sign-in resolver](../auth/identity-resolver.md).
+1 -1
View File
@@ -157,7 +157,7 @@ export const HomePage = () => {
return (
<Grid container spacing={3}>
<Grid item xs={12} md={4}>
<HomePageCompanyLogo className={container} />
<HomePageCompanyLogo />
</Grid>
</Grid>
);
+77 -23
View File
@@ -6,25 +6,95 @@ sidebar_label: Discovery
description: Automatically discovering catalog entities from repositories in an Azure DevOps organization
---
The Azure DevOps integration has a special discovery processor for discovering
catalog entities within an Azure DevOps. The processor will crawl the Azure
The Azure DevOps integration has a special entity provider for discovering
catalog entities within an Azure DevOps. The provider will crawl your Azure
DevOps organization and register entities matching the configured path. This can
be useful as an alternative to static locations or manually adding things to the
catalog.
This guide explains how to install and configure the Azure DevOps Entity Provider (recommended) or the Azure DevOps Processor.
## Dependencies
### Code Search Feature
Azure discovery is driven by the Code Search feature in Azure DevOps, this may not be enabled by default. For Azure
DevOps Services you can confirm this by looking at the installed extensions in your Organization Settings. For Azure
DevOps Server you'll find this information in your Collection Settings.
If the Code Search extension is not listed then you can install it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms.vss-code-search&targetId=f9352dac-ba6e-434e-9241-a848a510ce3f&utm_source=vstsproduct&utm_medium=SearchExtStatus).
### Azure Integration
Setup [Azure integration](locations.md) with `host` and `token`. Host must be `dev.azure.com` for Cloud users, otherwise set this to your on-premise hostname.
## Installation
You will have to add the processors in the catalog initialization code of your
backend. They are not installed by default, therefore you have to add a
dependency to `@backstage/plugin-catalog-backend-module-azure` to your backend
package.
At your configuration, you add one or more provider configs:
```yaml
# app-config.yaml
catalog:
providers:
azureDevOps:
yourProviderId: # identifies your dataset / provider independent of config changes
organization: myorg
project: myproject
repository: service-* # this will match all repos starting with service-*
path: /catalog-info.yaml
anotherProviderId: # another identifier
organization: myorg
project: myproject
repository: '*' # this will match all repos starting with service-*
path: /src/*/catalog-info.yaml # this will search for files deep inside the /src folder
yetAotherProviderId: # guess, what? Another one :)
host: selfhostedazure.yourcompany.com
organization: myorg
project: myproject
```
The parameters available are:
- `host:` Leave empty for Cloud hosted, otherwise set to your self-hosted instance host.
- `organization:` Your Organization slug (or Collection for on-premise users). Required.
- `project:` Your project slug. Required.
- `repository:` The repository name. Wildcards are supported as show on the examples above. If not set, all repositories will be searched.
- `path:` Where to find catalog-info.yaml files. Defaults to /catalog-info.yaml.
_Note:_ the path parameter follows the same rules as the search on Azure DevOps
web interface. For more details visit the
[official search documentation](https://docs.microsoft.com/en-us/azure/devops/project/search/get-started-search?view=azure-devops).
As this provider is not one of the default providers, you will first need to install
the Azure catalog plugin:
```bash
# From your Backstage root directory
yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-azure
```
And then add the processors to your catalog builder:
Once you've done that, you'll also need to add the segment below to `packages/backend/src/plugins/catalog.ts`:
```diff
/* packages/backend/src/plugins/catalog.ts */
+import { AzureDevOpsEntityProvider } from '@backstage/plugin-catalog-backend-module-azure';
const builder = await CatalogBuilder.create(env);
/** ... other processors and/or providers ... */
+builder.addEntityProvider(
+ AzureDevOpsEntityProvider.fromConfig(env.config, {
+ logger: env.logger,
+ schedule: env.scheduler.createScheduledTaskRunner({
+ frequency: Duration.fromObject({ minutes: 30 }),
+ timeout: Duration.fromObject({ minutes: 3 }),
+ }),
+ }),
+);
```
## Alternative Processor
As an alternative to the entity provider `AzureDevOpsEntityProvider`, you can still use the `AzureDevopsDiscoveryProcessor`.
```diff
// In packages/backend/src/plugins/catalog.ts
@@ -37,12 +107,6 @@ And then add the processors to your catalog builder:
+ builder.addProcessor(AzureDevOpsDiscoveryProcessor.fromConfig(env.config, { logger: env.logger }));
```
## Configuration
To use the discovery processor, you'll need a Azure integration
[set up](locations.md) with a `AZURE_TOKEN`. Then you can add a location target
to the catalog configuration:
```yaml
catalog:
locations:
@@ -70,13 +134,3 @@ When using a custom pattern, the target is composed of five parts:
- The path within each repository to find the catalog YAML file. This will
usually be `/catalog-info.yaml`, `/src/*/catalog-info.yaml` or a similar
variation for catalog files stored in the root directory of each repository.
_Note:_ the path parameter follows the same rules as the search on Azure DevOps
web interface. For more details visit the
[official search documentation](https://docs.microsoft.com/en-us/azure/devops/project/search/get-started-search?view=azure-devops).
Azure discovery is driven by the Code Search feature in Azure DevOps, this may not be enabled by default. For Azure
DevOps Services you can confirm this by looking at the installed extensions in your Organization Settings. For Azure
DevOps Server you'll find this information in your Collection Settings.
If the Code Search extension is not listed then you can install it from the [Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=ms.vss-code-search&targetId=f9352dac-ba6e-434e-9241-a848a510ce3f&utm_source=vstsproduct&utm_medium=SearchExtStatus).
+50 -6
View File
@@ -6,14 +6,55 @@ sidebar_label: Discovery
description: Automatically discovering catalog entities from repositories in GitLab
---
The GitLab integration has a special discovery processor for discovering catalog
entities from GitLab. The processor will crawl the GitLab instance and register
entities matching the configured path. This can be useful as an alternative to
The GitLab integration has a special entity provider for discovering catalog
entities from GitLab. The entity provider will crawl the GitLab instance and register
entities matching the configured paths. This can be useful as an alternative to
static locations or manually adding things to the catalog.
To use the discovery processor, you'll need a GitLab integration
[set up](locations.md) with a `token`. Then you can add a location target to the
catalog configuration:
To use the discovery provider, you'll need a GitLab integration
[set up](locations.md) with a `token`. Then you can add a provider config per group
to the catalog configuration:
```yaml
catalog:
providers:
gitlab:
yourProviderId:
host: gitlab-host # Identifies one of the hosts set up in the integrations
branch: main # Optional. Uses `master` as default
group: example-group # Group and subgroup (if needed) to look for repositories
entityFilename: catalog-info.yaml # Optional. Defaults to `catalog-info.yaml`
```
As this provider is not one of the default providers, you will first need to install
the gitlab catalog plugin:
```bash
# From the Backstage root directory
yarn add --cwd packages/backend @backstage/plugin-catalog-backend-module-gitlab
```
Once you've done that, you'll also need to add the segment below to `packages/backend/src/plugins/catalog.ts`:
```ts
/* packages/backend/src/plugins/catalog.ts */
import { GitlabDiscoveryEntityProvider } from '@backstage/plugin-catalog-backend-module-gitlab';
const builder = await CatalogBuilder.create(env);
/** ... other processors and/or providers ... */
builder.addEntityProvider(
...GitlabDiscoveryEntityProvider.fromConfig(env.config, {
logger: env.logger,
schedule: env.scheduler.createScheduledTaskRunner({
frequency: { minutes: 30 },
timeout: { minutes: 3 },
}),
}),
);
```
## Alternative processor
```yaml
catalog:
@@ -22,6 +63,9 @@ catalog:
target: https://gitlab.com/group/subgroup/blob/main/catalog-info.yaml
```
As alternative to the entity provider `GitlabDiscoveryEntityProvider`
you can still use the `GitLabDiscoveryProcessor`.
Note the `gitlab-discovery` type, as this is not a regular `url` processor.
The target is composed of three parts:
+6 -5
View File
@@ -52,11 +52,12 @@ learn how to contribute the integration yourself!
The following table summarizes events that, depending on the plugins you have
installed, may be captured.
| Action | Provided By | Subject |
| ---------- | -------------- | --------------------------------------------------- |
| `navigate` | Backstage Core | The URL of the page that was navigated to |
| `click` | Backstage Core | The text of the link that was clicked on |
| `search` | Backstage Core | The search term entered in any search bar component |
| Action | Subject | Other Notes |
| ---------- | --------------------------------------------------- | ----------------------------------------------------------------- |
| `navigate` | The URL of the page that was navigated to | |
| `click` | The text of the link that was clicked on | The `to` attribute represents the URL clicked to |
| `search` | The search term entered in any search bar component | The `searchTypes` attribute holds `types` constraining the search |
| `discover` | The title of the search result that was clicked on | The `value` is the result rank. A `to` attribute is also provided |
If there is an event you'd like to see captured, please [open an
issue][add-event] describing the event you want to see and the questions it
+2 -2
View File
@@ -104,10 +104,10 @@ directly be used with a URL. Some example usages -
- [`read`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/plugins/catalog-backend/src/ingestion/processors/codeowners/read.ts#L24-L33) -
Catalog using the `read` method to read the CODEOWNERS file in a repository.
- [`readTree`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/techdocs-common/src/helpers.ts#L198-L220) -
- [`readTree`](https://github.com/backstage/backstage/blob/84a8788/plugins/techdocs-node/src/helpers.ts#L146-L167) -
TechDocs using the `readTree` method to download markdown files in order to
generate the documentation site.
- [`readTree`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/packages/techdocs-common/src/stages/prepare/url.ts#L33-L54) -
- [`readTree`](https://github.com/backstage/backstage/blob/cb4f0e4/plugins/techdocs-node/src/stages/prepare/url.ts#L51-L73) -
TechDocs using `NotModifiedError` to maintain cache and speed up and limit the
number of requests.
- [`search`](https://github.com/backstage/backstage/blob/d5c83bb889b8142e343ebc4e4c0b90a02d1c1a3d/plugins/catalog-backend/src/ingestion/processors/UrlReaderProcessor.ts#L88-L108) -
File diff suppressed because it is too large Load Diff
+678
View File
@@ -0,0 +1,678 @@
# Release v1.3.0-next.2
## @backstage/backend-common@0.14.0-next.2
### Minor Changes
- 55647ec7df: **BREAKING**: Server-to-server tokens that are authenticated by the `ServerTokenManager` now must have an `exp` claim that has not expired. Tokens where the `exp` claim is in the past or missing are considered invalid and will throw an error. This is a followup to the deprecation from the `1.2` release of Backstage where perpetual tokens were deprecated. Be sure to update any usage of the `getToken()` method to have it be called every time a token is needed. Do not store tokens for later use.
### Patch Changes
- Updated dependencies
- @backstage/integration@1.2.1-next.2
## @backstage/plugin-pagerduty@0.4.0-next.2
### Minor Changes
- b157c2eb1c: **Breaking**: Use identityApi to provide auth token for pagerduty API calls.
### Patch Changes
- Updated dependencies
- @backstage/core-components@0.9.5-next.2
## @backstage/plugin-scaffolder@1.3.0-next.2
### Minor Changes
- dc39366bdb: - Added a new page under `/create/tasks` to show tasks that have been run by the Scaffolder.
- Ability to filter these tasks by the signed in user, and all tasks.
- Added optional method to the `ScaffolderApi` interface called `listTasks` to get tasks with an required `filterByOwnership` parameter.
### Patch Changes
- ac0c7e45ee: Fixes review mask in `MultistepJsonForm` to work as documented. `show: true` no longer needed when mask is set.
- fd505f40c0: Handle binary files and files that are too large during dry-run content upload.
- Updated dependencies
- @backstage/plugin-catalog-common@1.0.3-next.1
- @backstage/core-components@0.9.5-next.2
- @backstage/integration@1.2.1-next.2
## @backstage/plugin-scaffolder-backend@1.3.0-next.2
### Minor Changes
- ce0d8d7eb1: Fixed a bug in `publish:github` action that didn't permit to add users as collaborators.
This fix required changing the way parameters are passed to the action.
In order to add a team as collaborator, now you must use the `team` field instead of `username`.
In order to add a user as collaborator, you must use the `user` field.
It's still possible to use the field `username` but is deprecated in favor of `team`.
```yaml
- id: publish
name: Publish
action: publish:github
input:
repoUrl: ...
collaborators:
- access: ...
team: my_team
- access: ...
user: my_username
```
- 582003a059: - Added an optional `list` method on the `TaskBroker` and `TaskStore` interface to list tasks by an optional `userEntityRef`
- Implemented a `list` method on the `DatabaseTaskStore` class to list tasks by an optional `userEntityRef`
- Added a route under `/v2/tasks` to list tasks by a `userEntityRef` using the `createdBy` query parameter
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/plugin-catalog-backend@1.2.0-next.2
## @backstage/backend-tasks@0.3.2-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/backend-test-utils@0.1.25-next.2
### Patch Changes
- Updated dependencies
- @backstage/cli@0.17.2-next.2
- @backstage/backend-common@0.14.0-next.2
## @backstage/cli@0.17.2-next.2
### Patch Changes
- 026cfe525a: Fix the public path configuration of the frontend app build so that a trailing `/` is always appended when needed.
- 9002ebd76b: Updated dependency `@rollup/plugin-commonjs` to `^22.0.0`.
- 1a33e8b287: Updated dependency `minimatch` to `5.1.0`.
## @backstage/core-components@0.9.5-next.2
### Patch Changes
- ee2cd642c5: Updated dependency `rc-progress` to `3.3.3`.
- 1cf9caecd6: fix Sidebar Contexts deprecation message
## @backstage/create-app@0.4.28-next.2
### Patch Changes
- aaf7652084: Bump version of `cypress` in newly scaffolded Backstage Applications. To apply this change to your own instance, please make the following change to `packages/app/package.json` under `devDependencies`.
```diff
- "cypress": "^7.3.0",
+ "cypress": "^9.7.0",
```
## @backstage/integration@1.2.1-next.2
### Patch Changes
- e37c71b5a4: Updated to support deployments of Azure DevOps Server under TFS or similar sub path
## @backstage/search-common@0.3.5-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
## @techdocs/cli@1.1.2-next.2
### Patch Changes
- f96e98f4cd: Updated dependency `cypress` to `^10.0.0`.
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-techdocs-node@1.1.2-next.2
## @backstage/techdocs-common@0.11.16-next.2
### Patch Changes
- Updated dependencies
- @backstage/plugin-techdocs-node@1.1.2-next.2
## @backstage/plugin-adr-backend@0.1.1-next.2
### Patch Changes
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
## @backstage/plugin-airbrake-backend@0.2.6-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-app-backend@0.3.33-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-auth-backend@0.14.1-next.2
### Patch Changes
- bc6fb57094: Updated dependency `passport` to `^0.6.0`.
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-auth-node@0.2.2-next.2
## @backstage/plugin-auth-node@0.2.2-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-azure-devops-backend@0.3.12-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-badges-backend@0.1.27-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-bazaar-backend@0.1.17-next.1
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/backend-test-utils@0.1.25-next.2
## @backstage/plugin-catalog-backend@1.2.0-next.2
### Patch Changes
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/plugin-catalog-common@1.0.3-next.1
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/plugin-permission-node@0.6.2-next.2
## @backstage/plugin-catalog-backend-module-aws@0.1.6-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/backend-tasks@0.3.2-next.2
- @backstage/plugin-catalog-backend@1.2.0-next.2
## @backstage/plugin-catalog-backend-module-azure@0.1.4-next.2
### Patch Changes
- b8884fd579: Add a new provider `AzureDevOpsEntityProvider` as replacement for `AzureDevOpsDiscoveryProcessor`.
In order to migrate from the `AzureDevOpsDiscoveryProcessor` you need to apply
the following changes:
**Before:**
```yaml
# app-config.yaml
catalog:
locations:
- type: azure-discovery
target: https://dev.azure.com/myorg/myproject/_git/service-*?path=/catalog-info.yaml
```
```ts
/* packages/backend/src/plugins/catalog.ts */
import { AzureDevOpsDiscoveryProcessor } from '@backstage/plugin-catalog-backend-module-azure';
const builder = await CatalogBuilder.create(env);
/** ... other processors ... */
builder.addProcessor(new AzureDevOpsDiscoveryProcessor(env.reader));
```
**After:**
```yaml
# app-config.yaml
catalog:
providers:
azureDevOps:
anyProviderId:
host: selfhostedazure.yourcompany.com # This is only really needed for on-premise user, defaults to dev.azure.com
organization: myorg # For on-premise this would be your Collection
project: myproject
repository: service-*
path: /catalog-info.yaml
```
```ts
/* packages/backend/src/plugins/catalog.ts */
import { AzureDevOpsEntityProvider } from '@backstage/plugin-catalog-backend-module-azure';
const builder = await CatalogBuilder.create(env);
/** ... other processors and/or providers ... */
builder.addEntityProvider(
AzureDevOpsEntityProvider.fromConfig(env.config, {
logger: env.logger,
schedule: env.scheduler.createScheduledTaskRunner({
frequency: { minutes: 30 },
timeout: { minutes: 3 },
}),
}),
);
```
Visit <https://backstage.io/docs/integrations/azure/discovery> for more details and options on configuration.
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/backend-tasks@0.3.2-next.2
- @backstage/plugin-catalog-backend@1.2.0-next.2
## @backstage/plugin-catalog-backend-module-bitbucket@0.2.0-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/plugin-catalog-backend@1.2.0-next.2
## @backstage/plugin-catalog-backend-module-gerrit@0.1.1-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/backend-tasks@0.3.2-next.2
- @backstage/plugin-catalog-backend@1.2.0-next.2
## @backstage/plugin-catalog-backend-module-github@0.1.4-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/backend-tasks@0.3.2-next.2
- @backstage/plugin-catalog-backend@1.2.0-next.2
## @backstage/plugin-catalog-backend-module-gitlab@0.1.4-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/plugin-catalog-backend@1.2.0-next.2
## @backstage/plugin-catalog-common@1.0.3-next.1
### Patch Changes
- 7d8acfc32e: Replaced all usages of `@backstage/search-common` with `@backstage/plugin-search-common`
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
## @backstage/plugin-code-coverage-backend@0.1.31-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
## @backstage/plugin-codescene@0.1.1-next.2
### Patch Changes
- ee2cd642c5: Updated dependency `rc-progress` to `3.3.3`.
- Updated dependencies
- @backstage/core-components@0.9.5-next.2
## @backstage/plugin-cost-insights@0.11.28-next.2
### Patch Changes
- 2fc98ac50c: Fix broken app-config in the example in the README
- Updated dependencies
- @backstage/core-components@0.9.5-next.2
## @backstage/plugin-graphql-backend@0.1.23-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-jenkins-backend@0.1.23-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-auth-node@0.2.2-next.2
## @backstage/plugin-kafka-backend@0.2.26-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-kubernetes@0.6.6-next.2
### Patch Changes
- 5553f09e80: ability to configure refresh interval on Kubernetes tab
- Updated dependencies
- @backstage/core-components@0.9.5-next.2
## @backstage/plugin-kubernetes-backend@0.6.0-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-org@0.5.6-next.2
### Patch Changes
- 306d0b4fdd: Added the ability to use an additional `filter` when fetching groups in `MyGroupsSidebarItem` component. Example:
```diff
// app/src/components/Root/Root.tsx
<SidebarPage>
<Sidebar>
//...
<SidebarGroup label="Menu" icon={<MenuIcon />}>
{/* Global nav, not org-specific */}
//...
<SidebarItem icon={HomeIcon} to="catalog" text="Home" />
<MyGroupsSidebarItem
singularTitle="My Squad"
pluralTitle="My Squads"
icon={GroupIcon}
+ filter={{ 'spec.type': 'team' }}
/>
//...
</SidebarGroup>
</ Sidebar>
</SidebarPage>
```
- Updated dependencies
- @backstage/core-components@0.9.5-next.2
## @backstage/plugin-periskop-backend@0.1.4-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-permission-backend@0.5.8-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-auth-node@0.2.2-next.2
- @backstage/plugin-permission-node@0.6.2-next.2
## @backstage/plugin-permission-node@0.6.2-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-auth-node@0.2.2-next.2
## @backstage/plugin-proxy-backend@0.2.27-next.1
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-rollbar-backend@0.1.30-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-scaffolder-backend-module-cookiecutter@0.2.8-next.2
### Patch Changes
- Updated dependencies
- @backstage/plugin-scaffolder-backend@1.3.0-next.2
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
## @backstage/plugin-scaffolder-backend-module-rails@0.4.1-next.1
### Patch Changes
- Updated dependencies
- @backstage/plugin-scaffolder-backend@1.3.0-next.2
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
## @backstage/plugin-search@0.8.2-next.2
### Patch Changes
- 5388e6bdc5: Fixed a bug that could cause analytics events in other parts of Backstage to capture nonsensical values resembling search modal state under some circumstances.
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/core-components@0.9.5-next.2
## @backstage/plugin-search-backend@0.5.3-next.2
### Patch Changes
- 7d8acfc32e: `RouterOptions` and `createRouter` now marked as public exports
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-search-backend-node@0.6.2-next.2
- @backstage/plugin-auth-node@0.2.2-next.2
- @backstage/plugin-permission-node@0.6.2-next.2
## @backstage/plugin-search-backend-module-elasticsearch@0.1.5-next.2
### Patch Changes
- 7d8acfc32e: Additional types now exported publicly:
- ElasticSearchAgentOptions
- ElasticSearchConcreteQuery
- ElasticSearchQueryTranslator
- ElasticSearchConnectionConstructor,
- ElasticSearchTransportConstructor,
- ElasticSearchNodeOptions,
- ElasticSearchOptions,
- ElasticSearchAuth,
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/plugin-search-backend-node@0.6.2-next.2
## @backstage/plugin-search-backend-module-pg@0.3.4-next.2
### Patch Changes
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-search-backend-node@0.6.2-next.2
## @backstage/plugin-search-backend-node@0.6.2-next.2
### Patch Changes
- 7d8acfc32e: Replaced all `@beta` exports with `@public` exports
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/backend-common@0.14.0-next.2
- @backstage/backend-tasks@0.3.2-next.2
## @backstage/plugin-search-common@0.3.5-next.1
### Patch Changes
- 7d8acfc32e: `@beta` exports now replaced with `@public` exports
## @backstage/plugin-sonarqube@0.3.6-next.2
### Patch Changes
- ee2cd642c5: Updated dependency `rc-progress` to `3.3.3`.
- Updated dependencies
- @backstage/core-components@0.9.5-next.2
## @backstage/plugin-tech-insights-backend@0.4.1-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/backend-tasks@0.3.2-next.2
- @backstage/plugin-tech-insights-node@0.3.1-next.1
## @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.17-next.1
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-tech-insights-node@0.3.1-next.1
## @backstage/plugin-tech-insights-node@0.3.1-next.1
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
## @backstage/plugin-techdocs-backend@1.1.2-next.2
### Patch Changes
- 61fba6e50b: In order to ensure a good, stable TechDocs user experience when running TechDocs with `techdocs.builder` set to `local`, the number of concurrent builds has been limited to 10. Any additional builds requested concurrently will be queued and handled as prior builds complete. In the unlikely event that you need to handle more concurrent builds, consider scaling out your TechDocs backend deployment or using the `external` option for `techdocs.builder`.
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/plugin-catalog-common@1.0.3-next.1
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/plugin-techdocs-node@1.1.2-next.2
## @backstage/plugin-techdocs-node@1.1.2-next.2
### Patch Changes
- Updated dependencies
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
## @backstage/plugin-todo-backend@0.1.30-next.2
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/integration@1.2.1-next.2
## example-app@0.2.72-next.2
### Patch Changes
- Updated dependencies
- @backstage/plugin-scaffolder@1.3.0-next.2
- @backstage/cli@0.17.2-next.2
- @backstage/plugin-pagerduty@0.4.0-next.2
- @backstage/plugin-search-common@0.3.5-next.1
- @backstage/plugin-cost-insights@0.11.28-next.2
- @backstage/plugin-catalog-common@1.0.3-next.1
- @backstage/plugin-kubernetes@0.6.6-next.2
- @backstage/core-components@0.9.5-next.2
- @backstage/plugin-search@0.8.2-next.2
- @backstage/plugin-org@0.5.6-next.2
## example-backend@0.2.72-next.2
### Patch Changes
- Updated dependencies
- @backstage/plugin-scaffolder-backend@1.3.0-next.2
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-search-backend@0.5.3-next.2
- @backstage/plugin-auth-backend@0.14.1-next.2
- @backstage/plugin-search-backend-module-elasticsearch@0.1.5-next.2
- @backstage/integration@1.2.1-next.2
- @backstage/plugin-techdocs-backend@1.1.2-next.2
- @backstage/plugin-search-backend-node@0.6.2-next.2
- example-app@0.2.72-next.2
- @backstage/backend-tasks@0.3.2-next.2
- @backstage/plugin-app-backend@0.3.33-next.2
- @backstage/plugin-auth-node@0.2.2-next.2
- @backstage/plugin-azure-devops-backend@0.3.12-next.2
- @backstage/plugin-badges-backend@0.1.27-next.2
- @backstage/plugin-catalog-backend@1.2.0-next.2
- @backstage/plugin-code-coverage-backend@0.1.31-next.2
- @backstage/plugin-graphql-backend@0.1.23-next.2
- @backstage/plugin-jenkins-backend@0.1.23-next.2
- @backstage/plugin-kafka-backend@0.2.26-next.2
- @backstage/plugin-kubernetes-backend@0.6.0-next.2
- @backstage/plugin-permission-backend@0.5.8-next.2
- @backstage/plugin-permission-node@0.6.2-next.2
- @backstage/plugin-proxy-backend@0.2.27-next.1
- @backstage/plugin-rollbar-backend@0.1.30-next.2
- @backstage/plugin-scaffolder-backend-module-rails@0.4.1-next.1
- @backstage/plugin-search-backend-module-pg@0.3.4-next.2
- @backstage/plugin-tech-insights-backend@0.4.1-next.2
- @backstage/plugin-tech-insights-backend-module-jsonfc@0.1.17-next.1
- @backstage/plugin-tech-insights-node@0.3.1-next.1
- @backstage/plugin-todo-backend@0.1.30-next.2
## @internal/plugin-todo-list-backend@1.0.2-next.1
### Patch Changes
- Updated dependencies
- @backstage/backend-common@0.14.0-next.2
- @backstage/plugin-auth-node@0.2.2-next.2
+65
View File
@@ -0,0 +1,65 @@
---
id: v1.3.0
title: v1.3.0
description: Backstage Release v1.3.0
---
These are the release notes for the v1.3.0 release of [Backstage](https://backstage.io/).
A huge thanks to the whole team of maintainers and contributors as well as the amazing Backstage Community for the hard work in getting this release developed and done.
## Highlights
### Scaffolder Dry Run and Template Editor
The scaffolder plugin now has a new template editor in addition to the form editor, which is accessible via the context menu on the top right hand corner of the Create page. It allows you to load a template from a local directory, edit it with a preview, execute it in dry-run mode, and view the results. Note that the [File System Access API](https://developer.mozilla.org/en-US/docs/Web/API/File_System_Access_API) must be supported by your browser for this to be available.
### TypeScript 4.7
The recommended TypeScript version has been bumped to `~4.7.0`, and thats what the main Backstage repository uses right now for its builds. Each Backstage project manages their version separately however, so there is no rush or immediate effect on users - you can update the `typescript` dependency in your root `package.json` once you feel ready to do so.
### Expiring Backend Tokens
In 1.2 we introduced expiry times for server-to-server authentication tokens issued from the standard `TokenManager`. At that point in time, the expiry was only added to tokens and not yet enforced. In this release however, it is now also enforced, meaning that expired tokens are considered invalid and will be rejected.
### Discovery providers
Several new [entity providers](https://backstage.io/docs/features/software-catalog/life-of-an-entity) have been contributed as replacements for their corresponding discovery processors. Entity providers allow for more control and are [recommended](https://backstage.io/docs/features/software-catalog/external-integrations) over their processing counterparts.
- `AzureDevOpsEntityProvider` as replacement for `AzureDevOpsDiscoveryProcessor`. PR [#11604](https://github.com/backstage/backstage/pull/11604) contributed by [@goenning](https://github.com/goenning)
- `GitlabDiscoveryEntityProvider` as replacement for `GitLabDiscoveryProcessor`. PR [#11886](https://github.com/backstage/backstage/pull/11886) contributed by [@ivangonzalezacuna](https://github.com/ivangonzalezacuna)
- `BitbucketCloudEntityProvider` as a replacement for `BitbucketDiscoveryProcessor` (for Bitbucket Cloud only). PR [#11345](https://github.com/backstage/backstage/pull/11345) contributed by [@pjungermann](https://github.com/pjungermann)
### New plugin: Vault
View secrets from [HashiCorp Vault](https://www.vaultproject.io/) alongside your components. PR [#11423](https://github.com/backstage/backstage/pull/11423) contributed by [@ivangonzalezacuna](https://github.com/ivangonzalezacuna)
### New plugin: GitHub Pull Requests Board
GitHub Pull Requests Board Plugin is a board that helps you visualize all open pull requests from all repositories owned by a team, with the main goal of reducing the time from opening a PR to merging it. PR [#11043](https://github.com/backstage/backstage/pull/11043) contributed by [@gregorytalita](https://github.com/gregorytalita)
### New plugin: Dynatrace
Displays tracing data from [Dynatrace](https://www.dynatrace.com/) alongside your components. PR [#11754](https://github.com/backstage/backstage/pull/11754) contributed by [@isand3r](https://github.com/isand3r)
## Security Fixes
`@backstage/plugin-scaffolder-backend`, please upgrade to the latest version if you are using this module.
`@backstage/plugin-techdocs-node`, please upgrade to the latest version if you are using this module.
## Upgrade path
We recommend that you keep your Backstage project up to date with this latest release. For more guidance on how to upgrade, check out the documentation for [keeping Backstage updated](https://backstage.io/docs/getting-started/keeping-backstage-updated).
## Links and References
Below you can find a list of links and references to help you learn about and start using this new release.
- [Backstage official website](https://backstage.io/), [documentation](https://backstage.io/docs/), and [getting started guide](https://backstage.io/docs/getting-started/)
- [GitHub repository](https://github.com/backstage/backstage)
- Backstage's [versioning and support policy](https://backstage.io/docs/overview/versioning-policy)
- [Community Discord](https://discord.gg/bFESRKVt) for discussions and support
- [Changelog](https://github.com/backstage/backstage/tree/master/docs/releases/v1.3.0-changelog.md)
- Backstage [Demos](https://backstage.io/demos), [Blog](https://backstage.io/blog), [Roadmap](https://backstage.io/docs/overview/roadmap), and [Plugins](https://backstage.io/plugins)
Sign up for our [newsletter](https://mailchi.mp/spotify/backstage-community) if you want to be informed about what is happening in the world of Backstage.
File diff suppressed because it is too large Load Diff