From 3aa3fc7cdfa32974d30421b7d1f2b78e22a2eb5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Wed, 29 May 2024 14:45:24 +0200 Subject: [PATCH] just some small service docs advancements MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- .changeset/moody-buttons-hope.md | 5 + .../core-services/permissions.md | 44 +++---- .../core-services/plugin-metadata.md | 26 ++++- package.json | 2 +- packages/backend-plugin-api/api-report.md | 55 ++++----- .../src/services/definitions/AuthService.ts | 107 +++++++++++++++++- .../src/services/definitions/CacheService.ts | 2 + .../services/definitions/DatabaseService.ts | 4 +- .../services/definitions/DiscoveryService.ts | 14 ++- .../services/definitions/HttpAuthService.ts | 67 ++++++++++- .../services/definitions/HttpRouterService.ts | 36 +++++- .../services/definitions/IdentityService.ts | 9 +- .../services/definitions/LifecycleService.ts | 4 + .../src/services/definitions/LoggerService.ts | 2 + .../definitions/PermissionsService.ts | 35 +++++- .../definitions/PluginMetadataService.ts | 7 ++ .../services/definitions/RootConfigService.ts | 6 + .../definitions/RootHttpRouterService.ts | 4 + .../definitions/RootLifecycleService.ts | 8 +- .../services/definitions/RootLoggerService.ts | 8 +- .../services/definitions/SchedulerService.ts | 2 + .../definitions/TokenManagerService.ts | 5 +- .../services/definitions/UrlReaderService.ts | 2 + .../services/definitions/UserInfoService.ts | 18 ++- 24 files changed, 401 insertions(+), 71 deletions(-) create mode 100644 .changeset/moody-buttons-hope.md diff --git a/.changeset/moody-buttons-hope.md b/.changeset/moody-buttons-hope.md new file mode 100644 index 0000000000..0b8f57f9bc --- /dev/null +++ b/.changeset/moody-buttons-hope.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-plugin-api': patch +--- + +Marked the `TokenManagerService` and `IdentityService` types as deprecated diff --git a/docs/backend-system/core-services/permissions.md b/docs/backend-system/core-services/permissions.md index d979932c2f..06e966bbb2 100644 --- a/docs/backend-system/core-services/permissions.md +++ b/docs/backend-system/core-services/permissions.md @@ -16,36 +16,42 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; -import { Router } from 'express'; +import { NotAllowedError } from '@backstage/errors'; +import { AuthorizeResult } from '@backstage/plugin-permission-common'; +import Router from 'express-promise-router'; -createBackendPlugin({ +export default createBackendPlugin({ pluginId: 'example', register(env) { env.registerInit({ deps: { permissions: coreServices.permissions, - http: coreServices.httpRouter, + httpRouter: coreServices.httpRouter, + httpAuth: coreServices.httpAuth, }, - async init({ permissions, http }) { - const router = Router(); - router.get('/test-me', (request, response) => { - // use the identity service to pull out the token from request headers - const { token } = await identity.getIdentity({ - request, - }); - - // ask the permissions framework what the decision is for the permission + async init({ permissions, httpRouter, httpAuth }) { + const endpoints = Router(); + endpoints.get('/test-me', (request, response) => { + // Ask the permissions framework what the decision is for the given + // permission, for the principal that made the original request. The + // `httpAuth` service helps us extract those credentials. We authorize + // a single permission here, so the result will be an array with one + // element accordingly. const permissionResponse = await permissions.authorize( - [ - { - permission: myCustomPermission, - }, - ], - { token }, + [{ permission: myCustomPermission }], + { credentials: await httpAuth.credentials(request) }, ); + + if (permissionResponse[0].result !== AuthorizeResult.ALLOW) { + throw new NotAllowedError( + 'You are not permitted to perform this action', + ); + } + + // TODO: Actual code goes here }); - http.use(router); + httpRouter.use(endpoints); }, }); }, diff --git a/docs/backend-system/core-services/plugin-metadata.md b/docs/backend-system/core-services/plugin-metadata.md index f045ed7f19..4038a40b6c 100644 --- a/docs/backend-system/core-services/plugin-metadata.md +++ b/docs/backend-system/core-services/plugin-metadata.md @@ -5,4 +5,28 @@ sidebar_label: Plugin Metadata description: Documentation for the Plugin Metadata service --- -TODO +This service allows you to query for metadata about the current plugin. In particular, this service is used by other plugin-scoped services, if they need to know what the ID is of the plugin that they are being instantiated for. + +## Using the service + +The following example shows a fake plugin-scoped service which wants to know what plugin it "belongs" to. + +```ts +import { + coreServices, + createServiceFactory, +} from '@backstage/backend-plugin-api'; + +export const myServiceFactory = createServiceFactory({ + service: myServiceRef, + deps: { + logger: coreServices.logger, + plugin: coreServices.pluginMetadata, + }, + async factory({ logger, plugin }) { + const pluginId = plugin.getId(); + logger.info(`Creating an instance of my service for plugin '${id}'`); + return ...; // TODO + }, +}); +``` diff --git a/package.json b/package.json index 46041abf6b..35bf7e9528 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "build:all": "backstage-cli repo build --all", "build:api-docs": "LANG=en_EN yarn build:api-reports --docs --exclude 'plugins/@(adr|adr-backend|adr-common|airbrake|airbrake-backend|allure|analytics-module-ga|analytics-module-ga4|analytics-module-newrelic-browser|apache-airflow|api-docs|api-docs-module-protoc-gen-doc|apollo-explorer|app-visualizer|azure-devops|azure-devops-backend|azure-devops-common|azure-sites|azure-sites-backend|azure-sites-common|badges|badges-backend|bazaar|bazaar-backend|bitbucket-cloud-common|bitrise|catalog-graph|catalog-graphql|catalog-import|catalog-unprocessed-entities|cicd-statistics|cicd-statistics-module-gitlab|circleci|cloudbuild|code-climate|code-coverage|code-coverage-backend|codescene|config-schema|cost-insights|cost-insights-common|dynatrace|entity-feedback|entity-feedback-backend|entity-feedback-common|entity-validation|example-todo-list|example-todo-list-backend|example-todo-list-common|firehydrant|fossa|gcalendar|gcp-projects|git-release-manager|github-actions|github-deployments|github-issues|github-pull-requests-board|gitops-profiles|gocd|graphiql|graphql-backend|graphql-voyager|ilert|jenkins|jenkins-backend|jenkins-common|kafka|kafka-backend|lighthouse|lighthouse-backend|lighthouse-common|linguist|linguist-backend|linguist-common|microsoft-calendar|newrelic|newrelic-dashboard|nomad|nomad-backend|octopus-deploy|opencost|pagerduty|periskop|periskop-backend|playlist|playlist-backend|playlist-common|proxy-backend|puppetdb|rollbar|rollbar-backend|sentry|shortcuts|splunk-on-call|stack-overflow|stack-overflow-backend|stackstorm|tech-radar|tech-radar-2|todo|todo-backend|xcmetrics)'", "build:api-reports": "yarn build:api-reports:only --tsc", - "build:api-reports:only": "backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", + "build:api-reports:only": "NODE_OPTIONS=--max-old-space-size=8192 backstage-repo-tools api-reports --allow-warnings 'packages/core-components,plugins/+(catalog|catalog-import|git-release-manager|jenkins|kubernetes)' -o ae-wrong-input-file-type --validate-release-tags", "build:backend": "yarn workspace example-backend build", "build:knip-reports": "backstage-repo-tools knip-reports", "build:plugins-report": "node ./scripts/build-plugins-report", diff --git a/packages/backend-plugin-api/api-report.md b/packages/backend-plugin-api/api-report.md index 5e59378760..70ab3d8eed 100644 --- a/packages/backend-plugin-api/api-report.md +++ b/packages/backend-plugin-api/api-report.md @@ -24,41 +24,34 @@ import { Readable } from 'stream'; import { Request as Request_2 } from 'express'; import { Response as Response_2 } from 'express'; -// @public (undocumented) +// @public export interface AuthService { - // (undocumented) authenticate( token: string, options?: { allowLimitedAccess?: boolean; }, ): Promise; - // (undocumented) getLimitedUserToken( credentials: BackstageCredentials, ): Promise<{ token: string; expiresAt: Date; }>; - // (undocumented) getNoneCredentials(): Promise>; - // (undocumented) getOwnServiceCredentials(): Promise< BackstageCredentials >; - // (undocumented) getPluginRequestToken(options: { onBehalfOf: BackstageCredentials; targetPluginId: string; }): Promise<{ token: string; }>; - // (undocumented) isPrincipal( credentials: BackstageCredentials, type: TType, ): credentials is BackstageCredentials; - // (undocumented) listPublicServiceKeys(): Promise<{ keys: JsonObject[]; }>; @@ -116,14 +109,14 @@ export interface BackendPluginRegistrationPoints { }): void; } -// @public (undocumented) +// @public export type BackstageCredentials = { $$type: '@backstage/BackstageCredentials'; expiresAt?: Date; principal: TPrincipal; }; -// @public (undocumented) +// @public export type BackstageNonePrincipal = { type: 'none'; }; @@ -136,7 +129,7 @@ export type BackstagePrincipalAccessRestrictions = { }; }; -// @public (undocumented) +// @public export type BackstagePrincipalTypes = { user: BackstageUserPrincipal; service: BackstageServicePrincipal; @@ -144,14 +137,14 @@ export type BackstagePrincipalTypes = { unknown: unknown; }; -// @public (undocumented) +// @public export type BackstageServicePrincipal = { type: 'service'; subject: string; accessRestrictions?: BackstagePrincipalAccessRestrictions; }; -// @public (undocumented) +// @public export interface BackstageUserInfo { // (undocumented) ownershipEntityRefs: string[]; @@ -159,7 +152,7 @@ export interface BackstageUserInfo { userEntityRef: string; } -// @public (undocumented) +// @public export type BackstageUserPrincipal = { type: 'user'; userEntityRef: string; @@ -334,9 +327,8 @@ export type ExtensionPoint = { // @public @deprecated (undocumented) export type ExtensionPointConfig = CreateExtensionPointOptions; -// @public (undocumented) +// @public export interface HttpAuthService { - // (undocumented) credentials( req: Request_2, options?: { @@ -344,7 +336,6 @@ export interface HttpAuthService { allowLimitedAccess?: boolean; }, ): Promise>; - // (undocumented) issueUserCookie( res: Response_2, options?: { @@ -355,15 +346,13 @@ export interface HttpAuthService { }>; } -// @public (undocumented) +// @public export interface HttpRouterService { - // (undocumented) addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void; - // (undocumented) use(handler: Handler): void; } -// @public (undocumented) +// @public export interface HttpRouterServiceAuthPolicy { // (undocumented) allow: 'unauthenticated' | 'user-cookie'; @@ -371,7 +360,7 @@ export interface HttpRouterServiceAuthPolicy { path: string; } -// @public (undocumented) +// @public @deprecated export interface IdentityService extends IdentityApi {} export { isChildPath }; @@ -379,7 +368,7 @@ export { isChildPath }; // @public export function isDatabaseConflictError(e: unknown): boolean; -// @public (undocumented) +// @public export interface LifecycleService { addShutdownHook( hook: LifecycleServiceShutdownHook, @@ -421,14 +410,12 @@ export interface LoggerService { warn(message: string, meta?: Error | JsonObject): void; } -// @public (undocumented) +// @public export interface PermissionsService extends PermissionEvaluator { - // (undocumented) authorize( requests: AuthorizePermissionRequest[], options?: PermissionsServiceRequestOptions, ): Promise; - // (undocumented) authorizeConditional( requests: QueryPermissionRequest[], options?: PermissionsServiceRequestOptions, @@ -444,9 +431,8 @@ export type PermissionsServiceRequestOptions = credentials: BackstageCredentials; }; -// @public (undocumented) +// @public export interface PluginMetadataService { - // (undocumented) getId(): string; } @@ -535,18 +521,18 @@ export function resolvePackagePath(name: string, ...paths: string[]): string; // @public export function resolveSafeChildPath(base: string, path: string): string; -// @public (undocumented) +// @public export interface RootConfigService extends Config {} -// @public (undocumented) +// @public export interface RootHttpRouterService { use(path: string, handler: Handler): void; } -// @public (undocumented) +// @public export interface RootLifecycleService extends LifecycleService {} -// @public (undocumented) +// @public export interface RootLoggerService extends LoggerService {} // @public (undocumented) @@ -686,7 +672,7 @@ export interface ServiceRefConfig { scope?: TScope; } -// @public +// @public @deprecated export interface TokenManagerService { authenticate(token: string): Promise; getToken(): Promise<{ @@ -701,9 +687,8 @@ export interface UrlReaderService { search(url: string, options?: SearchOptions): Promise; } -// @public (undocumented) +// @public export interface UserInfoService { - // (undocumented) getUserInfo(credentials: BackstageCredentials): Promise; } ``` diff --git a/packages/backend-plugin-api/src/services/definitions/AuthService.ts b/packages/backend-plugin-api/src/services/definitions/AuthService.ts index 000ce8bbb1..dce5e9be3b 100644 --- a/packages/backend-plugin-api/src/services/definitions/AuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/AuthService.ts @@ -18,15 +18,29 @@ import { PermissionAttributes } from '@backstage/plugin-permission-common'; import { JsonObject } from '@backstage/types'; /** + * Represents a user principal (for example when a user Backstage token issued + * by the auth backend was given to a request). + * + * @remarks + * + * Additional information about the user can be fetched using the + * {@link UserInfoService}. + * * @public */ export type BackstageUserPrincipal = { type: 'user'; + /** + * The entity ref of the user entity that this principal represents. + */ userEntityRef: string; }; /** + * Represents a principal that is not authenticated (for example when no token + * at all was given to a request). + * * @public */ export type BackstageNonePrincipal = { @@ -34,13 +48,22 @@ export type BackstageNonePrincipal = { }; /** + * Represents a service principal (for example when an external access method + * token was given to a request, or the caller was a Backstage backend plugin). * @public */ export type BackstageServicePrincipal = { type: 'service'; - // Exact format TBD, possibly 'plugin:' or 'external:' - subject: string; + /** + * A string that represents the service. + * + * @remarks + * + * This string is only informational, has no well defined semantics, and + * should never be used to drive actual logic in code. + */ + subject: string; // Exact format TBD, possibly 'plugin:' or 'external:' /** * The access restrictions that apply to this principal. @@ -92,17 +115,38 @@ export type BackstagePrincipalAccessRestrictions = { }; /** + * An opaque representation of credentials, for example as passed in a + * request-response flow. + * * @public */ export type BackstageCredentials = { $$type: '@backstage/BackstageCredentials'; + /** + * If the credentials have a limited lifetime, this is the time at which they + * expire and may no longer be accepted by a receiver. + */ expiresAt?: Date; + /** + * The principal (originator) of the request. + * + * @remarks + * + * This is semantically the originator of a request chain, and may or may not + * represent the immediate caller of your service. For example, in + * on-behalf-of scenarios, the immediate caller may be an intermediary backend + * service, but the principal may still be a user that was the original + * caller. + */ principal: TPrincipal; }; /** + * The types of principal that can be represented in a + * {@link BackstageCredentials} object. + * * @public */ export type BackstagePrincipalTypes = { @@ -113,36 +157,95 @@ export type BackstagePrincipalTypes = { }; /** + * Provides token authentication and credentials management. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/auth | service documentation} for more details. + * * @public */ export interface AuthService { + /** + * Verifies a token and returns the associated credentials. + */ authenticate( token: string, options?: { + /** + * If set to true, allow limited access tokens (such as cookies). + * + * If this flag is not set, or is set to false, calls with limited access + * tokens will lead to a {@link @backstage/errors#NotAllowedError} being + * thrown. + */ allowLimitedAccess?: boolean; }, ): Promise; + /** + * Checks if the given credentials are of the given type, and narrows the + * TypeScript type accordingly if there's a match. + */ isPrincipal( credentials: BackstageCredentials, type: TType, ): credentials is BackstageCredentials; + /** + * Create a credentials object that represents an unauthenticated caller. + */ getNoneCredentials(): Promise>; + /** + * Create a credentials object that represents the current service itself. + */ getOwnServiceCredentials(): Promise< BackstageCredentials >; + /** + * Issue a token that can be used for authenticating calls towards other + * backend plugins. + * + * @remarks + * + * This method should be called before each request. Do not cold on to the + * issued token and reuse it for future calls. + */ getPluginRequestToken(options: { + /** + * The credentials of the originator of the request. + * + * @remarks + * + * This is most commonly the result of + * {@link AuthService.getOwnServiceCredentials} when the current service is + * the originator, or the output of {@link HttpAuthService.credentials} when + * performing requests on behalf of an incoming request identity. + */ onBehalfOf: BackstageCredentials; + /** + * The ID of the plugin that the request is being made to. + */ targetPluginId: string; }): Promise<{ token: string }>; + /** + * Issue a limited user token that can be used e.g. in cookie flows. + */ getLimitedUserToken( + /** + * The credentials that this token should represent. Must be a user + * principal. Commonly the output of {@link HttpAuthService.credentials} is + * used as the input. + */ credentials: BackstageCredentials, ): Promise<{ token: string; expiresAt: Date }>; + /** + * Retrieve the public keys that have been used to sign tokens that were + * issued by this service. This list is periodically pruned from keys that are + * significantly past their expiry. + */ listPublicServiceKeys(): Promise<{ keys: JsonObject[]; }>; diff --git a/packages/backend-plugin-api/src/services/definitions/CacheService.ts b/packages/backend-plugin-api/src/services/definitions/CacheService.ts index ccf88823b0..3b13292a58 100644 --- a/packages/backend-plugin-api/src/services/definitions/CacheService.ts +++ b/packages/backend-plugin-api/src/services/definitions/CacheService.ts @@ -47,6 +47,8 @@ export type CacheServiceOptions = { * A pre-configured, storage agnostic cache service suitable for use by * Backstage plugins. * + * See the {@link https://backstage.io/docs/backend-system/core-services/cache | service documentation} for more details. + * * @public */ export interface CacheService { diff --git a/packages/backend-plugin-api/src/services/definitions/DatabaseService.ts b/packages/backend-plugin-api/src/services/definitions/DatabaseService.ts index 20b7b3b5dc..c7f0e1ccf1 100644 --- a/packages/backend-plugin-api/src/services/definitions/DatabaseService.ts +++ b/packages/backend-plugin-api/src/services/definitions/DatabaseService.ts @@ -17,7 +17,9 @@ import { Knex } from 'knex'; /** - * The DatabaseService manages access to databases that Plugins get. + * Manages access to databases that plugins get. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/database | service documentation} for more details. * * @public */ diff --git a/packages/backend-plugin-api/src/services/definitions/DiscoveryService.ts b/packages/backend-plugin-api/src/services/definitions/DiscoveryService.ts index c3f0820c28..af92a4abb5 100644 --- a/packages/backend-plugin-api/src/services/definitions/DiscoveryService.ts +++ b/packages/backend-plugin-api/src/services/definitions/DiscoveryService.ts @@ -18,6 +18,10 @@ * The DiscoveryService is used to provide a mechanism for backend * plugins to discover the endpoints for itself or other backend plugins. * + * See the {@link https://backstage.io/docs/backend-system/core-services/discovery | service documentation} for more details. + * + * @remarks + * * The purpose of the discovery API is to allow for many different deployment * setups and routing methods through a central configuration, instead * of letting each individual plugin manage that configuration. @@ -32,13 +36,15 @@ export interface DiscoveryService { /** * Returns the internal HTTP base URL for a given plugin, without a trailing slash. * + * @remarks + * * The returned URL should point to an internal endpoint for the plugin, with * the shortest route possible. The URL should be used for service-to-service * communication within a Backstage backend deployment. * - * This method must always be called just before making a request, as opposed to - * fetching the URL when constructing an API client. That is to ensure that more - * flexible routing patterns can be supported. + * This method must always be called just before making each request, as opposed to + * fetching the URL once when constructing an API client. That is to ensure that more + * flexible routing patterns can be supported where a different result might be returned each time. * * For example, asking for the URL for `catalog` may return something * like `http://10.1.2.3/api/catalog` @@ -48,6 +54,8 @@ export interface DiscoveryService { /** * Returns the external HTTP base backend URL for a given plugin, without a trailing slash. * + * @remarks + * * The returned URL should point to an external endpoint for the plugin, such that * it is reachable from the Backstage frontend and other external services. The returned * URL should be usable for example as a callback / webhook URL. diff --git a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts index 5d1a2090d4..718aa9b532 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpAuthService.ts @@ -17,19 +17,84 @@ import { Request, Response } from 'express'; import { BackstageCredentials, BackstagePrincipalTypes } from './AuthService'; -/** @public */ +/** + * Provides handling of credentials in an ongoing request. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/http-auth | service documentation} for more details. + * + * @public + */ export interface HttpAuthService { + /** + * Extracts the caller's credentials from a request. + * + * @remarks + * + * The credentials have been validated before returning, and are guaranteed to + * adhere to whatever policies have been added to this route using + * {@link HttpRouterService.addAuthPolicy}, if any. + * + * Further restrictions can be imposed by passing in options that control the + * allowed types of credential. + * + * You can narrow the returned credentials object to specific principal types + * using {@link AuthService.isPrincipal}. + */ credentials( + /** + * An Express request object. + */ req: Request, + /** + * Optional further restrictions. + */ options?: { + /** + * If specified, allow only principals of the given type(s). + * + * If the incoming credentials were not of a type that matched this + * restriction, a {@link @backstage/errors#NotAllowedError} is thrown. + * + * The default is to allow user and service principals. + */ allow?: Array; + /** + * If set to true, allow limited access tokens (such as cookies). + * + * If this flag is not set, or is set to false, calls with limited access + * tokens will lead to a {@link @backstage/errors#NotAllowedError} being + * thrown. + */ allowLimitedAccess?: boolean; }, ): Promise>; + /** + * Issues a limited access token as a cookie on the given response object. + * This is only possible for requests that were originally made with user + * credentials (such as a Backstage token). + * + * This must be called before sending any payload data. + */ issueUserCookie( + /** + * An Express response object. + */ res: Response, + /** + * Optional further settings. + */ options?: { + /** + * Issue the cookie for this specific credential. Must be a "user" type + * principal, or a "none" type (which leads to deleting the cookie). + * + * @remarks + * + * Normally you do not have to specify this option, because the default + * behavior is to extract the credentials from the request that + * corresponded to the given respnse. + */ credentials?: BackstageCredentials; }, ): Promise<{ expiresAt: Date }>; diff --git a/packages/backend-plugin-api/src/services/definitions/HttpRouterService.ts b/packages/backend-plugin-api/src/services/definitions/HttpRouterService.ts index 695b337754..92f7e950f9 100644 --- a/packages/backend-plugin-api/src/services/definitions/HttpRouterService.ts +++ b/packages/backend-plugin-api/src/services/definitions/HttpRouterService.ts @@ -16,17 +16,51 @@ import { Handler } from 'express'; -/** @public */ +/** + * Options for {@link HttpRouterService.addAuthPolicy}. + * + * @public + */ export interface HttpRouterServiceAuthPolicy { path: string; allow: 'unauthenticated' | 'user-cookie'; } /** + * Allows plugins to register HTTP routes. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/http-router | service documentation} for more details. + * * @public */ export interface HttpRouterService { + /** + * Registers an Express request handler under the plugin's base router. This + * typically makes its base path `/api/`. + */ use(handler: Handler): void; + /** + * Adds an auth policy to the router. This is used to allow unauthenticated or + * cookie based access to parts of a plugin's API. + * + * @remarks + * + * The paths given follow the same pattern as the routers given to the `use` + * method, that is, they are relative to the plugin's base URL, and can + * contain placeholders. + * + * @example + * + * ```ts + * http.addAuthPolicy({ + * path: '/static/:id', + * allow: 'user-cookie', + * }); + * ``` + * + * This allows limited access tokens via cookies on the + * `/api//static/*` paths, but not unauthenticated access. + */ addAuthPolicy(policy: HttpRouterServiceAuthPolicy): void; } diff --git a/packages/backend-plugin-api/src/services/definitions/IdentityService.ts b/packages/backend-plugin-api/src/services/definitions/IdentityService.ts index 330aaf6447..5e18e26585 100644 --- a/packages/backend-plugin-api/src/services/definitions/IdentityService.ts +++ b/packages/backend-plugin-api/src/services/definitions/IdentityService.ts @@ -16,5 +16,12 @@ import { IdentityApi } from '@backstage/plugin-auth-node'; -/** @public */ +/** + * This is the legacy service for identity handling in Backstage. Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/identity | service documentation} for more details. + * + * @public + * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. + */ export interface IdentityService extends IdentityApi {} diff --git a/packages/backend-plugin-api/src/services/definitions/LifecycleService.ts b/packages/backend-plugin-api/src/services/definitions/LifecycleService.ts index e0641e0457..62ccc54f82 100644 --- a/packages/backend-plugin-api/src/services/definitions/LifecycleService.ts +++ b/packages/backend-plugin-api/src/services/definitions/LifecycleService.ts @@ -47,6 +47,10 @@ export interface LifecycleServiceShutdownOptions { } /** + * Provides registration of plugin startup and shutdown lifecycle hooks. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/lifecycle | service documentation} for more details. + * * @public */ export interface LifecycleService { diff --git a/packages/backend-plugin-api/src/services/definitions/LoggerService.ts b/packages/backend-plugin-api/src/services/definitions/LoggerService.ts index 2e4edc60be..86831d4520 100644 --- a/packages/backend-plugin-api/src/services/definitions/LoggerService.ts +++ b/packages/backend-plugin-api/src/services/definitions/LoggerService.ts @@ -19,6 +19,8 @@ import { JsonObject } from '@backstage/types'; /** * A service that provides a logging facility. * + * See the {@link https://backstage.io/docs/backend-system/core-services/logger | service documentation} for more details. + * * @public */ export interface LoggerService { diff --git a/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts b/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts index 1db15ce5e5..c5046a988b 100644 --- a/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts +++ b/packages/backend-plugin-api/src/services/definitions/PermissionsService.ts @@ -37,13 +37,46 @@ export type PermissionsServiceRequestOptions = credentials: BackstageCredentials; }; -/** @public */ +/** + * Permission system integration for authorization of user/service actions. + * + * See the {@link https://backstage.io/docs/permissions/overview | permissions documentation} + * and the {@link https://backstage.io/docs/backend-system/core-services/permissions | service documentation} + * for more details. + * + * @public + */ export interface PermissionsService extends PermissionEvaluator { + /** + * Evaluates + * {@link @backstage/plugin-permission-common#Permission | Permissions} and + * returns definitive decisions. + * + * @remarks + * + * The returned array has the same number of items, in the same order, as the + * given requests. + */ authorize( requests: AuthorizePermissionRequest[], options?: PermissionsServiceRequestOptions, ): Promise; + /** + * Evaluates {@link @backstage/plugin-permission-common#ResourcePermission | ResourcePermissions} and returns both definitive and + * conditional decisions, depending on the configured + * {@link @backstage/plugin-permission-node#PermissionPolicy}. + * + * @remarks + * + * This method is useful when the + * caller needs more control over the processing of conditional decisions. For example, a plugin + * backend may want to use {@link @backstage/plugin-permission-common#PermissionCriteria | conditions} in a database query instead of + * evaluating each resource in memory. + * + * The returned array has the same number of items, in the same order, as the + * given requests. + */ authorizeConditional( requests: QueryPermissionRequest[], options?: PermissionsServiceRequestOptions, diff --git a/packages/backend-plugin-api/src/services/definitions/PluginMetadataService.ts b/packages/backend-plugin-api/src/services/definitions/PluginMetadataService.ts index 48328e4db9..4fc3c45fd7 100644 --- a/packages/backend-plugin-api/src/services/definitions/PluginMetadataService.ts +++ b/packages/backend-plugin-api/src/services/definitions/PluginMetadataService.ts @@ -15,8 +15,15 @@ */ /** + * Access metadata about the current plugin. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/plugin-metadata | service documentation} for more details. + * * @public */ export interface PluginMetadataService { + /** + * The ID of the current plugin. + */ getId(): string; } diff --git a/packages/backend-plugin-api/src/services/definitions/RootConfigService.ts b/packages/backend-plugin-api/src/services/definitions/RootConfigService.ts index 02343e4ee8..453a7cda37 100644 --- a/packages/backend-plugin-api/src/services/definitions/RootConfigService.ts +++ b/packages/backend-plugin-api/src/services/definitions/RootConfigService.ts @@ -17,6 +17,12 @@ import { Config } from '@backstage/config'; /** + * Provides access to static configuration. + * + * See the {@link https://backstage.io/docs/conf/ | configuration documentation} + * and the {@link https://backstage.io/docs/backend-system/core-services/root-config | service documentation} + * for more details. + * * @public */ export interface RootConfigService extends Config {} diff --git a/packages/backend-plugin-api/src/services/definitions/RootHttpRouterService.ts b/packages/backend-plugin-api/src/services/definitions/RootHttpRouterService.ts index e583e978fa..a1006b749b 100644 --- a/packages/backend-plugin-api/src/services/definitions/RootHttpRouterService.ts +++ b/packages/backend-plugin-api/src/services/definitions/RootHttpRouterService.ts @@ -17,6 +17,10 @@ import { Handler } from 'express'; /** + * HTTP route registration for root services. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/root-http-router | service documentation} for more details. + * * @public */ export interface RootHttpRouterService { diff --git a/packages/backend-plugin-api/src/services/definitions/RootLifecycleService.ts b/packages/backend-plugin-api/src/services/definitions/RootLifecycleService.ts index e0e09cb859..b962fa68ba 100644 --- a/packages/backend-plugin-api/src/services/definitions/RootLifecycleService.ts +++ b/packages/backend-plugin-api/src/services/definitions/RootLifecycleService.ts @@ -16,5 +16,11 @@ import { LifecycleService } from './LifecycleService'; -/** @public */ +/** + * Registration of backend startup and shutdown lifecycle hooks. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/root-lifecycle | service documentation} for more details. + * + * @public + */ export interface RootLifecycleService extends LifecycleService {} diff --git a/packages/backend-plugin-api/src/services/definitions/RootLoggerService.ts b/packages/backend-plugin-api/src/services/definitions/RootLoggerService.ts index ad318ef53f..3e5b98d7f6 100644 --- a/packages/backend-plugin-api/src/services/definitions/RootLoggerService.ts +++ b/packages/backend-plugin-api/src/services/definitions/RootLoggerService.ts @@ -16,5 +16,11 @@ import { LoggerService } from './LoggerService'; -/** @public */ +/** + * Root-level logging. + * + * Seethe {@link https://backstage.io/docs/backend-system/core-services/root-logger | service documentation} for more details. + * + * @public + */ export interface RootLoggerService extends LoggerService {} diff --git a/packages/backend-plugin-api/src/services/definitions/SchedulerService.ts b/packages/backend-plugin-api/src/services/definitions/SchedulerService.ts index ad0fc1cf3a..91edf27ad6 100644 --- a/packages/backend-plugin-api/src/services/definitions/SchedulerService.ts +++ b/packages/backend-plugin-api/src/services/definitions/SchedulerService.ts @@ -285,6 +285,8 @@ export interface SchedulerServiceTaskRunner { /** * Deals with the scheduling of distributed tasks, for a given plugin. * + * See the {@link https://backstage.io/docs/backend-system/core-services/scheduler | service documentation} for more details. + * * @public */ export interface SchedulerService { diff --git a/packages/backend-plugin-api/src/services/definitions/TokenManagerService.ts b/packages/backend-plugin-api/src/services/definitions/TokenManagerService.ts index c9d7edcaef..445b2983d3 100644 --- a/packages/backend-plugin-api/src/services/definitions/TokenManagerService.ts +++ b/packages/backend-plugin-api/src/services/definitions/TokenManagerService.ts @@ -15,9 +15,12 @@ */ /** - * Interface for creating and validating tokens. + * This is the legacy service for creating and validating tokens. Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/token-manager | service documentation} for more details. * * @public + * @deprecated Please migrate to the new `coreServices.auth`, `coreServices.httpAuth`, and `coreServices.userInfo` services as needed instead. */ export interface TokenManagerService { /** diff --git a/packages/backend-plugin-api/src/services/definitions/UrlReaderService.ts b/packages/backend-plugin-api/src/services/definitions/UrlReaderService.ts index 734dcd9902..8cb40ff202 100644 --- a/packages/backend-plugin-api/src/services/definitions/UrlReaderService.ts +++ b/packages/backend-plugin-api/src/services/definitions/UrlReaderService.ts @@ -19,6 +19,8 @@ import { Readable } from 'stream'; /** * A generic interface for fetching plain data from URLs. * + * See the {@link https://backstage.io/docs/backend-system/core-services/url-reader | service documentation} for more details. + * * @public */ export interface UrlReaderService { diff --git a/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts b/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts index 90f5306a58..438de79219 100644 --- a/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts +++ b/packages/backend-plugin-api/src/services/definitions/UserInfoService.ts @@ -16,13 +16,27 @@ import { BackstageCredentials } from './AuthService'; -/** @public */ +/** + * Represents user information that is available to the backend, based on some + * user credentials. + * + * @public + */ export interface BackstageUserInfo { userEntityRef: string; ownershipEntityRefs: string[]; } -/** @public */ +/** + * Authenticated user information retrieval. + * + * See the {@link https://backstage.io/docs/backend-system/core-services/user-info | service documentation} for more details. + * + * @public + */ export interface UserInfoService { + /** + * Retrieve user information based on the provided credentials. + */ getUserInfo(credentials: BackstageCredentials): Promise; }