import { NoydbSealer, RecipientSealer } from '@noy-db/hub/at'; import { KMSClient } from '@aws-sdk/client-kms'; /** * **@noy-db/at-aws-kms** — AWS KMS sealing key provider for noy-db * managed-secret mode. * * An `at-*` provider that seals and unseals the hub-generated random * secret via AWS KMS Encrypt / Decrypt. Every seal and unseal is an * authenticated KMS API call, giving you a CloudTrail-backed access log of * every time a user's vault is opened — no additional instrumentation * required. * * ## When to use * * - Compliance regimes requiring auditable key access logs (FedRAMP, HIPAA * with managed-encryption requirements, SOC 2 Type II). * - Workloads already running on AWS where a KMS key costs less than * engineering an equivalent audit trail. * - Any case where you want automatic CMK rotation without rotating your * app's sealing key material manually. * * ## Setup * * ```bash * # 1. Create a KMS key (one-time, in your AWS console or CLI): * aws kms create-key --description "noy-db sealing key" * # Note the KeyId/ARN from the output. * * # 2. Grant the host's IAM role kms:Encrypt + kms:Decrypt on that key. * # Credentials are picked up automatically from the SDK's ambient chain * # (IAM role, ~/.aws/credentials, env vars — see AWS SDK docs). * ``` * * ```ts * // 3. In your app: * import { createNoydb } from '@noy-db/hub' * import { atAwsKms } from '@noy-db/at-aws-kms' * import { shamirRecoveryProvider } from '@noy-db/on-shamir' * * const db = await createNoydb({ * store, * user: 'alice', * secretMode: 'managed', * sealingKey: atAwsKms({ keyId: 'arn:aws:kms:us-east-1:123:key/abc' }), * shamirRecovery: shamirRecoveryProvider(), * }) * ``` * * @packageDocumentation */ /** Options for {@link atAwsKms}. */ interface AtAwsKmsOptions { /** KMS key id or ARN (e.g. `arn:aws:kms:us-east-1:123:key/abc`). */ readonly keyId: string; /** Optional pre-built client (DI for tests). Default `new KMSClient({})` (ambient creds). */ readonly client?: Pick; } /** * Build a {@link NoydbSealer} backed by AWS KMS Encrypt / Decrypt. * * Credentials are resolved by the SDK's ambient chain — IAM instance roles, * environment variables, or `~/.aws/credentials`. Never pass raw credentials * in the options; inject a pre-configured client for non-default auth instead. * * @throws Error when KMS returns no ciphertext or no plaintext (guards * against unexpected SDK-response shapes). * Any KMS API error (AccessDenied, InvalidKeyUsage, etc.) propagates as-is. */ declare function atAwsKms(opts: AtAwsKmsOptions): NoydbSealer; /** Options for {@link awsKmsRecipientSealer}. */ interface AwsKmsRecipientSealerOptions { /** * KMS key id or ARN of an **asymmetric RSA** key with `KeyUsage: * ENCRYPT_DECRYPT` and `KeySpec` one of `RSA_2048` / `RSA_3072` / * `RSA_4096`. The private key never leaves KMS — unseal runs `Decrypt`. */ readonly keyId: string; /** Optional region passed to the default `KMSClient` when no `client` is given. */ readonly region?: string; /** Optional pre-built client (DI for tests). Default `new KMSClient({ region? })` (ambient creds). */ readonly client?: Pick; } /** * A {@link RecipientSealer} (plus `unseal`) backed by an **asymmetric RSA** * AWS KMS key. Lets an `at-aws-kms` host act as a recipient target: a grantor * obtains the host's published {@link RecipientHint} (the KMS public key as * PEM) and seals bytes to it *locally* — no KMS call on the seal path. The * host unseals via KMS `Decrypt` with `EncryptionAlgorithm: * RSAES_OAEP_SHA_256`; the private key never leaves KMS. * * Wire format is the canonical recipient-target TLV * ({@link sealRsaOaepTlv}/{@link parseRsaOaepTlv}) shared with hub's * `MemoryRecipientSealer`, so a blob sealed by either side unseals on the * other. WebCrypto RSA-OAEP/SHA-256 and KMS `RSAES_OAEP_SHA_256` are * wire-compatible (RSAES-OAEP, SHA-256, MGF1-SHA256, empty label). KMS * asymmetric keys do not support an encryption context, so none is used. * * Separate from {@link atAwsKms} (symmetric self-seal for the * managed secret) — this factory targets an asymmetric key. * * @throws Error from `publishRecipientHint` when the key is not an RSA * `ENCRYPT_DECRYPT` key, or `GetPublicKey` returns no public key. * @throws Error from `sealForRecipient` on an unsupported `hint.v`/`hint.alg`. * Any KMS API error (AccessDenied, etc.) propagates as-is. */ declare function awsKmsRecipientSealer(opts: AwsKmsRecipientSealerOptions): RecipientSealer & { unseal(sealed: Uint8Array): Promise; }; export { type AtAwsKmsOptions, type AwsKmsRecipientSealerOptions, atAwsKms, awsKmsRecipientSealer };