@btravstack/keys

中文文档
0.58.0发布于 2026/11/08MITTypeScriptESM + CJS零依赖构建来源已验证近 30 天下载 4308

An EnvelopeKeys port for @btravstack/core: per-owner root keys wrapped by an AWS KMS key of that owner, unwrapped in memory and cached for a TTL, erased with one key deletion, and an HKDF helper giving each purpose its own key

原始使用文档
文档目录4 节
  1. A worked example
  2. Options
  3. What it decides, and what it does not
  4. License

@btravstack/keys

An EnvelopeKeys port for @btravstack/core: a root key per owner, in generations, wrapped by an AWS KMS key of that owner — unwrapped in memory and cached for a TTL, erased with one key deletion — and an HKDF helper giving each purpose its own key.

📖 Documentation · API Reference

pnpm add @btravstack/keys @btravstack/core @btravstack/config @btravstack/di unthrown
pnpm add @aws-sdk/client-kms # for @btravstack/keys/kms

Every dependency is a peer, and @aws-sdk/client-kms an optional one: only @btravstack/keys/kms imports it.

A worked example

A port that seals a tenant's payloads under a key of that tenant's own, and the composition that provides the keys:

import type { webcrypto } from "node:crypto";

import {
  EnvelopeKeys,
  deriveKey,
  type InvalidKeyPurpose,
  type KeyErased,
  type KeyGeneration,
  type KeysUnavailable,
} from "@btravstack/keys";
import { kmsKeys } from "@btravstack/keys/kms";

class PayloadKeys extends Port("ReadmePayloadKeys")<{
  readonly key: (
    generation: KeyGeneration,
  ) => AsyncResult<webcrypto.CryptoKey, KeyErased | KeysUnavailable | InvalidKeyPurpose>;
}> {}

export const payloadKeys = Provider(PayloadKeys)({
  inject: { keys: EnvelopeKeys },
  sync: ({ keys }) => ({
    key: (generation) =>
      keys.rootKey(generation).flatMap((root) =>
        deriveKey(root, { namespace: "payloads", purpose: "seal", version: 1 }, {
          algorithm: { name: "AES-GCM", length: 256 },
          usages: ["encrypt", "decrypt"],
        }),
      ),
  }),
});

export const Sealing = Module("ReadmeSealing")({
  imports: [kmsKeys()],
  provides: [payloadKeys],
  exports: [PayloadKeys],
});

Provisioning a generation, rotating, erasing a tenant in one call and sizing the cache are Keep envelope keys per owner.

Options

OptionWhereWhat it is
KEYS_KMS_REGIONenvironmentthe region of the owners' KMS keys — required
KEYS_KMS_ALIAS_PREFIXenvironmentan owner's KMS key is <prefix><owner> — required
KEYS_KMS_ENDPOINTenvironment, pinned by endpointan emulator or a VPC endpoint (default: AWS's own)
KEYS_CACHE_TTL_MSenvironment, pinned by cacheTtlMshow long an unwrapped root is kept (default five minutes)
KEYS_KMS_PENDING_WINDOW_DAYSenvironment, pinned by pendingWindowDaysthe days an erasure can be cancelled (default 30)
clockkmsKeys({ … })what the cache's TTL is measured against

The full table — defaults, semantics and the reasoning — lives on the reference page, which is this list's one detailed home.

What it decides, and what it does not

It decides that a generation is a KMS data key bound by the encryption context { owner, keyId }, so a blob presented for another owner or key id is refused rather than unwrapped; that a disabled, deleted, missing or refusing key is a typed KeyErased and anything else KMS says a typed KeysUnavailable; that erasing an owner is one scheduled key deletion; that every KMS request is reported to Observers; and that a derived key is HKDF-SHA-256 with info = <namespace>/<purpose>/v<version>.

It does not decide where the wrapped generations are kept, which one encrypts next, or how the owners' KMS keys are created: those are the application's and the platform's. The reasoning is in AGENTS.md.

License

MIT

版本与发布记录

@btravstack/keys 共发布 19 个版本,首次发布于 2026/10/21;过去 12 个月发布了 19 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.58.0latest2026/11/08今天
0.57.02026/11/071 天前
0.56.12026/11/062 天前
0.56.02026/11/062 天前
0.55.12026/11/035 天前
0.55.02026/11/035 天前

关于 @btravstack/keys 的常见问题

@btravstack/keys 是什么?

An EnvelopeKeys port for @btravstack/core: per-owner root keys wrapped by an AWS KMS key of that owner, unwrapped in memory and cached for a TTL, erased with one key deletion, and an HKDF helper giving each purpose its own key

如何安装 @btravstack/keys?

在项目目录运行 npm install @btravstack/keys,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:unthrown(^5.0.0)、@btravstack/di(^0.58.0)、@btravstack/core(^0.58.0)、@btravstack/config(^0.58.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@btravstack/keys 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@btravstack/keys 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@btravstack/keys 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=22。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@btravstack/keys 可以商用吗?

@btravstack/keys 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@btravstack/keys 的下载量有多少?

根据 npm 官方下载统计,@btravstack/keys 在 2026/10/09 – 2026/11/07 这 30 天内被下载 4,308 次,日均约 144 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@btravstack/keys 还在维护吗?

最新版本 0.58.0 发布于 2026/11/08(今天);至今共发布 19 个版本,其中过去 12 个月发布了 19 个;首次发布于 2026/10/21。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。