@kensio/yulin 1.21.7 → 1.21.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +22 -2
  2. package/dist/service/ses/command/authorize/sim-ses-authorizer.d.ts +9 -0
  3. package/dist/service/ses/command/authorize/sim-ses-authorizer.js +18 -2
  4. package/dist/service/ses/command/send/sim-ses-send-email.js +2 -1
  5. package/docs/README.md +7 -0
  6. package/docs/ai-skill/README.md +6 -1
  7. package/docs/sdk/README.md +15 -0
  8. package/docs/services/acm/README.md +24 -40
  9. package/docs/services/apigateway/README.md +52 -71
  10. package/docs/services/apigatewayv2/README.md +55 -74
  11. package/docs/services/athena/README.md +17 -26
  12. package/docs/services/backup/README.md +29 -39
  13. package/docs/services/bedrock/README.md +38 -52
  14. package/docs/services/cloudformation/README.md +43 -55
  15. package/docs/services/cloudfront/README.md +69 -95
  16. package/docs/services/cloudwatch/README.md +40 -54
  17. package/docs/services/cognito/README.md +30 -45
  18. package/docs/services/dynamodb/README.md +34 -51
  19. package/docs/services/ecr/README.md +36 -77
  20. package/docs/services/ecs/README.md +26 -46
  21. package/docs/services/elbv2/README.md +19 -29
  22. package/docs/services/eventbridge/README.md +14 -18
  23. package/docs/services/firehose/README.md +24 -32
  24. package/docs/services/glue/README.md +41 -78
  25. package/docs/services/iam/README.md +13 -15
  26. package/docs/services/kinesis/README.md +53 -93
  27. package/docs/services/kms/README.md +22 -32
  28. package/docs/services/lambda/README.md +53 -79
  29. package/docs/services/logs/README.md +41 -50
  30. package/docs/services/organizations/README.md +50 -85
  31. package/docs/services/personalize/README.md +28 -44
  32. package/docs/services/rekognition/README.md +26 -38
  33. package/docs/services/route53/README.md +17 -17
  34. package/docs/services/s3/README.md +47 -51
  35. package/docs/services/scheduler/README.md +41 -52
  36. package/docs/services/secretsmanager/README.md +27 -42
  37. package/docs/services/ses/README.md +24 -34
  38. package/docs/services/sns/README.md +18 -26
  39. package/docs/services/sqs/README.md +14 -14
  40. package/docs/services/ssm/README.md +13 -17
  41. package/docs/services/stepfunctions/README.md +18 -20
  42. package/docs/services/sts/README.md +32 -45
  43. package/docs/services/wafv2/README.md +12 -17
  44. package/docs/testing/README.md +228 -0
  45. package/docs/time/README.md +10 -0
  46. package/llms.txt +1 -0
  47. package/package.json +1 -1
@@ -1,11 +1,11 @@
1
1
  # Simulated IAM
2
2
 
3
- Yulin includes a simulated IAM service for tests and local development.
3
+ Yulin simulates IAM users, roles, policies and authorization decisions for tests and local
4
+ development. Other simulated services use IAM to authorize requests, simulated STS uses it to issue
5
+ temporary role sessions, and simulated CloudFormation can create IAM resources from templates.
4
6
 
5
- Sim IAM stores simulated Roles, Users and Policies, and evaluates allow/deny authorization decisions
6
- for them. Other simulated services use it to authorize their own actions, simulated STS uses it to
7
- issue temporary Role sessions, and sim CloudFormation can create IAM resources from templates. It can
8
- also be instantiated on its own as `SimIam` with isolated state.
7
+ Use IAM through `SimAws` when it should share state with other services. Use `SimIam` directly when
8
+ you need an isolated policy evaluator.
9
9
 
10
10
  ## Basic usage
11
11
 
@@ -70,9 +70,8 @@ denied for every action.
70
70
 
71
71
  ## Authorization decisions
72
72
 
73
- `authorize(...)` returns a decision object. A denied request comes back as a decision too, and a
74
- test can assert on exactly why it was allowed or denied. The decision models the common IAM
75
- evaluation rules:
73
+ `authorize(...)` returns an authorization decision without throwing when access is denied. Tests
74
+ can inspect why the request was allowed or denied. The evaluator applies these rules:
76
75
 
77
76
  - A matching explicit `Deny` statement in any evaluated policy wins
78
77
  - Otherwise, within one Account, a matching `Allow` in an identity policy or resource policy allows
@@ -81,12 +80,11 @@ evaluation rules:
81
80
  [Cross-Account requests](#cross-account-requests)
82
81
  - Otherwise the request is implicitly denied
83
82
 
84
- The decision exposes `value` (`"Allow"`, `"ExplicitDeny"`, or `"ImplicitDeny"`), the convenience
85
- flags `isAllowed`, `isDenied`, `isExplicitDeny`, and `isImplicitDeny`, the matching
86
- `allowStatements` and `explicitDenyStatements`, and the resolved `caller` for diagnostics. The
87
- matching Allows are also available per side as `identityAllowStatements` and
88
- `resourceAllowStatements`. A cross-Account denial is best read from those. Statements the simulator
89
- could not evaluate are reported by `unevaluatedStatements`, covered under
83
+ The decision's `value` is `"Allow"`, `"ExplicitDeny"` or `"ImplicitDeny"`. Convenience flags expose
84
+ the same result as `isAllowed`, `isDenied`, `isExplicitDeny` and `isImplicitDeny`. The decision also
85
+ contains the resolved `caller` and the matching allow and deny statements. For cross-account
86
+ requests, inspect `identityAllowStatements` and `resourceAllowStatements` to see which side did not
87
+ grant access. Unsupported statements appear in `unevaluatedStatements`, covered under
90
88
  [Statements left unevaluated](#statements-left-unevaluated).
91
89
 
92
90
  If the caller is omitted, authorization defaults to the simulation's own
@@ -1634,7 +1632,7 @@ stands apart from any wider `SimAws` environment. Other services instantiated st
1634
1632
  `new SimRoute53()`, fall back to allow-all authorization. Connect services through a shared `SimAws`
1635
1633
  instance when a test should exercise real IAM enforcement.
1636
1634
 
1637
- ## Available functionality
1635
+ ## Supported operations
1638
1636
 
1639
1637
  Sim IAM currently supports:
1640
1638
 
@@ -1,16 +1,14 @@
1
1
  # Simulated Kinesis Data Streams
2
2
 
3
- Yulin includes a simulated Kinesis Data Streams for tests and local development. It creates streams,
4
- places records on shards the way real Kinesis does, and hands them back through shard iterators. A
5
- test can put an event and assert that the consumer read it, without an AWS account and without
6
- waiting on a real stream.
3
+ Yulin simulates Kinesis streams, shards, records and shard iterators in memory. Use
4
+ `simAws.kinesis()` directly or intercept a `KinesisClient`.
7
5
 
8
6
  Kinesis specific types are imported from the `@kensio/yulin/kinesis` subpath.
9
7
 
10
8
  ## Putting a record and reading it back
11
9
 
12
- `simAws.kinesis()` gives the service for the default account and region. Records go on with
13
- `PutRecord`, and come off through a shard iterator, which is the walk every Kinesis consumer makes.
10
+ Create a stream, put a record, then read it through a shard iterator. This is the same sequence used
11
+ by an AWS SDK consumer.
14
12
 
15
13
  ```typescript sim-kinesis-put-and-read
16
14
  /**
@@ -59,17 +57,15 @@ const { Records } = await kinesis.getRecords(
59
57
  console.log(new TextDecoder().decode(Records[0]?.Data));
60
58
  ```
61
59
 
62
- A record keeps the bytes it was given. Whatever the producer encoded is what the consumer decodes.
60
+ Kinesis stores the bytes supplied by the producer. The consumer is responsible for decoding them.
63
61
 
64
62
  ## Shards and partition keys
65
63
 
66
- A stream is created with the shard count it asks for, and each shard owns a slice of a 128 bit hash
67
- key space. A record goes to the shard whose slice covers the MD5 hash of its partition key, which is
68
- the placement real Kinesis makes. Two records sharing a partition key therefore land on one shard,
69
- in the order they were put, and that per-key ordering is what most Kinesis consumers depend on.
64
+ A stream divides the 128-bit hash key space evenly across its shards. Kinesis uses the MD5 hash of
65
+ the partition key to select a shard. Records with the same partition key reach the same shard in
66
+ write order.
70
67
 
71
- Records under different partition keys can land anywhere. A consumer that has to see every record
72
- reads every shard.
68
+ Different partition keys may select different shards. Read every shard to consume the whole stream.
73
69
 
74
70
  ```typescript sim-kinesis-shards
75
71
  /**
@@ -121,12 +117,10 @@ console.log(
121
117
  );
122
118
  ```
123
119
 
124
- An `ExplicitHashKey` on a record overrides the partition key for placement, and the record still
125
- carries the partition key the producer gave it. That is how a producer pins a record to a shard it
126
- picked.
120
+ `ExplicitHashKey` overrides the hash used for placement. The stored record still contains the
121
+ original partition key.
127
122
 
128
- A stream created with `StreamModeDetails` of `ON_DEMAND` gets four shards, which is what real
129
- Kinesis starts an on-demand stream with. Nothing here grows or shrinks that count.
123
+ An `ON_DEMAND` stream starts with four shards. Its shard count remains fixed.
130
124
 
131
125
  ## Where a read starts
132
126
 
@@ -140,24 +134,20 @@ Every shard iterator type resolves to a place on the shard.
140
134
  | `AFTER_SEQUENCE_NUMBER` | The record following that sequence number. |
141
135
  | `AT_TIMESTAMP` | The first record that arrived at or after the instant given. |
142
136
 
143
- `GetRecords` hands back a `NextShardIterator` pointing at where the read finished, which is what a
144
- polling consumer passes to its next call. A read that has caught up comes back empty with an
145
- iterator standing where it was.
137
+ Pass `NextShardIterator` to the next `GetRecords` call. A reader at the end of the shard receives an
138
+ empty record list and another iterator at the same position.
146
139
 
147
- `MillisBehindLatest` reports how far behind the tip the reader is. Zero means caught up. Otherwise
148
- it is the age of the last record handed back, measured against simulated time.
140
+ `MillisBehindLatest` is zero for a reader at the end of the shard. Otherwise it reports the age of
141
+ the last returned record, measured against simulated time.
149
142
 
150
143
  ## Retention
151
144
 
152
- A stream keeps a record for 24 hours. Records older than that are gone from a read, and trimming is
153
- applied at the instant of the read rather than on a timer, so moving simulated time forward is all a
154
- test needs.
145
+ A stream retains records for 24 hours by default. Retention is applied when records are read. Move
146
+ simulated time forward to test expiration.
155
147
 
156
- `IncreaseStreamRetentionPeriod` and `DecreaseStreamRetentionPeriod` move it, up to the 8760 hours
157
- Kinesis keeps at most. Each refuses a request that goes the other way, including one asking for what
158
- the stream already keeps, which is what real Kinesis does with a caller that has the wrong idea of
159
- what the stream is set to. Shortening the window drops whatever it has already outlived from the
160
- next read.
148
+ Use `IncreaseStreamRetentionPeriod` or `DecreaseStreamRetentionPeriod` to change the period. Values
149
+ must stay between 24 and 8,760 hours. Each command rejects a value pointing in the wrong direction.
150
+ Shortening the period affects the next read.
161
151
 
162
152
  ```typescript sim-kinesis-retention
163
153
  /**
@@ -209,26 +199,21 @@ console.log(Records.length);
209
199
  ## Triggering a Lambda function
210
200
 
211
201
  A [Lambda event source mapping](https://yulinsim.dev/services/lambda/#triggering-a-function-from-a-kinesis-stream "Simulated Lambda Kinesis event source docs")
212
- polls a stream and invokes a function with the records it reads. Every shard is read by a processor
213
- of its own, as real Lambda reads one, and the function's execution role is what the polling is done
214
- as.
202
+ polls each shard and invokes the function with batches of records. Reads use the function's
203
+ execution role.
215
204
 
216
205
  ## Feeding a Firehose delivery stream
217
206
 
218
207
  A [Firehose delivery stream](https://yulinsim.dev/services/firehose/#reading-from-a-kinesis-stream "Simulated Firehose Kinesis source docs")
219
- can read a stream and buffer what it reads into an S3 Bucket. It reads every shard as its source
220
- `RoleARN`, starting at the end of the stream when the delivery stream is created.
208
+ can read every shard and buffer the records into S3. It starts at the end of the stream and reads as
209
+ its source `RoleARN`.
221
210
 
222
211
  ## Deploying a stream
223
212
 
224
- `AWS::Kinesis::Stream` creates a simulated stream, which is what a CDK `Stream` synthesizes. The
225
- stream goes through the ordinary `CreateStream` command, so a stream a template deployed is the same
226
- thing an SDK caller would have got, and a template asking for something Kinesis will not take is
227
- refused in the words `CreateStream` refuses it in.
213
+ Simulated CloudFormation deploys `AWS::Kinesis::Stream` through `CreateStream`. A CDK `Stream`
214
+ synthesizes this resource type.
228
215
 
229
- `Ref` gives the stream name and `Fn::GetAtt` on `Arn` gives the stream ARN, which is the way round
230
- real CloudFormation publishes them. Every Kinesis API and every grant names the ARN, so a template
231
- wiring a stream into a Lambda event source mapping or an IAM policy reads the attribute.
216
+ `Ref` returns the stream name. `Fn::GetAtt Arn` returns its ARN.
232
217
 
233
218
  ```typescript sim-kinesis-cloudformation
234
219
  /**
@@ -274,32 +259,24 @@ await simAws.kinesis().putRecord(
274
259
  );
275
260
  ```
276
261
 
277
- `Name`, `ShardCount`, `RetentionPeriodHours`, `StreamModeDetails` and `Tags` are read. A stream the
278
- template does not name is named after the stack, the logical ID and a tail derived from both, as
279
- [the CloudFormation docs](https://yulinsim.dev/services/cloudformation/#names-cloudformation-generates "Names CloudFormation generates")
280
- describe.
262
+ Yulin reads `Name`, `ShardCount`, `RetentionPeriodHours`, `StreamModeDetails` and `Tags`. It generates
263
+ a name when `Name` is absent. See [generated resource names](https://yulinsim.dev/services/cloudformation/#names-cloudformation-generates "Names CloudFormation generates").
281
264
 
282
- `RetentionPeriodHours` is applied after the stream is created, because `CreateStream` takes no
283
- retention on real Kinesis either. It only ever goes up: a new stream keeps records for 24 hours,
284
- which is also the least Kinesis accepts, so a template can ask for more or for the same and never
285
- for less.
265
+ `RetentionPeriodHours` is applied after creation. A new stream already has the minimum 24-hour
266
+ period, so a template may keep it or increase it.
286
267
 
287
- `StreamEncryption` and `DesiredShardLevelMetrics` are recorded against the resource as unsimulated
288
- and the stream is created anyway, so a template that encrypts its streams still deploys and the
289
- omission is somewhere a test can find it. Deleting the stack deletes the stream.
268
+ `StreamEncryption` and `DesiredShardLevelMetrics` are recorded as ignored properties. The stream is
269
+ still created. Deleting the stack deletes it.
290
270
 
291
- `AWS::Kinesis::StreamConsumer` and `AWS::Kinesis::ResourcePolicy` are reported as unsupported and
292
- skipped. One registers an enhanced fan-out consumer and the other admits a caller from another
293
- account, and neither has anything to act on here.
271
+ `AWS::Kinesis::StreamConsumer` and `AWS::Kinesis::ResourcePolicy` are skipped. Enhanced fan-out and
272
+ resource policies are absent.
294
273
 
295
274
  ## Permissions
296
275
 
297
- Every operation goes through simulated IAM. The action is the `kinesis:` name of the operation, and
298
- the resource is the stream ARN, `arn:aws:kinesis:<region>:<account>:stream/<name>`. `ListStreams`
299
- names no stream and authorizes against `*`.
276
+ Every operation uses simulated IAM. Stream operations authorize the corresponding `kinesis:` action
277
+ against the stream ARN. `ListStreams` authorizes against `*`.
300
278
 
301
- `GetRecords` authorizes against the stream the iterator was made on, which the iterator carries. A
302
- caller cannot reach a stream it lacks permission for by holding someone else's iterator.
279
+ `GetRecords` authorizes against the stream stored in the iterator.
303
280
 
304
281
  ```typescript sim-kinesis-permissions
305
282
  /**
@@ -362,8 +339,7 @@ try {
362
339
 
363
340
  ## SDK interception
364
341
 
365
- A `KinesisClient` handed to `SimSdk` reaches the simulated service, so application code that builds
366
- its own client needs no change.
342
+ Intercept a `KinesisClient` when application code creates and uses the client itself.
367
343
 
368
344
  ```typescript sim-kinesis-sdk-interception
369
345
  /**
@@ -418,38 +394,22 @@ console.log(put.ShardId);
418
394
 
419
395
  Every operation takes `StreamName` or `StreamARN`, and reads the ARN when a request carries both.
420
396
 
421
- Anything else refuses on send with `SimSdkUnsupportedCommandError`.
397
+ Any other command raises `SimSdkUnsupportedCommandError`.
422
398
 
423
399
  ## Divergences and limitations
424
400
 
425
- - **A stream is `ACTIVE` as soon as it exists.** Real Kinesis reports `CREATING` while it brings the
426
- shards up, and a status a test has to poll through earns nothing when there are no shards to bring
427
- up. `DELETING` and `UPDATING` are absent for the same reason.
428
- - **Nothing reshards.** `UpdateShardCount`, `SplitShard` and `MergeShards` move the shard map
429
- underneath consumers holding iterators, and they are left out. A shard is opened when the stream
430
- is created and never closes, so no shard reports an ending sequence number and no read reports a
431
- child shard.
432
- - **Enhanced fan-out is absent.** `RegisterStreamConsumer`, `DeregisterStreamConsumer`,
433
- `ListStreamConsumers`, `DescribeStreamConsumer` and `SubscribeToShard` need an HTTP/2 event stream
434
- that nothing here delivers. Every consumer reads through `GetRecords`.
401
+ - Streams become `ACTIVE` immediately. `CREATING`, `DELETING` and `UPDATING` states are absent.
402
+ - Resharding is absent. `UpdateShardCount`, `SplitShard` and `MergeShards` are unsupported. Shards
403
+ have no ending sequence number or child shards.
404
+ - Enhanced fan-out is absent. Consumers read through `GetRecords`.
435
405
  - **A shard iterator never expires.** Real Kinesis expires one after five minutes. An iterator this
436
406
  simulation never issued is still refused, with the `ExpiredIteratorException` real Kinesis uses.
437
- - **Throughput is unlimited.** Real Kinesis takes 1 MB or 1,000 records a second per shard for
438
- writes and 2 MB a second for reads, and refuses past that with
439
- `ProvisionedThroughputExceededException`. Nothing here counts. That is why `FailedRecordCount` on
440
- `PutRecords` is always zero: the reasons real Kinesis fails one record of a batch are throughput
441
- limits and internal faults, and neither is simulated. The per-record result shape is still what a
442
- consumer of the response reads.
407
+ - Throughput is unlimited. Yulin never raises `ProvisionedThroughputExceededException`, and
408
+ `PutRecords` reports zero failed records.
443
409
  - **Sequence numbers are 56 digit counters.** They are unique within a stream and increase within a
444
- shard, as real Kinesis promises. They also increase across shards here, which real Kinesis does
445
- not promise, so a consumer ordering two records from different shards would be relying on
446
- something AWS does not offer.
447
- - **Server-side encryption is absent.** `StartStreamEncryption` and `StopStreamEncryption` are left
448
- out, and no response carries an `EncryptionType`.
449
- - **Tags are kept and never listed.** A stream created with `Tags` holds them, readable through
450
- `findStream`. `AddTagsToStream`, `ListTagsForStream` and `RemoveTagsFromStream` are absent.
451
- - **Kinesis Data Firehose is a separate service.** It has a simulation of its own under
452
- `simAws.firehose()`, and a delivery stream there can read a stream here. Kinesis Video Streams is
453
- absent.
454
- - **`AWS::DynamoDB::Table` `KinesisStreamSpecification` stays unsimulated.** A table does not publish
455
- its changes into a stream here.
410
+ shard, as real Kinesis promises. Yulin also increments them across shards. AWS promises ordering
411
+ within a shard only.
412
+ - Server-side encryption is absent. Responses contain no `EncryptionType`.
413
+ - Stream tags are stored and available through `findStream`. Tagging commands are unsupported.
414
+ - Kinesis Video Streams is absent.
415
+ - The DynamoDB `KinesisStreamSpecification` integration is absent.
@@ -1,17 +1,15 @@
1
1
  # Simulated KMS
2
2
 
3
- Yulin includes a simulated AWS Key Management Service (KMS) for tests and local development.
4
-
5
- Encryption is real. Each simulated key holds AES-256 key material and the operations run through
6
- Node.js's own `crypto`. A ciphertext can only be read with its key, and a decryption with the wrong
7
- encryption context fails.
3
+ Yulin simulates AWS Key Management Service (KMS) in memory. Symmetric keys use AES-256 key material,
4
+ and asymmetric keys use real key pairs. Cryptographic operations run through Node.js `crypto`, so
5
+ the wrong key or encryption context cannot decrypt a ciphertext.
8
6
 
9
7
  KMS-specific types are imported from the `@kensio/yulin/kms` subpath.
10
8
 
11
9
  ## Encrypting and decrypting
12
10
 
13
- Create a key and use it. `Decrypt` needs no `KeyId` for a symmetric key, because the ciphertext
14
- already names the key that produced it.
11
+ Create a key, encrypt a value, then decrypt it. `Decrypt` does not need a `KeyId` for symmetric
12
+ ciphertext because the ciphertext identifies its key.
15
13
 
16
14
  ```typescript sim-kms-encrypt-decrypt
17
15
  /**
@@ -52,8 +50,8 @@ any second `SimAws` instance both reject it.
52
50
 
53
51
  ## Encryption context
54
52
 
55
- An encryption context is non-secret key/value data bound to a ciphertext. Decryption with a
56
- different context fails. That ties a ciphertext to the thing it belongs to.
53
+ An encryption context binds non-secret key/value data to a ciphertext. Decryption requires the same
54
+ context.
57
55
 
58
56
  ```typescript sim-kms-encryption-context
59
57
  /**
@@ -100,9 +98,8 @@ The context is an unordered map. The same pairs written in a different order sti
100
98
 
101
99
  ## Envelope encryption
102
100
 
103
- `Encrypt` takes at most 4096 bytes. That limit is what makes envelope encryption necessary.
104
- `GenerateDataKey` returns a data key twice, once in the clear to encrypt your data with, and once
105
- encrypted under the KMS key to store alongside it.
101
+ `Encrypt` accepts at most 4,096 bytes. For larger values, use `GenerateDataKey`. It returns a
102
+ plaintext data key for encryption and an encrypted copy to store with the data.
106
103
 
107
104
  ```typescript sim-kms-generate-data-key
108
105
  /**
@@ -141,8 +138,8 @@ console.log(recovered.Plaintext?.length); // 32
141
138
 
142
139
  ## Signing and verifying
143
140
 
144
- A key created with `KeyUsage: SIGN_VERIFY` holds a real key pair, and the signatures are real
145
- signatures. A key spec is required, because the default `SYMMETRIC_DEFAULT` spec cannot sign.
141
+ A key with `KeyUsage: SIGN_VERIFY` holds a real key pair. Set a signing key spec because the default
142
+ `SYMMETRIC_DEFAULT` key cannot sign.
146
143
 
147
144
  ```typescript sim-kms-sign-verify
148
145
  /**
@@ -261,9 +258,8 @@ both matching what KMS produces. `GetPublicKey` against a symmetric key is
261
258
 
262
259
  ## Key policies and IAM
263
260
 
264
- Every KMS key has a policy, and it cannot be removed. An IAM policy granting `kms:Decrypt` only
265
- takes effect where the key's own policy admits the caller. How it admits them decides what else is
266
- needed:
261
+ Every key has a key policy. An identity policy granting `kms:Decrypt` works only when the key policy
262
+ also permits the caller:
267
263
 
268
264
  - A statement naming the caller grants access outright. A role with no permissions of its own can
269
265
  still use the key.
@@ -342,16 +338,15 @@ on real KMS.
342
338
 
343
339
  ## AWS managed keys and `kms:ViaService`
344
340
 
345
- An alias beginning `alias/aws/` names an AWS managed key, and the key is created the first time
346
- something references it. Such a key gets the policy real AWS gives it, which differs from the
347
- customer default:
341
+ An alias beginning with `alias/aws/` names an AWS managed key. Yulin creates that key when it is
342
+ first referenced and applies AWS-managed-key policy behavior:
348
343
 
349
344
  - Use of the key is allowed to any principal in the owning account, but only when `kms:ViaService`
350
345
  names the service that owns the key, such as `ssm.us-east-1.amazonaws.com` for `aws/ssm`.
351
- - The account root is allowed to read the key's metadata. That is the whole of what this policy
352
- delegates to IAM.
346
+ - The account root can read the key's metadata.
353
347
 
354
- That is why a role holding `kms:Decrypt` on such a key cannot use it by calling KMS itself.
348
+ A role cannot use an AWS managed key by calling KMS directly, even when its identity policy grants
349
+ `kms:Decrypt`.
355
350
 
356
351
  `kms:ViaService` is set by the service making the call on the caller's behalf. Sim SSM does this for
357
352
  `SecureString` parameters. Code calling simulated KMS directly sets it with the `viaService` request
@@ -417,8 +412,7 @@ and a condition on it stays unmatched.
417
412
 
418
413
  ## Naming a key
419
414
 
420
- Every operation takes its target as a `KeyId`, in any of the four forms real KMS accepts. Those are
421
- a key ID, a key ARN, an alias name such as `alias/app-key`, and an alias ARN.
415
+ `KeyId` accepts a key ID, key ARN, alias name such as `alias/app-key`, or alias ARN.
422
416
 
423
417
  A key ARN or alias ARN naming another account or region resolves to no key at all. Its identifier is
424
418
  never read out and looked up locally. A foreign ARN cannot reach a key that happens to share an
@@ -473,8 +467,8 @@ console.log(managed.KeyMetadata?.KeyManager); // "AWS"
473
467
 
474
468
  A key can be disabled and re-enabled later. A disabled key stays present, and refuses to be used.
475
469
 
476
- Deletion is never immediate. `ScheduleKeyDeletion` sets a recovery window of 7 to 30 days, defaulting
477
- to 30. During that window the key refuses to be used but can still be recovered with
470
+ `ScheduleKeyDeletion` sets a recovery window from 7 to 30 days, defaulting to 30. During that window
471
+ the key cannot be used but can be recovered with
478
472
  `CancelKeyDeletion`. Cancelling leaves the key disabled. Re-enabling it is a separate step.
479
473
 
480
474
  A disabled key fails cryptographic operations with `DisabledException`. A key pending deletion fails
@@ -600,9 +594,7 @@ the function's execution role as the caller. A handler that decrypts a value the
600
594
  allowed to, by both the key policy and the role's identity policy, the same as on real AWS. See
601
595
  [simulated Lambda](https://yulinsim.dev/services/lambda/) for how function code and execution roles work.
602
596
 
603
- ## Available functionality
604
-
605
- Sim KMS currently supports:
597
+ ## Supported operations
606
598
 
607
599
  - `CreateKeyCommand`, for symmetric encryption keys and asymmetric signing keys
608
600
  - `DescribeKeyCommand` and `ListKeysCommand`
@@ -619,8 +611,6 @@ Sim KMS currently supports:
619
611
 
620
612
  ## Limitations
621
613
 
622
- Current documented limitations:
623
-
624
614
  - Only encryption with a symmetric key and signing with an asymmetric key are simulated. Left out
625
615
  are asymmetric encryption (`RSAES_OAEP_SHA_1` and `RSAES_OAEP_SHA_256`), HMAC keys and
626
616
  `GENERATE_VERIFY_MAC`, key agreement and `DeriveSharedSecret`, the `SM2` key spec, and