1import type { Input } from "../../Input.ts";
2import type { PolicyStatement } from "../IAM/Policy.ts";
3import type { AliasName } from "./Alias.ts";
4import type { Key } from "./Key.ts";
5
6/**
7 * The target of a KMS cryptographic binding: either a {@link Key} resource
8 * declared in the stack, or the alias name (`alias/...`) of a pre-existing
9 * key that is managed outside the stack.
10 *
11 * When an alias name is given, the runtime request identifies the key by that
12 * alias and the IAM policy is scoped with the `kms:RequestAlias` condition
13 * key, so the role can only use keys through that exact alias.
14 *
15 * @internal shared scaffolding for the KMS crypto bindings — not exported
16 * from the service index.
17 */
18export type KeyLike = Key | AliasName;
19
20/**
21 * Build the least-privilege IAM policy statement for a KMS crypto operation
22 * against a {@link KeyLike} target.
23 *
24 * - `Key` resource → `Resource` is the exact key ARN.
25 * - alias name → `Resource: "*"` constrained by the `kms:RequestAlias`
26 * condition, AWS's documented pattern for alias-scoped access. The runtime
27 * caller must (and does) address the key by that alias.
28 *
29 * @internal
30 */
31export const keyPolicyStatement = (
32 action: `kms:${string}` | readonly `kms:${string}`[],
33 key: KeyLike,
34): Input<PolicyStatement> =>
35 typeof key === "string"
36 ? {
37 Effect: "Allow",
38 Action: typeof action === "string" ? [action] : [...action],
39 Resource: ["*"],
40 Condition: { StringEquals: { "kms:RequestAlias": key } },
41 }
42 : {
43 Effect: "Allow",
44 Action: typeof action === "string" ? [action] : [...action],
45 Resource: [key.keyArn],
46 };
47
48/** Stable human-readable label for tracing spans. @internal */
49export const keyLabel = (key: KeyLike): string =>
50 typeof key === "string" ? key : key.LogicalId;