From 81e012067856b60559aae2b30496f350d525d63e Mon Sep 17 00:00:00 2001 From: Patrik Oldsberg Date: Fri, 1 Mar 2024 14:07:55 +0100 Subject: [PATCH] backend-app-api: fix config secret redactions Signed-off-by: Patrik Oldsberg --- .changeset/large-candles-sniff.md | 5 ++ .../backend-app-api/src/config/config.test.ts | 74 +++++++++++++++++++ packages/backend-app-api/src/config/config.ts | 4 +- 3 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 .changeset/large-candles-sniff.md create mode 100644 packages/backend-app-api/src/config/config.test.ts diff --git a/.changeset/large-candles-sniff.md b/.changeset/large-candles-sniff.md new file mode 100644 index 0000000000..3b62d212ba --- /dev/null +++ b/.changeset/large-candles-sniff.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-app-api': patch +--- + +Fixed an issue where configuration schema for the purpose of redacting secrets from logs was not being read correctly. diff --git a/packages/backend-app-api/src/config/config.test.ts b/packages/backend-app-api/src/config/config.test.ts new file mode 100644 index 0000000000..8828c557e0 --- /dev/null +++ b/packages/backend-app-api/src/config/config.test.ts @@ -0,0 +1,74 @@ +/* + * Copyright 2020 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { loadConfigSchema } from '@backstage/config-loader'; +import { createConfigSecretEnumerator } from './config'; +import { mockServices } from '@backstage/backend-test-utils'; + +describe('createConfigSecretEnumerator', () => { + it('should enumerate secrets', async () => { + const logger = mockServices.logger.mock(); + + const enumerate = await createConfigSecretEnumerator({ + logger, + }); + const secrets = enumerate( + mockServices.rootConfig({ + data: { + backend: { auth: { keys: [{ secret: 'my-secret-password' }] } }, + }, + }), + ); + expect(Array.from(secrets)).toEqual(['my-secret-password']); + }, 20_000); // Bit higher timeout since we're loading all config schemas in the repo + + it('should enumerate secrets with explicit schema', async () => { + const logger = mockServices.logger.mock(); + + const enumerate = await createConfigSecretEnumerator({ + logger, + schema: await loadConfigSchema({ + serialized: { + schemas: [ + { + value: { + type: 'object', + properties: { + secret: { + visibility: 'secret', + type: 'string', + }, + }, + }, + path: '/mock', + }, + ], + backstageConfigSchemaVersion: 1, + }, + }), + }); + + const secrets = enumerate( + mockServices.rootConfig({ + data: { + secret: 'my-secret', + other: 'not-secret', + }, + }), + ); + expect(Array.from(secrets)).toEqual(['my-secret']); + }); +}); diff --git a/packages/backend-app-api/src/config/config.ts b/packages/backend-app-api/src/config/config.ts index 8f98c5597c..60d1e46e90 100644 --- a/packages/backend-app-api/src/config/config.ts +++ b/packages/backend-app-api/src/config/config.ts @@ -42,7 +42,7 @@ export async function createConfigSecretEnumerator(options: { const schema = options.schema ?? (await loadConfigSchema({ - dependencies: packages.map(p => p.packageJson.name).filter(() => false), + dependencies: packages.map(p => p.packageJson.name), })); return (config: Config) => { @@ -55,7 +55,7 @@ export async function createConfigSecretEnumerator(options: { ); const secrets = new Set(); JSON.parse( - JSON.stringify(secretsData), + JSON.stringify(secretsData.data), (_, v) => typeof v === 'string' && secrets.add(v), ); logger.info(