move backend config schemas to where they belong
Signed-off-by: Fredrik Adelöw <freben@gmail.com>
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
---
|
||||
'@backstage/backend-defaults': patch
|
||||
'@backstage/backend-app-api': patch
|
||||
'@backstage/backend-common': patch
|
||||
'@backstage/backend-plugin-api': patch
|
||||
---
|
||||
|
||||
Updates to the config schema to match reality
|
||||
Vendored
+7
-292
@@ -16,297 +16,12 @@
|
||||
|
||||
export interface Config {
|
||||
backend?: {
|
||||
auth?: {
|
||||
/**
|
||||
* This disables the otherwise default auth policy, which requires all
|
||||
* requests to be authenticated with either user or service credentials.
|
||||
*
|
||||
* Disabling this check means that the backend will no longer block
|
||||
* unauthenticated requests, but instead allow them to pass through to
|
||||
* plugins.
|
||||
*
|
||||
* If permissions are enabled, unauthenticated requests will be treated
|
||||
* exactly as such, leaving it to the permission policy to determine what
|
||||
* permissions should be allowed for an unauthenticated identity. Note
|
||||
* that this will also apply to service-to-service calls between plugins
|
||||
* unless you configure credentials for service calls.
|
||||
*/
|
||||
dangerouslyDisableDefaultAuthPolicy?: boolean;
|
||||
|
||||
/** Controls how to store keys for plugin-to-plugin auth */
|
||||
pluginKeyStore?:
|
||||
| { type: 'database' }
|
||||
| {
|
||||
type: 'static';
|
||||
static: {
|
||||
/**
|
||||
* Must be declared at least once and the first one will be used for signing.
|
||||
*/
|
||||
keys: Array<{
|
||||
/**
|
||||
* Path to the public key file in the SPKI format. Should be an absolute path.
|
||||
*/
|
||||
publicKeyFile: string;
|
||||
/**
|
||||
* Path to the matching private key file in the PKCS#8 format. Should be an absolute path.
|
||||
*
|
||||
* The first array entry must specify a private key file, the rest must not.
|
||||
*/
|
||||
privateKeyFile?: string;
|
||||
/**
|
||||
* ID to uniquely identify this key within the JWK set.
|
||||
*/
|
||||
keyId: string;
|
||||
/**
|
||||
* JWS "alg" (Algorithm) Header Parameter value. Defaults to ES256.
|
||||
* Must match the algorithm used to generate the keys in the provided files
|
||||
*/
|
||||
algorithm?: string;
|
||||
}>;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Configures methods of external access, ie ways for callers outside of
|
||||
* the Backstage ecosystem to get authorized for access to APIs that do
|
||||
* not permit unauthorized access.
|
||||
*/
|
||||
externalAccess?: Array<
|
||||
| {
|
||||
/**
|
||||
* This is the legacy service-to-service access method, where a set
|
||||
* of static keys were shared among plugins and used for symmetric
|
||||
* signing and verification. These correspond to the old
|
||||
* `backend.auth.keys` set and retain their behavior for backwards
|
||||
* compatibility. Please migrate to other access methods when
|
||||
* possible.
|
||||
*
|
||||
* Callers generate JWT tokens with the following payload:
|
||||
*
|
||||
* ```json
|
||||
* {
|
||||
* "sub": "backstage-plugin",
|
||||
* "exp": <epoch seconds one hour in the future>
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* And sign them with HS256, using the base64 decoded secret. The
|
||||
* tokens are then passed along with requests in the Authorization
|
||||
* header:
|
||||
*
|
||||
* ```
|
||||
* Authorization: Bearer eyJhbGciOiJIUzI...
|
||||
* ```
|
||||
*/
|
||||
type: 'legacy';
|
||||
options: {
|
||||
/**
|
||||
* Any set of base64 encoded random bytes to be used as both the
|
||||
* signing and verification key. Should be sufficiently long so as
|
||||
* not to be easy to guess by brute force.
|
||||
*
|
||||
* Can be generated eg using
|
||||
*
|
||||
* ```sh
|
||||
* node -p 'require("crypto").randomBytes(24).toString("base64")'
|
||||
* ```
|
||||
*
|
||||
* @visibility secret
|
||||
*/
|
||||
secret: string;
|
||||
|
||||
/**
|
||||
* Sets the subject of the principal, when matching this token.
|
||||
* Useful for debugging and tracking purposes.
|
||||
*/
|
||||
subject: string;
|
||||
};
|
||||
/**
|
||||
* Restricts what types of access that are permitted for this access
|
||||
* method. If no access restrictions are given, it'll have unlimited
|
||||
* access. This access restriction applies for the framework level;
|
||||
* individual plugins may have their own access control mechanisms
|
||||
* on top of this.
|
||||
*/
|
||||
accessRestrictions?: Array<{
|
||||
/**
|
||||
* Permit access to make requests to this plugin.
|
||||
*
|
||||
* Can be further refined by setting additional fields below.
|
||||
*/
|
||||
plugin: string;
|
||||
/**
|
||||
* If given, this method is limited to only performing actions
|
||||
* with these named permissions in this plugin.
|
||||
*
|
||||
* Note that this only applies where permissions checks are
|
||||
* enabled in the first place. Endpoints that are not protected by
|
||||
* the permissions system at all, are not affected by this
|
||||
* setting.
|
||||
*/
|
||||
permission?: string | Array<string>;
|
||||
/**
|
||||
* If given, this method is limited to only performing actions
|
||||
* whose permissions have these attributes.
|
||||
*
|
||||
* Note that this only applies where permissions checks are
|
||||
* enabled in the first place. Endpoints that are not protected by
|
||||
* the permissions system at all, are not affected by this
|
||||
* setting.
|
||||
*/
|
||||
permissionAttribute?: {
|
||||
/**
|
||||
* One of more of 'create', 'read', 'update', or 'delete'.
|
||||
*/
|
||||
action?: string | Array<string>;
|
||||
};
|
||||
}>;
|
||||
}
|
||||
| {
|
||||
/**
|
||||
* This access method consists of random static tokens that can be
|
||||
* handed out to callers.
|
||||
*
|
||||
* The tokens are then passed along verbatim with requests in the
|
||||
* Authorization header:
|
||||
*
|
||||
* ```
|
||||
* Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW
|
||||
* ```
|
||||
*/
|
||||
type: 'static';
|
||||
options: {
|
||||
/**
|
||||
* A raw token that can be any string, but for security reasons
|
||||
* should be sufficiently long so as not to be easy to guess by
|
||||
* brute force.
|
||||
*
|
||||
* Can be generated eg using
|
||||
*
|
||||
* ```sh
|
||||
* node -p 'require("crypto").randomBytes(24).toString("base64")'
|
||||
* ```
|
||||
*
|
||||
* Since the tokens can be any string, you are free to add
|
||||
* additional identifying data to them if you like. For example,
|
||||
* adding a `freben-local-dev-` prefix for debugging purposes to a
|
||||
* token that you know will be handed out for use as a personal
|
||||
* access token during development.
|
||||
*
|
||||
* @visibility secret
|
||||
*/
|
||||
token: string;
|
||||
|
||||
/**
|
||||
* Sets the subject of the principal, when matching this token.
|
||||
* Useful for debugging and tracking purposes.
|
||||
*/
|
||||
subject: string;
|
||||
};
|
||||
/**
|
||||
* Restricts what types of access that are permitted for this access
|
||||
* method. If no access restrictions are given, it'll have unlimited
|
||||
* access. This access restriction applies for the framework level;
|
||||
* individual plugins may have their own access control mechanisms
|
||||
* on top of this.
|
||||
*/
|
||||
accessRestrictions?: Array<{
|
||||
/**
|
||||
* Permit access to make requests to this plugin.
|
||||
*
|
||||
* Can be further refined by setting additional fields below.
|
||||
*/
|
||||
plugin: string;
|
||||
/**
|
||||
* If given, this method is limited to only performing actions
|
||||
* with these named permissions in this plugin.
|
||||
*
|
||||
* Note that this only applies where permissions checks are
|
||||
* enabled in the first place. Endpoints that are not protected by
|
||||
* the permissions system at all, are not affected by this
|
||||
* setting.
|
||||
*/
|
||||
permission?: string | Array<string>;
|
||||
/**
|
||||
* If given, this method is limited to only performing actions
|
||||
* whose permissions have these attributes.
|
||||
*
|
||||
* Note that this only applies where permissions checks are
|
||||
* enabled in the first place. Endpoints that are not protected by
|
||||
* the permissions system at all, are not affected by this
|
||||
* setting.
|
||||
*/
|
||||
permissionAttribute?: {
|
||||
/**
|
||||
* One of more of 'create', 'read', 'update', or 'delete'.
|
||||
*/
|
||||
action?: string | Array<string>;
|
||||
};
|
||||
}>;
|
||||
}
|
||||
| {
|
||||
/**
|
||||
* This access method consists of a JWKS endpoint that can be used to
|
||||
* verify JWT tokens.
|
||||
*
|
||||
* Callers generate JWT tokens via 3rd party tooling
|
||||
* and pass them in the Authorization header:
|
||||
*
|
||||
* ```
|
||||
* Authorization: Bearer eZv5o+fW3KnR3kVabMW4ZcDNLPl8nmMW
|
||||
* ```
|
||||
*/
|
||||
type: 'jwks';
|
||||
options: {
|
||||
/**
|
||||
* The full URL of the JWKS endpoint.
|
||||
*/
|
||||
url: string;
|
||||
/**
|
||||
* Sets the algorithm(s) that should be used to verify the JWT tokens.
|
||||
* The passed JWTs must have been signed using one of the listed algorithms.
|
||||
*/
|
||||
algorithm?: string | string[];
|
||||
/**
|
||||
* Sets the issuer(s) that should be used to verify the JWT tokens.
|
||||
* Passed JWTs must have an `iss` claim which matches one of the specified issuers.
|
||||
*/
|
||||
issuer?: string | string[];
|
||||
/**
|
||||
* Sets the audience(s) that should be used to verify the JWT tokens.
|
||||
* The passed JWTs must have an "aud" claim that matches one of the audiences specified,
|
||||
* or have no audience specified.
|
||||
*/
|
||||
audience?: string | string[];
|
||||
/**
|
||||
* Sets an optional subject prefix. Passes the subject to called plugins.
|
||||
* Useful for debugging and tracking purposes.
|
||||
*/
|
||||
subjectPrefix?: string;
|
||||
};
|
||||
}
|
||||
>;
|
||||
};
|
||||
packages?: 'all' | { include?: string[]; exclude?: string[] };
|
||||
};
|
||||
|
||||
/** Discovery options. */
|
||||
discovery?: {
|
||||
/**
|
||||
* Endpoints
|
||||
*
|
||||
* A list of target baseUrls and the associated plugins.
|
||||
*/
|
||||
endpoints: {
|
||||
/**
|
||||
* The target baseUrl to use for the plugin
|
||||
*
|
||||
* Can be either a string or an object with internal and external keys.
|
||||
* Targets with `{{pluginId}}` or `{{ pluginId }} in the url will be replaced with the pluginId.
|
||||
*/
|
||||
target: string | { internal: string; external: string };
|
||||
/** Array of plugins which use the target baseUrl. */
|
||||
plugins: string[];
|
||||
}[];
|
||||
/** Used by the feature discovery service */
|
||||
packages?:
|
||||
| 'all'
|
||||
| {
|
||||
include?: string[];
|
||||
exclude?: string[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Vendored
+13
-10
@@ -210,6 +210,9 @@ export interface Config {
|
||||
defaultTtl?: number | HumanDuration;
|
||||
};
|
||||
|
||||
/**
|
||||
* Properties returned upon CORS requests to the backend, including the app-backend.
|
||||
*/
|
||||
cors?: {
|
||||
origin?: string | string[];
|
||||
methods?: string | string[];
|
||||
@@ -221,6 +224,16 @@ export interface Config {
|
||||
optionsSuccessStatus?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Content Security Policy options.
|
||||
*
|
||||
* The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The
|
||||
* values are on the format that the helmet library expects them, as an
|
||||
* array of strings. There is also the special value false, which means to
|
||||
* remove the default value that Backstage puts in place for that policy.
|
||||
*/
|
||||
csp?: { [policyId: string]: string[] | false };
|
||||
|
||||
/**
|
||||
* Configuration related to URL reading, used for example for reading catalog info
|
||||
* files, scaffolder templates, and techdocs content.
|
||||
@@ -248,15 +261,5 @@ export interface Config {
|
||||
paths?: string[];
|
||||
}>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Content Security Policy options.
|
||||
*
|
||||
* The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The
|
||||
* values are on the format that the helmet library expects them, as an
|
||||
* array of strings. There is also the special value false, which means to
|
||||
* remove the default value that Backstage puts in place for that policy.
|
||||
*/
|
||||
csp?: { [policyId: string]: string[] | false };
|
||||
};
|
||||
}
|
||||
|
||||
+217
@@ -14,8 +14,51 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { HumanDuration } from '@backstage/types';
|
||||
|
||||
export interface Config {
|
||||
app: {
|
||||
baseUrl: string; // defined in core, but repeated here without doc
|
||||
};
|
||||
|
||||
backend?: {
|
||||
/**
|
||||
* The full base URL of the backend, as seen from the browser's point of
|
||||
* view as it makes calls to the backend.
|
||||
*/
|
||||
baseUrl: string;
|
||||
|
||||
/** Address that the backend should listen to. */
|
||||
listen?:
|
||||
| string
|
||||
| {
|
||||
/** Address of the interface that the backend should bind to. */
|
||||
host?: string;
|
||||
/** Port that the backend should listen to. */
|
||||
port?: string | number;
|
||||
};
|
||||
|
||||
/**
|
||||
* HTTPS configuration for the backend. If omitted the backend will serve HTTP.
|
||||
*
|
||||
* Setting this to `true` will cause self-signed certificates to be generated, which
|
||||
* can be useful for local development or other non-production scenarios.
|
||||
*/
|
||||
https?:
|
||||
| true
|
||||
| {
|
||||
/** Certificate configuration */
|
||||
certificate?: {
|
||||
/** PEM encoded certificate. Use $file to load in a file */
|
||||
cert: string;
|
||||
/**
|
||||
* PEM encoded certificate key. Use $file to load in a file.
|
||||
* @visibility secret
|
||||
*/
|
||||
key: string;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Options used by the default auth, httpAuth and userInfo services.
|
||||
*/
|
||||
@@ -353,4 +396,178 @@ export interface Config {
|
||||
plugins: string[];
|
||||
}>;
|
||||
};
|
||||
|
||||
/** Database connection configuration, select base database type using the `client` field */
|
||||
database: {
|
||||
/** Default database client to use */
|
||||
client: 'better-sqlite3' | 'sqlite3' | 'pg';
|
||||
/**
|
||||
* Base database connection string, or object with individual connection properties
|
||||
* @visibility secret
|
||||
*/
|
||||
connection:
|
||||
| string
|
||||
| {
|
||||
/**
|
||||
* Password that belongs to the client User
|
||||
* @visibility secret
|
||||
*/
|
||||
password?: string;
|
||||
/**
|
||||
* Other connection settings
|
||||
*/
|
||||
[key: string]: unknown;
|
||||
};
|
||||
/** Database name prefix override */
|
||||
prefix?: string;
|
||||
/**
|
||||
* Whether to ensure the given database exists by creating it if it does not.
|
||||
* Defaults to true if unspecified.
|
||||
*/
|
||||
ensureExists?: boolean;
|
||||
/**
|
||||
* Whether to ensure the given database schema exists by creating it if it does not.
|
||||
* Defaults to false if unspecified.
|
||||
*
|
||||
* NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema
|
||||
*/
|
||||
ensureSchemaExists?: boolean;
|
||||
/**
|
||||
* How plugins databases are managed/divided in the provided database instance.
|
||||
*
|
||||
* `database` -> Plugins are each given their own database to manage their schemas/tables.
|
||||
*
|
||||
* `schema` -> Plugins will be given their own schema (in the specified/default database)
|
||||
* to manage their tables.
|
||||
*
|
||||
* NOTE: Currently only supported by the `pg` client.
|
||||
*
|
||||
* @default database
|
||||
*/
|
||||
pluginDivisionMode?: 'database' | 'schema';
|
||||
/** Configures the ownership of newly created schemas in pg databases. */
|
||||
role?: string;
|
||||
/**
|
||||
* Arbitrary config object to pass to knex when initializing
|
||||
* (https://knexjs.org/#Installation-client). Most notable is the debug
|
||||
* and asyncStackTraces booleans
|
||||
*/
|
||||
knexConfig?: object;
|
||||
/** Plugin specific database configuration and client override */
|
||||
plugin?: {
|
||||
[pluginId: string]: {
|
||||
/** Database client override */
|
||||
client?: 'better-sqlite3' | 'sqlite3' | 'pg';
|
||||
/**
|
||||
* Database connection string or Knex object override
|
||||
* @visibility secret
|
||||
*/
|
||||
connection?: string | object;
|
||||
/**
|
||||
* Whether to ensure the given database exists by creating it if it does not.
|
||||
* Defaults to base config if unspecified.
|
||||
*/
|
||||
ensureExists?: boolean;
|
||||
/**
|
||||
* Whether to ensure the given database schema exists by creating it if it does not.
|
||||
* Defaults to false if unspecified.
|
||||
*
|
||||
* NOTE: Currently only supported by the `pg` client when pluginDivisionMode: schema
|
||||
*/
|
||||
ensureSchemaExists?: boolean;
|
||||
/**
|
||||
* Arbitrary config object to pass to knex when initializing
|
||||
* (https://knexjs.org/#Installation-client). Most notable is the
|
||||
* debug and asyncStackTraces booleans.
|
||||
*
|
||||
* This is merged recursively into the base knexConfig
|
||||
*/
|
||||
knexConfig?: object;
|
||||
/** Configures the ownership of newly created schemas in pg databases. */
|
||||
role?: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
/** Cache connection configuration, select cache type using the `store` field */
|
||||
cache?:
|
||||
| {
|
||||
store: 'memory';
|
||||
/** An optional default TTL (in milliseconds). */
|
||||
defaultTtl?: number | HumanDuration;
|
||||
}
|
||||
| {
|
||||
store: 'redis';
|
||||
/**
|
||||
* A redis connection string in the form `redis://user:pass@host:port`.
|
||||
* @visibility secret
|
||||
*/
|
||||
connection: string;
|
||||
/** An optional default TTL (in milliseconds). */
|
||||
defaultTtl?: number | HumanDuration;
|
||||
/**
|
||||
* Whether or not [useRedisSets](https://github.com/jaredwray/keyv/tree/main/packages/redis#useredissets) should be configured to this redis cache.
|
||||
* Defaults to true if unspecified.
|
||||
*/
|
||||
useRedisSets?: boolean;
|
||||
}
|
||||
| {
|
||||
store: 'memcache';
|
||||
/**
|
||||
* A memcache connection string in the form `user:pass@host:port`.
|
||||
* @visibility secret
|
||||
*/
|
||||
connection: string;
|
||||
/** An optional default TTL (in milliseconds). */
|
||||
defaultTtl?: number | HumanDuration;
|
||||
};
|
||||
|
||||
cors?: {
|
||||
origin?: string | string[];
|
||||
methods?: string | string[];
|
||||
allowedHeaders?: string | string[];
|
||||
exposedHeaders?: string | string[];
|
||||
credentials?: boolean;
|
||||
maxAge?: number;
|
||||
preflightContinue?: boolean;
|
||||
optionsSuccessStatus?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Content Security Policy options.
|
||||
*
|
||||
* The keys are the plain policy ID, e.g. "upgrade-insecure-requests". The
|
||||
* values are on the format that the helmet library expects them, as an
|
||||
* array of strings. There is also the special value false, which means to
|
||||
* remove the default value that Backstage puts in place for that policy.
|
||||
*/
|
||||
csp?: { [policyId: string]: string[] | false };
|
||||
|
||||
/**
|
||||
* Configuration related to URL reading, used for example for reading catalog info
|
||||
* files, scaffolder templates, and techdocs content.
|
||||
*/
|
||||
reading?: {
|
||||
/**
|
||||
* A list of targets to allow outgoing requests to. Users will be able to make
|
||||
* requests on behalf of the backend to the targets that are allowed by this list.
|
||||
*/
|
||||
allow?: Array<{
|
||||
/**
|
||||
* A host to allow outgoing requests to, being either a full host or
|
||||
* a subdomain wildcard pattern with a leading `*`. For example `example.com`
|
||||
* and `*.example.com` are valid values, `prod.*.example.com` is not.
|
||||
* The host may also contain a port, for example `example.com:8080`.
|
||||
*/
|
||||
host: string;
|
||||
|
||||
/**
|
||||
* An optional list of paths. In case they are present only targets matching
|
||||
* any of them will are allowed. You can use trailing slashes to make sure only
|
||||
* subdirectories are allowed, for example `/mydir/` will allow targets with
|
||||
* paths like `/mydir/a` but will block paths like `/mydir2`.
|
||||
*/
|
||||
paths?: string[];
|
||||
}>;
|
||||
};
|
||||
}
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2024 The Backstage Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
export interface Config {
|
||||
backend?: {
|
||||
/**
|
||||
* An absolute path to a directory that can be used as a working dir, for
|
||||
* example as scratch space for large operations.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* Note that this must be an absolute path.
|
||||
*
|
||||
* If not set, the operating system's designated temporary directory is
|
||||
* commonly used, but that is implementation defined per plugin.
|
||||
*
|
||||
* Plugins are encouraged to heed this config setting if present, to allow
|
||||
* deployment in severely locked-down or limited environments.
|
||||
*/
|
||||
workingDirectory?: string;
|
||||
};
|
||||
}
|
||||
@@ -40,7 +40,8 @@
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
"dist",
|
||||
"config.d.ts"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "backstage-cli package build",
|
||||
@@ -67,5 +68,6 @@
|
||||
"devDependencies": {
|
||||
"@backstage/backend-test-utils": "workspace:^",
|
||||
"@backstage/cli": "workspace:^"
|
||||
}
|
||||
},
|
||||
"configSchema": "config.d.ts"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user