backend-{plugin,app}-api: refactored auth APIs to use principals

Co-authored-by: Fredrik Adelöw <freben@gmail.com>
Co-authored-by: Carl-Erik Bergström <cbergstrom@spotify.com>
Co-authored-by: blam <ben@blam.sh>
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-02-10 09:53:37 +01:00
parent 6a685868ff
commit a19ef483f1
9 changed files with 296 additions and 170 deletions
@@ -17,9 +17,7 @@
/**
* @public
*/
export type BackstageUserCredentials = {
$$type: '@backstage/BackstageCredentials';
export type BackstageUserPrincipal = {
type: 'user';
userEntityRef: string;
@@ -28,27 +26,54 @@ export type BackstageUserCredentials = {
/**
* @public
*/
export type BackstageServiceCredentials = {
$$type: '@backstage/BackstageCredentials';
type: 'service';
subject: string;
export type BackstageNonePrincipal = {
type: 'none';
};
/**
* @public
*/
export type BackstageCredentials =
| BackstageUserCredentials
| BackstageServiceCredentials;
export type BackstageServicePrincipal = {
type: 'service';
// Exact format TBD, possibly 'plugin:<pluginId>' or 'external:<externalServiceId>'
subject: string;
// Not implemented in the first iteration, but this is how we might extend this in the future
permissions?: string[];
};
/**
* @public
*/
export type BackstageCredentials<TPrincipal = unknown> = {
$$type: '@backstage/BackstageCredentials';
principal: TPrincipal;
};
/**
* @public
*/
export type BackstagePrincipalTypes = {
user: BackstageUserPrincipal;
service: BackstageServicePrincipal;
};
/**
* @public
*/
export interface AuthService {
authenticate(token: string): Promise<BackstageCredentials>;
issueServiceToken(options?: {
isPrincipal<TType extends keyof BackstagePrincipalTypes>(
credentials: BackstageCredentials,
type: TType,
): credentials is BackstageCredentials<BackstagePrincipalTypes[TType]>;
// TODO: should the caller provide the target plugin ID?
// TODO: how can we make it very difficult to forget to forward credentials
issueToken(options: {
forward?: BackstageCredentials;
}): Promise<{ token: string }>;
}
@@ -16,36 +16,39 @@
import { Request, Response } from 'express';
import {
BackstageUserCredentials,
BackstageServiceCredentials,
BackstageCredentials,
BackstageServicePrincipal,
BackstageNonePrincipal,
BackstageUserPrincipal,
} from './AuthService';
/** @public */
export type BackstageUnauthorizedCredentials = {
$$type: '@backstage/BackstageCredentials';
type: 'unauthorized';
};
/** @public */
export type BackstageCredentialTypes = {
user: BackstageUserCredentials;
'user-cookie': BackstageUserCredentials;
service: BackstageServiceCredentials;
unauthorized: BackstageUnauthorizedCredentials;
export type BackstageHttpAccessToPrincipalTypesMapping = {
user: BackstageUserPrincipal;
'user-cookie': BackstageUserPrincipal;
service: BackstageServicePrincipal;
unauthenticated: BackstageNonePrincipal;
};
/** @public */
export interface HttpAuthService {
credentials<TAllowed extends keyof BackstageCredentialTypes>(
credentials<
TAllowed extends
| keyof BackstageHttpAccessToPrincipalTypesMapping
| undefined = undefined,
>(
req: Request,
options: {
options?: {
allow: Array<TAllowed>;
},
): Promise<BackstageCredentialTypes[TAllowed]>;
): Promise<
BackstageCredentials<
TAllowed extends keyof BackstageHttpAccessToPrincipalTypesMapping
? BackstageHttpAccessToPrincipalTypesMapping[TAllowed]
: unknown
>
>;
// TODO: Keep an eye on this, might not be needed
requestHeaders(options?: {
forward?: BackstageCredentials;
}): Promise<Record<string, string>>;
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { BackstageUserCredentials } from './AuthService';
import { BackstageCredentials } from './AuthService';
/** @public */
export interface BackstageUserInfo {
@@ -24,7 +24,5 @@ export interface BackstageUserInfo {
/** @public */
export interface UserInfoService {
getUserInfo(
credentials: BackstageUserCredentials,
): Promise<BackstageUserInfo>;
getUserInfo(credentials: BackstageCredentials): Promise<BackstageUserInfo>;
}
@@ -18,8 +18,10 @@ export { coreServices } from './coreServices';
export type {
AuthService,
BackstageCredentials,
BackstageServiceCredentials,
BackstageUserCredentials,
BackstageUserPrincipal,
BackstageServicePrincipal,
BackstagePrincipalTypes,
BackstageNonePrincipal,
} from './AuthService';
export type {
CacheService,
@@ -35,8 +37,7 @@ export type {
} from './HttpRouterService';
export type {
HttpAuthService,
BackstageCredentialTypes,
BackstageUnauthorizedCredentials,
BackstageHttpAccessToPrincipalTypesMapping,
} from './HttpAuthService';
export type {
LifecycleService,