npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@workit-poa/hedera-kms-wallet

v0.2.0

Published

AWS KMS-backed Hedera wallet provisioning and signing utilities.

Readme

@workit-poa/hedera-kms-wallet

AWS KMS-backed Hedera wallet utilities for secure key management, account provisioning, transaction signing, and key rotation.

This package is designed for backend services that want to:

  • keep private keys non-exportable inside AWS KMS,
  • use secp256k1 signatures for Hedera transactions,
  • enforce explicit key ownership and least-privilege IAM boundaries,
  • support audited provisioning and controlled key rotation.

Table of Contents

What This Package Solves

Hedera transactions need signatures from account keys. This library lets you:

  • generate and store secp256k1 keys in AWS KMS (ECC_SECG_P256K1, SIGN_VERIFY),
  • derive Hedera-compatible public keys from KMS public key material,
  • sign Hedera transaction bytes without exporting private keys,
  • provision new Hedera accounts tied to KMS keys,
  • rotate account keys with explicit dual-signature account updates.

Features

  • KMS key management for user wallets:
    • create user-tagged keys with aliases,
    • validate key type and enabled state,
    • assert key ownership via required tags (app, userId).
  • Hedera signing and transaction helpers:
    • convert KMS DER ECDSA signatures into Hedera raw 64-byte (r||s) signatures,
    • submit topic message and tinybar transfer transactions.
  • Account lifecycle:
    • provision Hedera account from existing or newly-created KMS key,
    • rotate account key by co-signing with current and replacement keys.
  • Security and operations:
    • enforced least-privilege key policy bindings for key creation,
    • structured audit hook for provisioning/key/signing events.

Requirements

  • Node.js >=18
  • AWS account with KMS permissions for your runtime/admin roles
  • Hedera operator account (OPERATOR_ID + OPERATOR_KEY or HEDERA_OPERATOR_*)
  • Package manager: pnpm (repo standard), npm, or yarn

Requirement Coverage Matrix

This section maps project requirements to implementation and documentation artifacts.

1) Secure key management solution with compliance and auditability

  • Key lifecycle is implemented in kmsKeyManager and walletProvisioning.
  • Least-privilege key policy generation is enforced using policyBindings.
  • Structured audit events are emitted via auditLogger for key and signing operations.
  • CloudTrail verification guidance is documented in Audit and Compliance Logging.

Code references:

2) Use AWS KMS for secure key generation, storage, and rotation

  • Key generation: createUserKmsKey() creates ECC_SECG_P256K1 + SIGN_VERIFY keys.
  • Key storage/security: private keys are KMS-managed and never exported.
  • Key rotation: rotateHederaAccountKmsKey() performs managed replacement + Hedera account key update.
  • Automatic in-place rotation limits for asymmetric keys are documented with mitigation workflow.

Code references:

3) Submit a transaction on Hedera

  • Transaction helpers:
    • submitTopicMessageWithKmsSignature()
    • submitTinybarTransferWithKmsSignature()
  • End-to-end demo transaction flow is implemented in:
    • examples/hedera-kms-wallet-demo/src/kms-hedera-demo.ts

Code references:

4) Implement proper access controls and audit logging

  • Access control:
    • buildLeastPrivilegeKeyPolicy()
    • kmsAccessPolicyGuidance()
    • ownership enforcement with assertKmsKeyOwnershipForUser()
  • Audit:
    • structured auditLogger hook across key/sign/provision/rotation operations
    • CloudTrail event and field guidance documented

Code references:

5) Demonstrate secure transaction signing without exposing private keys

  • createKmsHederaSigner() uses KMS Sign API with digest mode.
  • Private keys remain in KMS; only signature/public key material is handled by application code.
  • DER ECDSA signatures are canonicalized into Hedera raw 64-byte format.

Code references:

6) Working prototype + documentation for architecture, security controls, and Hedera integration

  • Working prototype:
    • standalone demo app in examples/hedera-kms-wallet-demo
    • integrated app prototype in apps/web auth flow (NextAuth + OTP/OAuth + managed wallet provisioning)
    • runnable command for standalone flow: pnpm demo:kms-hedera
  • Documentation:
    • architecture and trust boundaries
    • IAM and key policy guidance
    • audit/compliance logging
    • integration and usage examples for Hedera transactions

Code and doc references:

Screenshot placeholder: Compliance checklist screenshot showing each requirement mapped to a README section and source file.

Installation

From npm

pnpm add @workit-poa/hedera-kms-wallet

or:

npm install @workit-poa/hedera-kms-wallet

In This Monorepo

Install workspace dependencies from repository root:

pnpm install

Architecture and Trust Boundaries

Components

  • Your backend calls this package for provisioning/signing operations.
  • AWS KMS stores and signs with non-exportable private keys.
  • Hedera SDK freezes, signs, submits, and resolves transaction receipts.
  • Hedera testnet/mainnet receives signed transactions.

Identity mapping

userId -> kmsKeyId/kmsKeyArn -> hederaAccountId (+ public key fingerprint)

Trust boundaries

  • Private key material never leaves KMS.
  • Runtime role is scoped to signing + metadata reads.
  • Key creation is guarded by explicit policy bindings.
  • Existing/replacement keys are tag-validated before use.

Screenshot placeholder: Architecture diagram showing backend -> AWS KMS -> Hedera network, with private key boundary around KMS.

Configuration

Copy .env.example and fill values for your environment.

Core environment variables

| Variable | Required | Description | | --- | --- | --- | | AWS_REGION | Yes | AWS region for KMS client | | OPERATOR_ID or HEDERA_OPERATOR_ID | Yes | Hedera operator account ID used to submit transactions | | OPERATOR_KEY or HEDERA_OPERATOR_KEY | Yes | Hedera operator private key | | HEDERA_NETWORK | No | testnet (default) or mainnet | | OPERATOR_KEY_TYPE | No | Force parsing mode: ecdsa, secp256k1, ed25519, or der | | HEDERA_KMS_ALIAS_PREFIX | No | Default alias prefix when creating keys (default: alias/workit-user) | | HEDERA_KMS_KEY_DESCRIPTION_PREFIX | No | Default key description prefix |

Variables required for secure key creation

These are required when your flow allows creating new KMS keys:

| Variable | Required when creating keys | Description | | --- | --- | --- | | AWS_ACCOUNT_ID | Yes | 12-digit AWS account ID | | KMS_KEY_ADMIN_PRINCIPAL_ARN | Yes | IAM principal ARN for key administration | | KMS_RUNTIME_SIGNER_PRINCIPAL_ARN | Yes | IAM principal ARN for runtime signing role |

Quick Start

import { KMSClient } from "@aws-sdk/client-kms";
import {
  createHederaClient,
  createKmsHederaSigner,
  submitTopicMessageWithKmsSignature
} from "@workit-poa/hedera-kms-wallet";

const kms = new KMSClient({ region: process.env.AWS_REGION });

const signer = await createKmsHederaSigner({
  kms,
  keyId: process.env.KMS_KEY_ID!
});

const client = createHederaClient({
  network: (process.env.HEDERA_NETWORK as "testnet" | "mainnet") || "testnet",
  operatorId: process.env.OPERATOR_ID!,
  operatorKey: process.env.OPERATOR_KEY!
});

const result = await submitTopicMessageWithKmsSignature({
  client,
  signer,
  payerAccountId: "0.0.12345",
  message: "hello from KMS signer"
});

console.log(result.transactionId, result.receiptStatus, result.mirrorLink);

kms.destroy();
client.close();

Usage Guide

1) Create a KMS-backed signer

import { KMSClient } from "@aws-sdk/client-kms";
import { createKmsHederaSigner } from "@workit-poa/hedera-kms-wallet";

const kms = new KMSClient({ region: "us-east-1" });

const signer = await createKmsHederaSigner({
  kms,
  keyId: "your-kms-key-id-or-arn",
  auditLogger: event => console.log(event)
});

2) Provision a Hedera account for a user

Runtime-safe mode (recommended): use pre-created key.

import { provisionHederaAccountForUser } from "@workit-poa/hedera-kms-wallet";

const provisioned = await provisionHederaAccountForUser({
  userId: "user-123",
  existingKeyId: "kms-key-id",
  awsRegion: process.env.AWS_REGION,
  operatorId: process.env.OPERATOR_ID,
  operatorKey: process.env.OPERATOR_KEY
});

Admin mode: allow secure key creation.

const provisioned = await provisionHederaAccountForUser({
  userId: "user-123",
  allowKeyCreation: true,
  initialHbar: 1,
  policyBindings: {
    accountId: process.env.AWS_ACCOUNT_ID!,
    keyAdminPrincipalArn: process.env.KMS_KEY_ADMIN_PRINCIPAL_ARN!,
    runtimeSignerPrincipalArn: process.env.KMS_RUNTIME_SIGNER_PRINCIPAL_ARN!
  }
});

3) Submit a tinybar transfer

import { submitTinybarTransferWithKmsSignature } from "@workit-poa/hedera-kms-wallet";

const transfer = await submitTinybarTransferWithKmsSignature({
  client,
  signer,
  fromAccountId: "0.0.123",
  toAccountId: "0.0.456",
  payerAccountId: "0.0.123",
  amountTinybar: 10
});

payerAccountId lets you charge network fees to the KMS-managed wallet account instead of the operator account.

4) Rotate Hedera account key

AWS asymmetric secp256k1 keys do not support in-place automatic rotation. Use managed replacement:

import { rotateHederaAccountKmsKey } from "@workit-poa/hedera-kms-wallet";

const rotated = await rotateHederaAccountKmsKey({
  userId: "user-123",
  accountId: "0.0.12345",
  currentKeyId: "current-kms-key-id",
  policyBindings: {
    accountId: process.env.AWS_ACCOUNT_ID!,
    keyAdminPrincipalArn: process.env.KMS_KEY_ADMIN_PRINCIPAL_ARN!,
    runtimeSignerPrincipalArn: process.env.KMS_RUNTIME_SIGNER_PRINCIPAL_ARN!
  }
});

Rotation flow:

  1. Create or reuse replacement key.
  2. Verify ownership tags for current + replacement keys.
  3. Build AccountUpdateTransaction with replacement public key.
  4. Co-sign with current and replacement keys.
  5. Submit transaction and persist new key details.

Screenshot placeholder: Console output showing successful key rotation with previous/new key fingerprints and transaction ID.

IAM and Key Policy Guidance

Use separate IAM responsibilities:

  • Key admin role: create/manage key lifecycle and aliases.
  • Runtime signer role: sign and read key metadata/public key.

Helpers:

  • buildLeastPrivilegeKeyPolicy(bindings)
  • kmsAccessPolicyGuidance(keyArn?, aliasArn?)

Enforced safeguards:

  • keyPolicy overrides are intentionally rejected.
  • allowUnsafeDefaultKeyPolicy bypass is intentionally rejected.
  • policyBindings is required whenever a new key is created.

Recommended runtime permissions:

  • kms:Sign
  • kms:GetPublicKey
  • kms:DescribeKey
  • kms:ListResourceTags

Scope runtime policies to explicit key ARNs whenever possible.

Audit and Compliance Logging

Pass auditLogger to emit structured events for:

  • CreateKey
  • CreateAlias
  • EnableKeyRotation
  • DescribeKey
  • GetPublicKey
  • ListResourceTags
  • Sign
  • ProvisionAccount
  • RotateAccountKey

CloudTrail should also record KMS API calls. Useful fields for audit evidence:

  • eventTime
  • eventName
  • userIdentity
  • requestParameters.keyId
  • sourceIPAddress
  • awsRegion

Screenshot placeholder: CloudTrail event history filtered to Sign and CreateKey for the relevant KMS key ARN.

Run the Demo

Demo source:

1) Configure demo env

cp examples/hedera-kms-wallet-demo/.env.example examples/hedera-kms-wallet-demo/.env

The demo loads:

  1. examples/hedera-kms-wallet-demo/.env
  2. repo root .env as fallback

2) Choose demo mode

  • DEMO_MODE=topic (default): creates topic + submits message
  • DEMO_MODE=transfer: submits tinybar transfer

Validation behavior:

  • DEMO_TRANSFER_TINYBAR must be a positive safe integer.
  • If provisioning a new account, HEDERA_NEW_ACCOUNT_INITIAL_HBAR must be > 0.
  • If creating a new KMS key, key policy bindings env vars are mandatory.

3) Run

From repo root:

pnpm demo:kms-hedera

or:

pnpm --filter @workit-poa/hedera-kms-wallet-demo demo:kms-hedera

Expected output includes:

  • key/account details,
  • transaction ID + receipt status,
  • Hashscan transaction link.

Note: the demo now sets payerAccountId to the managed wallet account, so transaction fees are charged to the KMS-backed wallet account (not the operator).

Screenshot placeholder: Terminal output from successful DEMO_MODE=topic run including topic ID and Hashscan URL. Screenshot placeholder: Hashscan transaction page confirming SUCCESS status.

Testing

Run package tests:

pnpm --filter @workit-poa/hedera-kms-wallet test

Run coverage:

pnpm --filter @workit-poa/hedera-kms-wallet test:coverage

What is covered:

  • key creation/validation/tag ownership checks,
  • DER-to-raw signature conversion and low-S normalization,
  • signer behavior and audit logging,
  • Hedera client and transaction helper behavior,
  • provisioning and rotation happy paths + validation failures.

Test env loading:

  • libs/hedera-kms-wallet/.env.test
  • libs/hedera-kms-wallet/.env.test.local (local override)

Current tests are mock-driven and do not require live AWS/Hedera credentials.

API Reference

All exports are re-exported from src/index.ts.

Key management (kmsKeyManager)

  • createUserKmsKey(params)
  • validateKmsSecp256k1SigningKey(kms, keyId, auditLogger?)
  • getPublicKeyBytes(kms, keyId, auditLogger?)
  • assertKmsKeyOwnershipForUser({ kms, keyId, userId, expectedAppTag?, auditLogger? })
  • buildLeastPrivilegeKeyPolicy(bindings)
  • kmsAccessPolicyGuidance(keyArn?, aliasArn?)

Signer (kmsSigner)

  • createKmsHederaSigner({ kms, keyId, auditLogger? })
  • Returns KmsHederaSigner:
    • keyId, keyArn
    • hederaPublicKey
    • compressedPublicKey, uncompressedPublicKey
    • sign(message)

Hedera helpers (hederaClient)

  • createHederaClient({ network?, operatorId, operatorKey })
  • createHederaClientFromEnv()
  • addKmsSignatureToFrozenTransaction(transaction, signer)
  • executeSignedTransaction(client, transaction)
  • submitTopicMessageWithKmsSignature({ client, signer, message, topicMemo?, payerAccountId?, network? })
  • submitTinybarTransferWithKmsSignature({ client, signer, fromAccountId, toAccountId, amountTinybar, payerAccountId?, network? })
  • mirrorLinkForTransaction(network, transactionId)
  • getWalletDetails(accountId, network?)

Wallet lifecycle (walletProvisioning)

  • provisionHederaAccountForUser(params)
  • rotateHederaAccountKmsKey(params)

Publishing

Pack/publish checks:

pnpm --filter @workit-poa/hedera-kms-wallet prepack
pnpm --filter @workit-poa/hedera-kms-wallet pack

prepack runs:

  1. clean
  2. lint
  3. test
  4. build

Published files are restricted to:

  • dist
  • README.md
  • .env.example
  • LICENSE

Troubleshooting

  • Missing AWS_REGION
    • Set AWS_REGION (or pass awsRegion explicitly where supported).
  • Missing operator credentials
    • Set OPERATOR_ID + OPERATOR_KEY (or HEDERA_OPERATOR_* alternatives).
  • existingKeyId is required unless allowKeyCreation=true
    • Runtime path expects pre-provisioned keys.
  • policyBindings is required when creating a new key
    • Provide AWS_ACCOUNT_ID, admin signer principal ARNs, and pass policyBindings.
  • KMS key ... must use KeySpec ECC_SECG_P256K1
    • Use secp256k1 signing keys only.
  • Signer must return a 64-byte (r||s) secp256k1 signature
    • Ensure signatures come from this package’s signer or equivalent canonical formatter.

References

  • Hedera account model: https://docs.hedera.com/hedera/core-concepts/accounts/account-properties
  • Hedera SDK and KMS signing guidance: https://docs.hedera.com/hedera/sdks-and-apis/sdks/client#how-to-sign-a-transaction-with-aws-kms
  • HIP-222 (ECDSA secp256k1 transaction signatures): https://hips.hedera.com/hip/hip-222
  • AWS KMS GetPublicKey: https://docs.aws.amazon.com/kms/latest/APIReference/API_GetPublicKey.html
  • AWS KMS + CloudTrail: https://docs.aws.amazon.com/kms/latest/developerguide/logging-using-cloudtrail.html

License

MIT