1import type * as kms from "@distilled.cloud/aws/kms";
2import type * as Effect from "effect/Effect";
3import * as Binding from "../../Binding.ts";
4import type { AliasName } from "./Alias.ts";
5import type { Key } from "./Key.ts";
6
7export interface GenerateDataKeyRequest extends Omit<
8 kms.GenerateDataKeyRequest,
9 "KeyId"
10> {}
11
12/**
13 * Runtime binding for `kms:GenerateDataKey`.
14 *
15 * Bind this operation to a KMS {@link Key} (or the `alias/...` name of a
16 * pre-existing key) inside a function runtime to get a callable that
17 * automatically injects the `KeyId`. Returns a fresh symmetric data key as
18 * both plaintext (for immediate envelope encryption outside KMS) and a
19 * ciphertext blob encrypted under the bound key (for storage alongside the
20 * data). Decrypt the stored blob later with the `Decrypt` binding.
21 *
22 * The `Plaintext` data key in the response is wrapped in `Redacted` so it
23 * never leaks into logs — unwrap with `Redacted.value(...)` at the point of
24 * use and discard it as soon as the envelope operation is done.
25 *
26 * ### Envelope Encryption
27 * **Example:** Generate a Data Key
28 * ```typescript
29 * import * as Redacted from "effect/Redacted";
30 *
31 * const generateDataKey = yield* AWS.KMS.GenerateDataKey(key);
32 *
33 * const response = yield* generateDataKey({ KeySpec: "AES_256" });
34 * const dataKey = Redacted.isRedacted(response.Plaintext)
35 * ? Redacted.value(response.Plaintext)
36 * : response.Plaintext; // 32-byte Uint8Array — use, then discard
37 * const stored = response.CiphertextBlob; // persist next to the data
38 * ```
39 *
40 * **Example:** Recover the Data Key Later
41 * ```typescript
42 * const decrypt = yield* AWS.KMS.Decrypt(key);
43 * const recovered = yield* decrypt({ CiphertextBlob: stored });
44 * ```
45 *
46 * ### Pre-Existing Keys
47 * **Example:** Bind by Alias Name
48 * ```typescript
49 * const generateDataKey = yield* AWS.KMS.GenerateDataKey("alias/app-key");
50 * ```
51 *
52 * ### Wiring
53 * **Example:** Provide the Implementation on a Lambda Function
54 * ```typescript
55 * // Envelope encryption pairs GenerateDataKey with Decrypt — provide
56 * // both HTTP layers on the Function's init Effect.
57 * export default EnvelopeFunction.make(
58 * { main: import.meta.url, functionUrl: true },
59 * Effect.gen(function* () {
60 * const key = yield* AWS.KMS.Key("DataKey");
61 * const generateDataKey = yield* AWS.KMS.GenerateDataKey(key);
62 * const decrypt = yield* AWS.KMS.Decrypt(key);
63 * // ... generate a data key, encrypt locally, store the CiphertextBlob
64 * return { fetch: handler };
65 * }).pipe(
66 * Effect.provide(
67 * Layer.mergeAll(AWS.KMS.GenerateDataKeyHttp, AWS.KMS.DecryptHttp),
68 * ),
69 * ),
70 * );
71 * ```
72 *
73 * @binding
74 */
75export interface GenerateDataKey extends Binding.Service<
76 GenerateDataKey,
77 "AWS.KMS.GenerateDataKey",
78 (
79 key: Key | AliasName,
80 ) => Effect.Effect<
81 (
82 request: GenerateDataKeyRequest,
83 ) => Effect.Effect<kms.GenerateDataKeyResponse, kms.GenerateDataKeyError>
84 >
85> {}
86
87export const GenerateDataKey = Binding.Service<GenerateDataKey>(
88 "AWS.KMS.GenerateDataKey",
89);