Package Exports
- updating-secrets
- updating-secrets/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (updating-secrets) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
updating-secrets
Automatically update secrets on an interval with support for seamless secret rotation.
Reference docs: https://electrovir.github.io/updating-secrets
Install
npm i updating-secretsUsage
Basics
First, define your set of secrets:
import {defineSecrets, rotatableSecretShape} from 'updating-secrets';
// example collection of secrets
export const mySecrets = defineSecrets({
databaseCredentials: {
description: 'All credentials and access information needed for accessing the database.',
whereToFind:
'These values are automatically generated by RDS and only stored in AWS Secrets Manager.',
adapterConfig: {
aws: {
rootOf: 'prod/DatabaseCredentials',
},
},
shape: {
password: '',
dbname: '',
port: -1,
host: '',
username: '',
},
},
stripeSecret: {
description: 'Keys for accessing and authenticating with Stripe.',
whereToFind: 'Navigate to Developers > API keys > Standard keys > Secret key.',
adapterConfig: {
aws: {
keyIn: 'prod/BackendSecrets',
},
},
},
adminPassword: {
description:
'Password required by the admin to access sensitive information on the website.',
whereToFind: 'This is randomly generated and stored in AWS Secrets Manager.',
adapterConfig: {
aws: {
keyIn: 'prod/BackendSecrets',
},
},
shape: rotatableSecretShape,
},
});Second, choose your secrets adapters:
- https://www.npmjs.com/package/@updating-secrets/infisical-adapter
- https://www.npmjs.com/package/@updating-secrets/aws-secrets-manager-adapter
SecretsJsonFileAdapter: loads secrets from a JSON file.StaticSecretsAdapter: allows you to define all secrets values in-place.
Or create your own:
import {BaseSecretsAdapter, type ProcessedSecretDefinitions} from 'updating-secrets';
export class MyCustomSecretsAdapter extends BaseSecretsAdapter {
constructor() {
super('MyCustomSecretsAdapter');
}
public override loadSecrets(secrets: Readonly<ProcessedSecretDefinitions>) {
// load secrets here
return {};
}
}Lastly, create an instance of UpdatingSecrets (with createUpdatingSecrets):
import {SecretsManager} from '@aws-sdk/client-secrets-manager';
import {AwsSecretsManagerAdapter, createUpdatingSecrets} from '@updating-secrets/aws-secrets-manager-adapter';
import {mySecrets} from './define-secrets.example.js';
const updatingSecrets = await createUpdatingSecrets(mySecrets, [
new AwsSecretsManagerAdapter(
new SecretsManager({
region: 'us-east-1',
}),
),
]);Rotatable secrets
To create a seamlessly rotatable secret, use rotatableSecretShape in the secret definition's shape property, either as the root (shape: rotatableSecretShape) or as a sub-property (secret: {id: '', secret: rotatableSecretShape}).
Use this secret in the following way:
- always store the secret with JSON like
{current: 'latest-value'} - when rotation is needed, move the old value to the
legacyproperty:{current: 'new-value', legacy: 'old-value'} - in your code, always access the secret
.current - if you need to compare a third party's usage of the secret (for example, if the secret is an API key that you distributed to them), use
UpdatingSecrets.compareRotatableSecret()to allow both the current and the legacy secret to pass comparisons:// assuming the `apiKey` secret is defined with `shape: rotatableSecretShape` updatingSecrets.compareRotatableSecret(request.headers.apiKey, updatingSecrets.get.apiKey);