backend-defaults: define token field on credentials as non-enumerable

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2024-10-11 11:44:36 +02:00
parent 6fa100e824
commit 321a994358
3 changed files with 104 additions and 18 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-defaults': patch
---
Sensitive internal fields on `BackstageCredentials` objects are now defined as read-only properties in order to minimize risk of leakage.
@@ -0,0 +1,67 @@
/*
* 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.
*/
import {
createCredentialsWithNonePrincipal,
createCredentialsWithServicePrincipal,
createCredentialsWithUserPrincipal,
} from './helpers';
describe('credentials', () => {
it('should be created', () => {
expect(createCredentialsWithServicePrincipal('my-service')).toEqual({
$$type: '@backstage/BackstageCredentials',
version: 'v1',
principal: {
type: 'service',
subject: 'my-service',
},
});
expect(
createCredentialsWithUserPrincipal('user:default/mock', 'my-token'),
).toEqual({
$$type: '@backstage/BackstageCredentials',
version: 'v1',
principal: {
type: 'user',
userEntityRef: 'user:default/mock',
},
});
expect(createCredentialsWithNonePrincipal()).toEqual({
$$type: '@backstage/BackstageCredentials',
version: 'v1',
principal: {
type: 'none',
},
});
});
it('should not include tokens when serialized', () => {
expect(
JSON.stringify(
createCredentialsWithServicePrincipal('my-service', 'my-token'),
),
).not.toMatch(/my-token/);
expect(
JSON.stringify(
createCredentialsWithUserPrincipal('user:default/mock', 'my-token'),
),
).not.toMatch(/my-token/);
});
});
@@ -28,16 +28,23 @@ export function createCredentialsWithServicePrincipal(
token?: string,
accessRestrictions?: BackstagePrincipalAccessRestrictions,
): InternalBackstageCredentials<BackstageServicePrincipal> {
return {
$$type: '@backstage/BackstageCredentials',
version: 'v1',
token,
principal: {
type: 'service',
subject: sub,
accessRestrictions,
return Object.defineProperty(
{
$$type: '@backstage/BackstageCredentials',
version: 'v1',
principal: {
type: 'service',
subject: sub,
accessRestrictions,
},
},
};
'token',
{
enumerable: false,
configurable: true,
value: token,
},
);
}
export function createCredentialsWithUserPrincipal(
@@ -45,16 +52,23 @@ export function createCredentialsWithUserPrincipal(
token: string,
expiresAt?: Date,
): InternalBackstageCredentials<BackstageUserPrincipal> {
return {
$$type: '@backstage/BackstageCredentials',
version: 'v1',
token,
expiresAt,
principal: {
type: 'user',
userEntityRef: sub,
return Object.defineProperty(
{
$$type: '@backstage/BackstageCredentials',
version: 'v1',
expiresAt,
principal: {
type: 'user',
userEntityRef: sub,
},
},
};
'token',
{
enumerable: false,
configurable: true,
value: token,
},
);
}
export function createCredentialsWithNonePrincipal(): InternalBackstageCredentials<BackstageNonePrincipal> {