Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 168 additions & 0 deletions .github/workflows/publish.npm.storage.aws.kms.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
name: Publish AWS Storage to NPM
on:
workflow_dispatch:
inputs:
publish:
description: 'Publish to NPM (uncheck to build only)'
required: false
default: true
type: boolean

permissions:
contents: read

jobs:
generate-sbom:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Get the source code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '24'

- name: Install package dependencies
run: npm ci --omit=dev
working-directory: ./sdk/javascript/packages/aws

- name: Install Syft
run: |
echo "Installing Syft v1.32.0..."
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /tmp/bin v1.32.0
echo "/tmp/bin" >> "$GITHUB_PATH"

- name: Install Manifest CLI
run: |
echo "Installing Manifest CLI v0.31.0..."
curl -sSfL https://raw.githubusercontent.com/manifest-cyber/cli/main/install.sh | sh -s -- -b /tmp/bin v0.31.0

- name: Create Syft configuration
run: |
cat > syft-config.yaml << 'EOF'
select-catalogers:
- "-github-action-workflow-usage-cataloger"
- "-github-actions-usage-cataloger"
EOF

- name: Generate and upload SBOM
env:
MANIFEST_API_KEY: ${{ secrets.MANIFEST_TOKEN }}
run: |
JAVASCRIPT_SDK_DIR="./sdk/javascript"

# Get version from package.json
echo "Detecting AWS Storage version..."
if [ -f "${JAVASCRIPT_SDK_DIR}/packages/aws/package.json" ]; then
VERSION=$(grep -o '"version": "[^"]*"' "${JAVASCRIPT_SDK_DIR}/packages/aws/package.json" | cut -d'"' -f4)
echo "Detected version: ${VERSION}"
else
VERSION="1.0.0"
echo "Could not detect version, using default: ${VERSION}"
fi

echo "Generating SBOM with Manifest CLI..."
manifest sbom "${JAVASCRIPT_SDK_DIR}/packages/aws" \
--generator=syft \
--name=keeper-secrets-manager-javascript-storage-aws-kms \
--version="${VERSION}" \
--output=spdx-json \
--file=aws-storage-sbom.json \
--api-key="${MANIFEST_API_KEY}" \
--publish=true \
--asset-label=application,sbom-generated,nodejs,aws-storage \
--generator-config=syft-config.yaml

echo "SBOM generated and uploaded successfully: aws-storage-sbom.json"
echo "---------- SBOM Preview (first 20 lines) ----------"
head -n 20 aws-storage-sbom.json

- name: Upload SBOM artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: sbom-keeper-secrets-manager-javascript-storage-aws-kms-${{ github.run_number }}
path: aws-storage-sbom.json
retention-days: 10

build-npm:
needs: generate-sbom
runs-on: ubuntu-latest
permissions:
contents: read

defaults:
run:
working-directory: ./sdk/javascript/packages/aws

steps:
- name: Get the source code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '24'

- name: Install dependencies
run: npm install

- name: Run tests
run: npm test

- name: Build package
run: npm run build

- name: Upload NPM package
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
with:
name: npm-package-aws-kms-${{ github.run_number }}
path: |
${{ github.workspace }}/sdk/javascript/packages/aws/dist/
${{ github.workspace }}/sdk/javascript/packages/aws/package.json

publish-npm:
Comment thread Fixed
needs: build-npm
if: ${{ github.event.inputs.publish == 'true' }}
environment: prod
runs-on: ubuntu-latest
permissions:
contents: read

defaults:
run:
working-directory: ./sdk/javascript/packages/aws

steps:
- name: Get the source code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
persist-credentials: false

- name: Setup Node.js
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: '24'

- name: Install dependencies
run: npm ci

- name: Build package
run: npm run build

- name: Retrieve secrets from KSM
id: ksmsecrets
uses: Keeper-Security/ksm-action@560d170bea253481a48eae617f0493aab7436c28 # master
with:
keeper-secret-config: ${{ secrets.KSM_NPM_PUBLISHER_NPM_SDK_CONFIG }}
secrets: |
2LmZq2z682qhTKYUizehow/field/password > env:NPM_TOKEN

- name: Publish package
run: npm publish --ignore-scripts
Comment thread Fixed
38 changes: 38 additions & 0 deletions .github/workflows/test.javascript.storage.aws.kms.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Test JavaScript Storage - AWS KMS

on:
push:
branches:
- 'release/storage/javascript/aws-kms/**'
paths:
- 'sdk/javascript/packages/aws/**'
- '.github/workflows/test.javascript.storage.aws.kms.yml'
pull_request:
branches:
- 'release/storage/javascript/aws-kms/**'
paths:
- 'sdk/javascript/packages/aws/**'
workflow_dispatch:

jobs:
test:
runs-on: ubuntu-latest
defaults:
run:
working-directory: ./sdk/javascript/packages/aws
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Node.js 20.x
uses: actions/setup-node@v4
with:
node-version: '20.x'
cache: 'npm'
cache-dependency-path: sdk/javascript/packages/aws/package-lock.json

- name: Install dependencies
run: npm ci

- name: Run tests
run: npm test
Comment on lines +19 to +38

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium test

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 5 months ago

To resolve the issue, an explicit permissions block should be added to limit the permissions granted to the workflow's jobs. The least-privilege starting point is typically contents: read, which allows jobs to clone and read the repository content but does not permit write operations. This block can be added either at the root level of the workflow, applying to all jobs, or just to the specific job. Since the workflow contains only one job (test), either location is acceptable, but best practice is to place it at the root for future extensibility. The modification involves editing .github/workflows/test.javascript.storage.aws.kms.yml by inserting the following block after the name: and before the on: section:

permissions:
  contents: read

No new imports, methods, or definitions are required beyond adding this block.

Suggested changeset 1
.github/workflows/test.javascript.storage.aws.kms.yml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/test.javascript.storage.aws.kms.yml b/.github/workflows/test.javascript.storage.aws.kms.yml
--- a/.github/workflows/test.javascript.storage.aws.kms.yml
+++ b/.github/workflows/test.javascript.storage.aws.kms.yml
@@ -1,4 +1,6 @@
 name: Test JavaScript Storage - AWS KMS
+permissions:
+  contents: read
 
 on:
   push:
EOF
@@ -1,4 +1,6 @@
name: Test JavaScript Storage - AWS KMS
permissions:
contents: read

on:
push:
Copilot is powered by AI and may make mistakes. Always verify output.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ venv.bak/
# Don't add Config files
keeper.ini*
*config*.json
!tsconfig.json
!tsconfig.test.json
.secrets
ansible.cfg

Expand Down
26 changes: 26 additions & 0 deletions sdk/javascript/packages/aws/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json",
"sourceType": "module",
"ecmaVersion": "latest"
},
"plugins": [
"@typescript-eslint",
"prettier",
"jest"
],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:jest/recommended",
"plugin:jest/style",
"plugin:prettier/recommended"
],
"rules": {
"prettier/prettier": "error",
"no-console": "error"
},
"ignorePatterns": ["node_modules/", "dist/", "coverage/"]
}
1 change: 1 addition & 0 deletions sdk/javascript/packages/aws/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
yarn.lock
1 change: 1 addition & 0 deletions sdk/javascript/packages/aws/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
26 changes: 26 additions & 0 deletions sdk/javascript/packages/aws/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Changelog

All notable changes to the Keeper Secrets Manager JavaScript AWS KMS Storage will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.0]

### Added

- Initial release — `AWSKeyValueStorage` for encrypting KSM configuration files with AWS KMS
- Supports symmetric (SYMMETRIC_DEFAULT) and RSA asymmetric key types
- Authenticate with `AWSSessionConfig` (access key, secret, region) or environment-based credentials
- `changeKey(newKeyId)` method to rotate the KMS key without re-initializing storage
- `decryptConfig(autosave)` to export configuration back to plaintext for migration or backup
- Configurable log levels via `LoggerLogLevelOptions` (`trace`, `debug`, `info`, `warn`, `error`, `fatal`)
- Requires `@keeper-security/secrets-manager-core` v17.3.0

### Fixed

- KSM-846 - Fixed encryption and decryption errors being silently swallowed — invalid credentials, bad key IDs, and failed key rotation now throw as expected
- `encryptBuffer()` and `decryptBuffer()` in `utils.ts` now rethrow AWS KMS failures instead of returning empty values
- `saveConfig()` in `AwsKeyValueStore.ts` now rethrows errors instead of logging and continuing, making the full error propagation chain work end-to-end
- `saveString()`, `saveBytes()`, and `saveObject()` now propagate AWS KMS errors to the caller
- `changeKey()` rollback path (key and crypto client restoration) is now reachable when encryption with the new key fails
Loading
Loading