diff --git a/docs/auth/index.md b/docs/auth/index.md index 74433d157f..091c8b01a0 100644 --- a/docs/auth/index.md +++ b/docs/auth/index.md @@ -423,7 +423,7 @@ auth: provider: 'static' static: keys: - # Must be declared at least once and the first one will be used for signing */ + # Must be declared at least once and the first one will be used for signing - keyId: 'primary' publicKeyFile: /path/to/public.key privateKeyFile: /path/to/private.key diff --git a/plugins/auth-backend/package.json b/plugins/auth-backend/package.json index 32c3e86cf3..355c8eb554 100644 --- a/plugins/auth-backend/package.json +++ b/plugins/auth-backend/package.json @@ -88,7 +88,6 @@ "@backstage/backend-defaults": "workspace:^", "@backstage/backend-test-utils": "workspace:^", "@backstage/cli": "workspace:^", - "@backstage/core-app-api": "workspace:^", "@types/body-parser": "^1.19.0", "@types/cookie-parser": "^1.4.2", "@types/express-session": "^1.17.2", diff --git a/plugins/auth-backend/src/identity/KeyStores.ts b/plugins/auth-backend/src/identity/KeyStores.ts index eecf94edc5..7242530c57 100644 --- a/plugins/auth-backend/src/identity/KeyStores.ts +++ b/plugins/auth-backend/src/identity/KeyStores.ts @@ -76,12 +76,7 @@ export class KeyStores { } if (provider === 'static') { - const settings = ks?.getConfig(provider); - if (settings === undefined) { - throw new Error(`Missing configuration for static key store provider`); - } - - await StaticKeyStore.fromConfig(settings); + await StaticKeyStore.fromConfig(config); } throw new Error(`Unknown KeyStore provider: ${provider}`); diff --git a/plugins/auth-backend/src/identity/StaticKeyStore.test.ts b/plugins/auth-backend/src/identity/StaticKeyStore.test.ts index d56698189e..26ec9e4358 100644 --- a/plugins/auth-backend/src/identity/StaticKeyStore.test.ts +++ b/plugins/auth-backend/src/identity/StaticKeyStore.test.ts @@ -13,13 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -import { promises as fs } from 'fs'; import { StaticKeyStore } from './StaticKeyStore'; import { AnyJWK } from './types'; -import { ConfigReader } from '@backstage/core-app-api'; +import { ConfigReader } from '@backstage/config'; +import { createMockDirectory } from '@backstage/backend-test-utils'; -const publicKeyPath = '/mnt/public.pem'; -const privateKeyPath = '/mnt/private.pem'; const privateKey = ` -----BEGIN PRIVATE KEY----- MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgR8Ja2ppMEgOm1KeY @@ -35,37 +33,39 @@ ZoUEY72HTvjIP9xSbLOhWhMREk84T0q91/m3v3sWq5EzHIWw1zRHQisKZw== -----END PUBLIC KEY----- `.trim(); -const config = new ConfigReader({ - keys: [ - { - publicKeyFile: publicKeyPath, - privateKeyFile: privateKeyPath, - keyId: '1', - algorithm: 'ES256', - }, - { - publicKeyFile: publicKeyPath, - privateKeyFile: privateKeyPath, - keyId: '2', - algorithm: 'ES256', - }, - ], -}); - -jest.mock('fs/promises'); - describe('StaticKeyStore', () => { - beforeEach(() => { - jest.resetAllMocks(); - fs.readFile = jest.fn().mockImplementation(async (path: string, _: any) => { - if (path === publicKeyPath) { - return Promise.resolve(publicKey); - } - if (path === privateKeyPath) { - return Promise.resolve(privateKey); - } + let config: ConfigReader; + const sourceDir = createMockDirectory(); - throw new Error('Unexpected path'); + beforeAll(() => { + sourceDir.setContent({ + 'public.pem': publicKey, + 'private.pem': privateKey, + }); + + const publicKeyPath = sourceDir.resolve('public.pem'); + const privateKeyPath = sourceDir.resolve('private.pem'); + config = new ConfigReader({ + auth: { + keyStore: { + static: { + keys: [ + { + publicKeyFile: publicKeyPath, + privateKeyFile: privateKeyPath, + keyId: '1', + algorithm: 'ES256', + }, + { + publicKeyFile: publicKeyPath, + privateKeyFile: privateKeyPath, + keyId: '2', + algorithm: 'ES256', + }, + ], + }, + }, + }, }); }); diff --git a/plugins/auth-backend/src/identity/StaticKeyStore.ts b/plugins/auth-backend/src/identity/StaticKeyStore.ts index 11ec1585d2..13b9faf771 100644 --- a/plugins/auth-backend/src/identity/StaticKeyStore.ts +++ b/plugins/auth-backend/src/identity/StaticKeyStore.ts @@ -74,16 +74,18 @@ export class StaticKeyStore implements KeyStore { } public static async fromConfig(config: Config): Promise { - const keyConfigs = config.getConfigArray('keys').map(c => { - const staticKeyConfig: StaticKeyConfig = { - publicKeyFile: c.getString('publicKeyFile'), - privateKeyFile: c.getString('privateKeyFile'), - keyId: c.getString('keyId'), - algorithm: c.getOptionalString('algorithm') ?? DEFAULT_ALGORITHM, - }; + const keyConfigs = config + .getConfigArray('auth.keyStore.static.keys') + .map(c => { + const staticKeyConfig: StaticKeyConfig = { + publicKeyFile: c.getString('publicKeyFile'), + privateKeyFile: c.getString('privateKeyFile'), + keyId: c.getString('keyId'), + algorithm: c.getOptionalString('algorithm') ?? DEFAULT_ALGORITHM, + }; - return staticKeyConfig; - }); + return staticKeyConfig; + }); const keyPairs = await Promise.all( keyConfigs.map(async k => await this.loadKeyPair(k)), diff --git a/plugins/auth-backend/src/identity/StaticTokenIssuer.test.ts b/plugins/auth-backend/src/identity/StaticTokenIssuer.test.ts index df792f3e58..3e5d659d54 100644 --- a/plugins/auth-backend/src/identity/StaticTokenIssuer.test.ts +++ b/plugins/auth-backend/src/identity/StaticTokenIssuer.test.ts @@ -26,7 +26,6 @@ const entityRef = stringifyEntityRef({ name: 'name', }); -jest.mock('fs/promises'); describe('StaticTokenIssuer', () => { it('should issue valid tokens signed by the first listed key', async () => { const staticKeyStore = { diff --git a/plugins/auth-backend/src/identity/StaticTokenIssuer.ts b/plugins/auth-backend/src/identity/StaticTokenIssuer.ts index 77c13c7c33..41dc96e71c 100644 --- a/plugins/auth-backend/src/identity/StaticTokenIssuer.ts +++ b/plugins/auth-backend/src/identity/StaticTokenIssuer.ts @@ -35,7 +35,6 @@ export type Options = { issuer: string; /** Expiration time of the JWT in seconds */ sessionExpirationSeconds: number; - /** id to uniquely identify this key within the JWK set, defaults to '1' */ }; /** diff --git a/yarn.lock b/yarn.lock index c4aa235464..2533a51f32 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5006,7 +5006,6 @@ __metadata: "@backstage/catalog-model": "workspace:^" "@backstage/cli": "workspace:^" "@backstage/config": "workspace:^" - "@backstage/core-app-api": "workspace:^" "@backstage/errors": "workspace:^" "@backstage/plugin-auth-backend-module-gcp-iap-provider": "workspace:^" "@backstage/plugin-auth-backend-module-github-provider": "workspace:^"