@kensio/yulin 1.20.14 → 1.20.16

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 (154) hide show
  1. package/README.md +13 -0
  2. package/{dist/config/oxlint/cffjs2.oxlintrc.json → cffjs2.oxlintrc.json} +1 -1
  3. package/dist/config/oxlint/cffjs2.oxlint.config.js +4 -3
  4. package/dist/sdk/module/sim-sdk-module-client-interceptor.d.ts +5 -0
  5. package/dist/sdk/module/sim-sdk-module-client-interceptor.js +14 -0
  6. package/dist/sdk/module/sim-sdk-static-client-factory.d.ts +26 -0
  7. package/dist/sdk/module/sim-sdk-static-client-factory.js +59 -0
  8. package/dist/sdk/send-patch.d.ts +8 -0
  9. package/dist/sdk/send-patch.js +11 -0
  10. package/dist/service/aws/caller/sim-aws-caller-resolver.d.ts +28 -6
  11. package/dist/service/aws/caller/sim-aws-caller-resolver.js +18 -11
  12. package/dist/service/aws/caller/sim-aws-caller.d.ts +9 -0
  13. package/dist/service/aws/caller/sim-aws-resolved-caller.d.ts +19 -0
  14. package/dist/service/aws/caller/sim-aws-resolved-caller.js +26 -0
  15. package/dist/service/aws/factory/sim-aws-account-region-service-builder.d.ts +6 -0
  16. package/dist/service/aws/factory/sim-aws-account-region-service-builder.js +3 -0
  17. package/dist/service/aws/factory/sim-aws-account-service-cache.d.ts +6 -0
  18. package/dist/service/aws/factory/sim-aws-account-service-cache.js +5 -0
  19. package/dist/service/aws/factory/sim-aws-service-factory.d.ts +5 -0
  20. package/dist/service/aws/factory/sim-aws-service-factory.js +6 -0
  21. package/dist/service/aws/sim-aws-properties.d.ts +15 -0
  22. package/dist/service/aws/sim-aws.js +2 -1
  23. package/dist/service/cloudformation/resource/resolve/property/sim-cfn-resource-property-resolver.d.ts +11 -4
  24. package/dist/service/cloudformation/resource/resolve/property/sim-cfn-resource-property-resolver.js +21 -8
  25. package/dist/service/cloudformation/resource/sim-cfn-resource.type.d.ts +9 -0
  26. package/dist/service/cloudformation/template/dynamic/make-sim-cfn-dynamic-references.d.ts +2 -0
  27. package/dist/service/cloudformation/template/dynamic/make-sim-cfn-dynamic-references.js +2 -2
  28. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-resolvers.d.ts +10 -0
  29. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-resolvers.js +4 -3
  30. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-scan.d.ts +11 -0
  31. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-reference-scan.js +21 -0
  32. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-references.d.ts +24 -2
  33. package/dist/service/cloudformation/template/dynamic/sim-cfn-dynamic-references.js +50 -11
  34. package/dist/service/cloudformation/template/dynamic/sim-cfn-prefetched-dynamic-references.d.ts +42 -0
  35. package/dist/service/cloudformation/template/dynamic/sim-cfn-prefetched-dynamic-references.js +80 -0
  36. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-failures.d.ts +16 -0
  37. package/dist/service/eventbridge/delivery/sim-event-bridge-delivery-failures.js +19 -0
  38. package/dist/service/iam/authorize/context/sim-iam-auth-z-caller-context-builder.d.ts +30 -7
  39. package/dist/service/iam/authorize/context/sim-iam-auth-z-caller-context-builder.js +20 -11
  40. package/dist/service/iam/authorize/context/sim-iam-auth-z-context-builder.d.ts +2 -1
  41. package/dist/service/iam/authorize/context/sim-iam-auth-z-context-builder.js +5 -1
  42. package/dist/service/iam/authorize/match/sim-iam-policy-principal-matcher.d.ts +10 -0
  43. package/dist/service/iam/authorize/match/sim-iam-policy-principal-matcher.js +15 -3
  44. package/dist/service/iam/authorize/sim-iam-account-auth-z.d.ts +11 -4
  45. package/dist/service/iam/authorize/sim-iam-account-auth-z.js +5 -3
  46. package/dist/service/iam/authorize/sim-iam-authorizer.d.ts +2 -1
  47. package/dist/service/iam/authorize/sim-iam-authorizer.js +1 -0
  48. package/dist/service/iam/command/policy/create-policy/create-policy-input-resolver.js +4 -1
  49. package/dist/service/iam/command/policy/put-role-policy/put-role-policy.handler.js +5 -1
  50. package/dist/service/iam/command/policy/put-user-policy/put-user-policy.handler.js +5 -1
  51. package/dist/service/iam/policy/parse/sim-iam-document-parser.d.ts +4 -1
  52. package/dist/service/iam/policy/parse/sim-iam-document-parser.js +13 -15
  53. package/dist/service/iam/policy/sim-iam-statement-label.d.ts +28 -0
  54. package/dist/service/iam/policy/sim-iam-statement-label.js +17 -0
  55. package/dist/service/iam/policy/sim-iam-statement-strings.d.ts +11 -0
  56. package/dist/service/iam/policy/sim-iam-statement-strings.js +27 -0
  57. package/dist/service/iam/role/sim-iam-role-with-policy.factory.d.ts +9 -0
  58. package/dist/service/iam/role/sim-iam-role-with-policy.factory.js +4 -2
  59. package/dist/service/iam/sim-iam-account-parts.d.ts +8 -0
  60. package/dist/service/iam/sim-iam-account-parts.js +1 -0
  61. package/dist/service/iam/validate/sim-iam-policy-document-validator.d.ts +9 -2
  62. package/dist/service/iam/validate/sim-iam-policy-document-validator.js +37 -19
  63. package/dist/service/lambda/function/code/sim-lambda-vm-zip-function.factory.d.ts +7 -0
  64. package/dist/service/lambda/function/code/sim-lambda-vm-zip-function.factory.js +1 -0
  65. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-provided-sdk-module.d.ts +19 -0
  66. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-provided-sdk-module.js +78 -0
  67. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-sdk-packages-not-installed.error.d.ts +15 -0
  68. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-sdk-packages-not-installed.error.js +27 -0
  69. package/dist/service/lambda/function/code/vm/sdk/sim-lambda-vm-sdk-module-provider.d.ts +9 -0
  70. package/dist/service/lambda/function/code/vm/sdk/sim-sdk-lambda-vm-module-provider.d.ts +10 -0
  71. package/dist/service/lambda/function/code/vm/sdk/sim-sdk-lambda-vm-module-provider.js +28 -34
  72. package/dist/service/lambda/function/code/vm/sim-lambda-host-modules.d.ts +15 -0
  73. package/dist/service/lambda/function/code/vm/sim-lambda-host-modules.js +31 -0
  74. package/dist/service/lambda/function/code/vm/sim-lambda-vm-module-resolver.d.ts +7 -0
  75. package/dist/service/lambda/function/code/vm/sim-lambda-vm-module-resolver.js +15 -0
  76. package/dist/service/lambda/function/code/vm/sim-lambda-vm-modules.js +5 -4
  77. package/dist/service/s3/command/put-bucket-policy/put-bucket-policy.handler.js +4 -1
  78. package/dist/service/scheduler/delivery/sim-scheduler-delivery-failures.d.ts +16 -0
  79. package/dist/service/scheduler/delivery/sim-scheduler-delivery-failures.js +19 -0
  80. package/dist/service/scheduler/index.d.ts +1 -1
  81. package/dist/service/scheduler/index.js +1 -1
  82. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-dynamic-reference-resolver.d.ts +13 -15
  83. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-dynamic-reference-resolver.js +22 -43
  84. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-stand-in.d.ts +9 -0
  85. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-stand-in.js +14 -0
  86. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-value.d.ts +12 -0
  87. package/dist/service/secretsmanager/cfn/dynamic/sim-cfn-secrets-manager-reference-value.js +29 -0
  88. package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-dynamic-reference-resolver.d.ts +22 -6
  89. package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-dynamic-reference-resolver.js +39 -24
  90. package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-secure-dynamic-reference-resolver.d.ts +10 -5
  91. package/dist/service/ssm/cfn/dynamic/sim-cfn-ssm-secure-dynamic-reference-resolver.js +10 -8
  92. package/dist/service/ssm/sim-ssm.d.ts +10 -2
  93. package/dist/service/ssm/sim-ssm.js +12 -4
  94. package/dist/service/sts/auth-z/assume-role-auth-z-coordinator.d.ts +9 -2
  95. package/dist/service/sts/auth-z/assume-role-auth-z-coordinator.js +2 -2
  96. package/dist/service/sts/auth-z/assume-role-source-account-auth-z.d.ts +10 -4
  97. package/dist/service/sts/auth-z/assume-role-source-account-auth-z.js +8 -7
  98. package/dist/service/sts/auth-z/assume-role-target-auth-z.d.ts +2 -2
  99. package/dist/service/sts/auth-z/assume-role-trust-policy-authorizer.d.ts +6 -2
  100. package/dist/service/sts/auth-z/assume-role-trust-policy-authorizer.js +14 -11
  101. package/dist/service/sts/command/assume-role/assume-role.handler.d.ts +5 -1
  102. package/dist/service/sts/command/assume-role/assume-role.handler.js +5 -2
  103. package/dist/service/sts/command/get-caller-identity/get-caller-identity.handler.d.ts +5 -1
  104. package/dist/service/sts/command/get-caller-identity/get-caller-identity.handler.js +4 -1
  105. package/dist/service/sts/service-role/sim-service-role.js +5 -1
  106. package/dist/service/sts/sim-sts.d.ts +9 -1
  107. package/dist/service/sts/sim-sts.js +4 -0
  108. package/docs/README.md +54 -0
  109. package/docs/ai-skill/README.md +69 -0
  110. package/docs/cli/README.md +284 -0
  111. package/docs/factories/README.md +140 -0
  112. package/docs/lint/README.md +176 -0
  113. package/docs/non-aws-dependencies/README.md +261 -0
  114. package/docs/sdk/README.md +272 -0
  115. package/docs/serve/README.md +1126 -0
  116. package/docs/services/acm/README.md +823 -0
  117. package/docs/services/apigateway/README.md +1919 -0
  118. package/docs/services/apigatewayv2/README.md +2678 -0
  119. package/docs/services/athena/README.md +1044 -0
  120. package/docs/services/bedrock/README.md +350 -0
  121. package/docs/services/cloudformation/README.md +3440 -0
  122. package/docs/services/cloudfront/README.md +2874 -0
  123. package/docs/services/cloudwatch/README.md +420 -0
  124. package/docs/services/cognito/README.md +4923 -0
  125. package/docs/services/dynamodb/README.md +3784 -0
  126. package/docs/services/ecr/README.md +302 -0
  127. package/docs/services/ecs/README.md +2010 -0
  128. package/docs/services/elbv2/README.md +1897 -0
  129. package/docs/services/eventbridge/README.md +1110 -0
  130. package/docs/services/firehose/README.md +805 -0
  131. package/docs/services/glue/README.md +501 -0
  132. package/docs/services/iam/README.md +1283 -0
  133. package/docs/services/kinesis/README.md +454 -0
  134. package/docs/services/kms/README.md +659 -0
  135. package/docs/services/lambda/README.md +3645 -0
  136. package/docs/services/logs/README.md +868 -0
  137. package/docs/services/organizations/README.md +574 -0
  138. package/docs/services/personalize/README.md +835 -0
  139. package/docs/services/rekognition/README.md +1070 -0
  140. package/docs/services/route53/README.md +1783 -0
  141. package/docs/services/s3/README.md +3024 -0
  142. package/docs/services/scheduler/README.md +806 -0
  143. package/docs/services/secretsmanager/README.md +667 -0
  144. package/docs/services/ses/README.md +1011 -0
  145. package/docs/services/sns/README.md +1904 -0
  146. package/docs/services/sqs/README.md +1185 -0
  147. package/docs/services/ssm/README.md +1072 -0
  148. package/docs/services/stepfunctions/README.md +1332 -0
  149. package/docs/services/sts/README.md +245 -0
  150. package/docs/services/wafv2/README.md +1378 -0
  151. package/docs/terraform/README.md +248 -0
  152. package/docs/time/README.md +284 -0
  153. package/llms.txt +59 -0
  154. package/package.json +9 -5
@@ -1,6 +1,6 @@
1
1
  import type { SimArn } from "../../../aws/arn.js";
2
2
  import type { AwsRegionName } from "../../../aws/sim-aws-region.js";
3
- import type { SimAwsCaller, SimAwsPrincipal } from "../../../aws/caller/sim-aws-caller.js";
3
+ import type { SimAwsCaller, SimAwsDefaultCaller, SimAwsPrincipal } from "../../../aws/caller/sim-aws-caller.js";
4
4
  import type { SimAwsAccountId } from "../../../aws/sim-aws-account.js";
5
5
  import type { SimIamAccountResolver } from "../../registry/sim-iam-account-resolver.js";
6
6
  import type { SimIamConditionValue, SimIamPolicy, SimIamPolicyDocument } from "../../policy/sim-iam-policy.js";
@@ -85,6 +85,7 @@ interface SimIamAuthZContextBuilderProperties {
85
85
  readonly roles: ReadonlyMap<SimIamRoleName, SimIamRole>;
86
86
  readonly users: ReadonlyMap<SimIamUsername, SimIamUser>;
87
87
  readonly credentialIdentityResolver: SimAwsCredentialIdentityResolver;
88
+ readonly defaultCaller?: SimAwsDefaultCaller | undefined;
88
89
  /**
89
90
  * Resolves other Accounts' IAM in the same simulation, for the identity side
90
91
  * of a cross-Account request.
@@ -43,7 +43,11 @@ export class SimIamAuthZContextBuilder {
43
43
  derivedConditions = new SimIamDerivedConditions();
44
44
  scpSourceBuilder;
45
45
  constructor(properties) {
46
- this.callerContextBuilder = new SimIamAuthZCallerContextBuilder(makeSimAwsAccountRootPrincipal(properties.accountId), properties.credentialIdentityResolver);
46
+ this.callerContextBuilder = new SimIamAuthZCallerContextBuilder({
47
+ accountRootPrincipal: makeSimAwsAccountRootPrincipal(properties.accountId),
48
+ credentialIdentityResolver: properties.credentialIdentityResolver,
49
+ defaultCaller: properties.defaultCaller,
50
+ });
47
51
  this.identityPolicyCoordinator = new SimIamAuthZIdentityPolicyCoordinator({
48
52
  policies: properties.policies,
49
53
  roles: properties.roles,
@@ -47,8 +47,18 @@ export declare class SimIamPolicyPrincipalMatcher {
47
47
  * The wildcard matches both authenticated and anonymous requests. Other AWS
48
48
  * forms require an ARN-based caller. Account delegation forms compare against
49
49
  * the account ID derived by the caller resolver.
50
+ *
51
+ * A pattern is compared against two ARNs, because an assumed-role session
52
+ * has two. The session ARN is the caller, and the Role behind it is the
53
+ * identity whose policies apply. AWS matches a policy naming either one, and
54
+ * recommends naming the Role. The two ARNs are the same for every caller
55
+ * that is not a session, so one comparison happens in that case.
50
56
  */
51
57
  private awsPatternMatches;
58
+ /**
59
+ * Whether a principal pattern names one of the caller's ARNs.
60
+ */
61
+ private arnMatches;
52
62
  /**
53
63
  * Compare a service principal pattern with the resolved caller.
54
64
  *
@@ -81,6 +81,12 @@ export class SimIamPolicyPrincipalMatcher {
81
81
  * The wildcard matches both authenticated and anonymous requests. Other AWS
82
82
  * forms require an ARN-based caller. Account delegation forms compare against
83
83
  * the account ID derived by the caller resolver.
84
+ *
85
+ * A pattern is compared against two ARNs, because an assumed-role session
86
+ * has two. The session ARN is the caller, and the Role behind it is the
87
+ * identity whose policies apply. AWS matches a policy naming either one, and
88
+ * recommends naming the Role. The two ARNs are the same for every caller
89
+ * that is not a session, so one comparison happens in that case.
84
90
  */
85
91
  awsPatternMatches(pattern) {
86
92
  if (pattern === "*") {
@@ -94,9 +100,15 @@ export class SimIamPolicyPrincipalMatcher {
94
100
  if (delegatedAccountId !== undefined) {
95
101
  return SimIamPrincipalMatch.accountDelegation().when(caller.accountId === delegatedAccountId);
96
102
  }
97
- return SimIamPrincipalMatch.direct().when(simIamWildcardMatch(pattern, caller.arn, {
98
- caseSensitive: true,
99
- }));
103
+ return SimIamPrincipalMatch.direct().when(this.arnMatches(pattern, caller.arn) ||
104
+ this.arnMatches(pattern, caller.identityPolicyArn));
105
+ }
106
+ /**
107
+ * Whether a principal pattern names one of the caller's ARNs.
108
+ */
109
+ arnMatches(pattern, arn) {
110
+ return (arn !== undefined &&
111
+ simIamWildcardMatch(pattern, arn, { caseSensitive: true }));
100
112
  }
101
113
  /**
102
114
  * Compare a service principal pattern with the resolved caller.
@@ -1,7 +1,7 @@
1
1
  import type { SimAwsAccountId } from "../../aws/sim-aws-account.js";
2
2
  import type { SimArn } from "../../aws/arn.js";
3
3
  import type { SimAwsCredentialIdentityResolver } from "../../aws/caller/sim-aws-caller-resolver.js";
4
- import type { SimAwsPrincipal } from "../../aws/caller/sim-aws-caller.js";
4
+ import type { SimAwsDefaultCaller, SimAwsPrincipal } from "../../aws/caller/sim-aws-caller.js";
5
5
  import type { SimIamManagedPolicy } from "../policy/sim-iam-policy.js";
6
6
  import type { SimIamRole, SimIamRoleName } from "../role/sim-iam-role.js";
7
7
  import type { SimIamUser, SimIamUsername } from "../user/sim-iam-user.js";
@@ -17,6 +17,12 @@ interface SimIamAccountAuthZProperties {
17
17
  readonly roles: Map<SimIamRoleName, SimIamRole>;
18
18
  readonly users: Map<SimIamUsername, SimIamUser>;
19
19
  readonly credentialIdentityResolver: SimAwsCredentialIdentityResolver;
20
+ /**
21
+ * The caller this simulation attributes a request naming none to.
22
+ *
23
+ * Left out, such a request is decided as this Account's root principal.
24
+ */
25
+ readonly defaultCaller?: SimAwsDefaultCaller | undefined;
20
26
  /**
21
27
  * Resolves other Accounts' IAM in the same simulation.
22
28
  *
@@ -37,9 +43,10 @@ interface SimIamAccountAuthZProperties {
37
43
  * Evaluates IAM authorization attempts against one simulated Account's IAM
38
44
  * state.
39
45
  *
40
- * If the caller is omitted, authorization defaults to the root principal of
41
- * the owning sim Account. An explicit anonymous caller suppresses that
42
- * fallback and is evaluated without identity policies.
46
+ * If the caller is omitted, authorization defaults to the simulation's default
47
+ * caller, and to the root principal of the owning sim Account where the
48
+ * simulation has none. An explicit anonymous caller suppresses both and is
49
+ * evaluated without identity policies.
43
50
  */
44
51
  export declare class SimIamAccountAuthZ implements SimIamAccountIdentityPolicies {
45
52
  private readonly properties;
@@ -3,9 +3,10 @@ import { SimIamAuthorizer } from "./sim-iam-authorizer.js";
3
3
  * Evaluates IAM authorization attempts against one simulated Account's IAM
4
4
  * state.
5
5
  *
6
- * If the caller is omitted, authorization defaults to the root principal of
7
- * the owning sim Account. An explicit anonymous caller suppresses that
8
- * fallback and is evaluated without identity policies.
6
+ * If the caller is omitted, authorization defaults to the simulation's default
7
+ * caller, and to the root principal of the owning sim Account where the
8
+ * simulation has none. An explicit anonymous caller suppresses both and is
9
+ * evaluated without identity policies.
9
10
  */
10
11
  export class SimIamAccountAuthZ {
11
12
  properties;
@@ -38,6 +39,7 @@ export class SimIamAccountAuthZ {
38
39
  roles: this.properties.roles,
39
40
  users: this.properties.users,
40
41
  credentialIdentityResolver: this.properties.credentialIdentityResolver,
42
+ defaultCaller: this.properties.defaultCaller,
41
43
  iamResolver: this.properties.iamResolver,
42
44
  scpResolver: this.properties.scpResolver,
43
45
  });
@@ -3,7 +3,7 @@ import type { SimIamPolicy } from "../policy/sim-iam-policy.js";
3
3
  import type { SimIamRole, SimIamRoleName } from "../role/sim-iam-role.js";
4
4
  import { type SimIamAuthorizationInput } from "./context/sim-iam-auth-z-context-builder.js";
5
5
  import { SimIamPolicyDecision } from "./sim-iam-decision.js";
6
- import type { SimAwsPrincipal } from "../../aws/caller/sim-aws-caller.js";
6
+ import type { SimAwsDefaultCaller, SimAwsPrincipal } from "../../aws/caller/sim-aws-caller.js";
7
7
  import type { SimIamUser, SimIamUsername } from "../user/sim-iam-user.js";
8
8
  import type { SimAwsCredentialIdentityResolver } from "../../aws/caller/sim-aws-caller-resolver.js";
9
9
  import type { SimAwsAccountId } from "../../aws/sim-aws-account.js";
@@ -17,6 +17,7 @@ interface SimIamAuthorizerProperties {
17
17
  readonly roles: ReadonlyMap<SimIamRoleName, SimIamRole>;
18
18
  readonly users: ReadonlyMap<SimIamUsername, SimIamUser>;
19
19
  readonly credentialIdentityResolver: SimAwsCredentialIdentityResolver;
20
+ readonly defaultCaller?: SimAwsDefaultCaller | undefined;
20
21
  readonly iamResolver?: SimIamAccountResolver | undefined;
21
22
  readonly scpResolver?: SimIamServiceControlPolicyResolver | undefined;
22
23
  }
@@ -17,6 +17,7 @@ export class SimIamAuthorizer {
17
17
  roles: properties.roles,
18
18
  users: properties.users,
19
19
  credentialIdentityResolver: properties.credentialIdentityResolver,
20
+ defaultCaller: properties.defaultCaller,
20
21
  iamResolver: properties.iamResolver,
21
22
  scpResolver: properties.scpResolver,
22
23
  });
@@ -26,7 +26,10 @@ export class CreatePolicyInputResolver {
26
26
  if (policyName === undefined || policyName.length === 0) {
27
27
  throw new Error("PolicyName is required");
28
28
  }
29
- this.policyDocValidator.validateOptional(command.input.PolicyDocument);
29
+ this.policyDocValidator.validateOptional(command.input.PolicyDocument, {
30
+ attachedTo: "Policy",
31
+ name: policyName,
32
+ });
30
33
  const path = normalisePolicyPath(command.input.Path);
31
34
  const arn = makeSimPolicyArn({
32
35
  accountId: this.accountId,
@@ -33,7 +33,11 @@ export class PutRolePolicyCommandHandler {
33
33
  throw new Error("PolicyName is required");
34
34
  }
35
35
  const policyDocument = command.input.PolicyDocument;
36
- this.policyDocValidator.validateRequired(policyDocument);
36
+ this.policyDocValidator.validateRequired(policyDocument, {
37
+ attachedTo: "Role",
38
+ name: roleName,
39
+ policyName,
40
+ });
37
41
  // Allow for potential non-deterministic sequencing of async events.
38
42
  await this.background.sequence();
39
43
  const role = this.roles.get(roleName);
@@ -29,7 +29,11 @@ export class PutUserPolicyCommandHandler {
29
29
  const policyName = command.input.PolicyName;
30
30
  assertDefined(policyName, "PutUserPolicyCommand.input.PolicyName");
31
31
  const policyDocument = command.input.PolicyDocument;
32
- this.policyDocValidator.validateRequired(policyDocument);
32
+ this.policyDocValidator.validateRequired(policyDocument, {
33
+ attachedTo: "User",
34
+ name: username,
35
+ policyName,
36
+ });
33
37
  // Allow for potential non-deterministic sequencing of async events.
34
38
  await this.background.sequence();
35
39
  const user = this.users.get(username);
@@ -19,6 +19,10 @@ export interface SimIamParsedPolicyStatement {
19
19
  *
20
20
  * IAM policy JSON commonly allows either a single value or an array. The decision
21
21
  * engine should not need to care which source shape was used.
22
+ *
23
+ * A document stored without validation can hold a value of the wrong type in
24
+ * one of those fields. Parsing it reports a malformed policy naming the
25
+ * statement.
22
26
  */
23
27
  export declare class SimIamPolicyDocumentParser {
24
28
  /**
@@ -26,5 +30,4 @@ export declare class SimIamPolicyDocumentParser {
26
30
  */
27
31
  parse(policy: SimIamPolicyDocument): SimIamParsedPolicyDocument;
28
32
  private parseStatement;
29
- private stringList;
30
33
  }
@@ -1,9 +1,15 @@
1
1
  import { simIamPolicyDocumentStatements } from "../sim-iam-pol-document-statements.js";
2
+ import { simIamStatementLabel } from "../sim-iam-statement-label.js";
3
+ import { simIamStatementStrings } from "../sim-iam-statement-strings.js";
2
4
  /**
3
5
  * Parse raw IAM policy document shapes into a form convenient for evaluation.
4
6
  *
5
7
  * IAM policy JSON commonly allows either a single value or an array. The decision
6
8
  * engine should not need to care which source shape was used.
9
+ *
10
+ * A document stored without validation can hold a value of the wrong type in
11
+ * one of those fields. Parsing it reports a malformed policy naming the
12
+ * statement.
7
13
  */
8
14
  export class SimIamPolicyDocumentParser {
9
15
  /**
@@ -11,30 +17,22 @@ export class SimIamPolicyDocumentParser {
11
17
  */
12
18
  parse(policy) {
13
19
  return {
14
- statements: simIamPolicyDocumentStatements(policy).map((statement) => this.parseStatement(statement)),
20
+ statements: simIamPolicyDocumentStatements(policy).map((statement, index) => this.parseStatement(statement, index)),
15
21
  };
16
22
  }
17
- parseStatement(statement) {
23
+ parseStatement(statement, index) {
24
+ const label = simIamStatementLabel(index);
18
25
  return {
19
26
  source: statement,
20
27
  sid: statement.Sid,
21
28
  effect: statement.Effect,
22
- actions: this.stringList(statement.Action),
23
- notActions: this.stringList(statement.NotAction),
24
- resources: this.stringList(statement.Resource),
25
- notResources: this.stringList(statement.NotResource),
29
+ actions: simIamStatementStrings(statement.Action, label, "Action"),
30
+ notActions: simIamStatementStrings(statement.NotAction, label, "NotAction"),
31
+ resources: simIamStatementStrings(statement.Resource, label, "Resource"),
32
+ notResources: simIamStatementStrings(statement.NotResource, label, "NotResource"),
26
33
  principal: statement.Principal,
27
34
  notPrincipal: statement.NotPrincipal,
28
35
  condition: statement.Condition,
29
36
  };
30
37
  }
31
- stringList(value) {
32
- if (value === undefined) {
33
- return undefined;
34
- }
35
- if (typeof value === "string") {
36
- return [value];
37
- }
38
- return [...value];
39
- }
40
38
  }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * What a policy document is attached to, for naming it when one of its
3
+ * statements is rejected.
4
+ */
5
+ export interface SimIamPolicyDocumentSubject {
6
+ /**
7
+ * The kind of thing the document is attached to, such as `Role` or `Bucket`.
8
+ */
9
+ readonly attachedTo: string;
10
+ /**
11
+ * The name of the thing the document is attached to.
12
+ */
13
+ readonly name: string;
14
+ /**
15
+ * The policy's own name, for a document stored under one.
16
+ */
17
+ readonly policyName?: string | undefined;
18
+ }
19
+ /**
20
+ * Name one statement of a policy document, for a message about what is wrong
21
+ * with it.
22
+ *
23
+ * A malformed statement usually arrives from a CloudFormation template. The
24
+ * reader chasing one back needs the document it came from as well as the fault
25
+ * in it. Statements carry no names of their own. The position in the document
26
+ * stands in for one.
27
+ */
28
+ export declare function simIamStatementLabel(index: number, subject?: SimIamPolicyDocumentSubject): string;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Name one statement of a policy document, for a message about what is wrong
3
+ * with it.
4
+ *
5
+ * A malformed statement usually arrives from a CloudFormation template. The
6
+ * reader chasing one back needs the document it came from as well as the fault
7
+ * in it. Statements carry no names of their own. The position in the document
8
+ * stands in for one.
9
+ */
10
+ export function simIamStatementLabel(index, subject) {
11
+ const statement = `statement ${index + 1}`;
12
+ if (subject === undefined) {
13
+ return `IAM policy ${statement}`;
14
+ }
15
+ const policy = subject.policyName === undefined ? "" : ` policy "${subject.policyName}"`;
16
+ return `${subject.attachedTo} "${subject.name}"${policy} ${statement}`;
17
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Read a statement field holding either one string or a list of strings.
3
+ *
4
+ * Action, NotAction, Resource and NotResource each take either shape, and
5
+ * anything else is a malformed document. An unresolved CloudFormation intrinsic
6
+ * is the usual way one arrives. The IAM policy parsers store `PolicyDocument`
7
+ * whole, and a `Ref` or `Fn::GetAtt` nested inside a statement is kept as
8
+ * written. Refusing it here keeps it out of evaluation, where the same value
9
+ * surfaces as a `TypeError` naming no policy.
10
+ */
11
+ export declare function simIamStatementStrings(value: unknown, label: string, field: string): readonly string[] | undefined;
@@ -0,0 +1,27 @@
1
+ import { SimIamMalformedPolicyDocument } from "../error/sim-iam.error.js";
2
+ /**
3
+ * Read a statement field holding either one string or a list of strings.
4
+ *
5
+ * Action, NotAction, Resource and NotResource each take either shape, and
6
+ * anything else is a malformed document. An unresolved CloudFormation intrinsic
7
+ * is the usual way one arrives. The IAM policy parsers store `PolicyDocument`
8
+ * whole, and a `Ref` or `Fn::GetAtt` nested inside a statement is kept as
9
+ * written. Refusing it here keeps it out of evaluation, where the same value
10
+ * surfaces as a `TypeError` naming no policy.
11
+ */
12
+ export function simIamStatementStrings(value, label, field) {
13
+ if (value === undefined) {
14
+ return undefined;
15
+ }
16
+ if (typeof value === "string") {
17
+ return [value];
18
+ }
19
+ if (isStringArray(value)) {
20
+ return [...value];
21
+ }
22
+ throw new SimIamMalformedPolicyDocument(`${label}: ${field} must be a string or an array of strings, but holds ${JSON.stringify(value)}`);
23
+ }
24
+ function isStringArray(value) {
25
+ return (Array.isArray(value) &&
26
+ value.every((entry) => typeof entry === "string"));
27
+ }
@@ -1,5 +1,6 @@
1
1
  import { AsyncMappedFactory } from "@kensio/part-factory";
2
2
  import type { SimAws } from "../../aws/sim-aws.js";
3
+ import type { SimAwsCaller } from "../../aws/caller/sim-aws-caller.js";
3
4
  import type { SimCreateRoleCommandOutput } from "../command/role/create-role/create-role.command.js";
4
5
  /**
5
6
  * What a test asks for when it wants a Role that may do something.
@@ -13,6 +14,14 @@ export interface SimIamRoleWithPolicyInput {
13
14
  readonly policyName: string;
14
15
  readonly actions: readonly string[];
15
16
  readonly resource: string;
17
+ /**
18
+ * The principal creating the Role.
19
+ *
20
+ * A simulation given a default caller attributes these two commands to it,
21
+ * and a Role being created for that caller has no policies to allow them
22
+ * yet. Naming the Account root here is how such a test bootstraps.
23
+ */
24
+ readonly caller?: SimAwsCaller | undefined;
16
25
  }
17
26
  /**
18
27
  * The Role a CreateRole request answers with.
@@ -24,8 +24,10 @@ export const simIamRoleWithPolicyFactory = new AsyncMappedFactory(() => ({
24
24
  policyName: "ApplicationPolicy",
25
25
  actions: [],
26
26
  resource: "*",
27
+ caller: undefined,
27
28
  }), async (input, simAws) => {
28
29
  const simIam = simAws.iam();
30
+ const options = input.caller === undefined ? undefined : { caller: input.caller };
29
31
  const creation = await simIam.createRole({
30
32
  input: {
31
33
  RoleName: input.roleName,
@@ -38,7 +40,7 @@ export const simIamRoleWithPolicyFactory = new AsyncMappedFactory(() => ({
38
40
  },
39
41
  }),
40
42
  },
41
- });
43
+ }, options);
42
44
  await simIam.putRolePolicy({
43
45
  input: {
44
46
  RoleName: input.roleName,
@@ -47,6 +49,6 @@ export const simIamRoleWithPolicyFactory = new AsyncMappedFactory(() => ({
47
49
  Statement: { Action: input.actions, Resource: input.resource },
48
50
  }),
49
51
  },
50
- });
52
+ }, options);
51
53
  return creation.Role;
52
54
  });
@@ -1,6 +1,7 @@
1
1
  import { type BackgroundScheduler } from "../../util/background/background.js";
2
2
  import type { SimAwsAccountId } from "../aws/sim-aws-account.js";
3
3
  import type { SimAwsAccountRegionScope } from "../aws/sim-aws-account-region-scope.js";
4
+ import type { SimAwsDefaultCaller } from "../aws/caller/sim-aws-caller.js";
4
5
  import { SimIamAccountAuthZ } from "./authorize/sim-iam-account-auth-z.js";
5
6
  import type { SimIamInterServiceAuthZ } from "./authorize/sim-iam-inter-service-auth-z.js";
6
7
  import { SimIamCommandHandlers } from "./command/sim-iam-command-handlers.js";
@@ -19,6 +20,13 @@ export interface SimIamProperties {
19
20
  readonly credentialRegistry?: SimIamCredentialRegistry;
20
21
  readonly sessionCredentialGenerator?: SimIamSessionCredentialGenerator;
21
22
  readonly userCredentialGenerator?: SimIamUserCredentialGenerator;
23
+ /**
24
+ * The caller this simulation attributes a request naming none to.
25
+ *
26
+ * A SimAws passes on what it was built with. Left out, such a request is
27
+ * decided as the Account root, which is what a standalone SimIam does.
28
+ */
29
+ readonly defaultCaller?: SimAwsDefaultCaller | undefined;
22
30
  /**
23
31
  * Resolves the IAM of other Accounts in the same simulation.
24
32
  *
@@ -47,6 +47,7 @@ export class SimIamAccountParts {
47
47
  roles: this.roles,
48
48
  users: this.users,
49
49
  credentialIdentityResolver: credentialRegistry,
50
+ defaultCaller: properties.defaultCaller,
50
51
  iamResolver: properties.iamResolver,
51
52
  scpResolver: properties.scpResolver,
52
53
  });
@@ -1,17 +1,24 @@
1
1
  import { type JSONString } from "../../../util/type-guard/json.js";
2
2
  import type { SimIamPolicyDocument } from "../policy/sim-iam-policy.js";
3
+ import { type SimIamPolicyDocumentSubject } from "../policy/sim-iam-statement-label.js";
3
4
  /**
4
5
  * Performs basic IAM policy document validation shared by IAM policy commands.
6
+ *
7
+ * A caller can say what the document is attached to, and a rejection names it.
8
+ * Malformed documents usually arrive from a CloudFormation template, and the
9
+ * failure has to carry enough for a reader to find the template that wrote
10
+ * it.
5
11
  */
6
12
  export declare class SimIamPolicyDocumentValidator {
7
13
  /**
8
14
  * Validate a required JSON IAM policy document string.
9
15
  */
10
- validateRequired(policyDocument: string | undefined): asserts policyDocument is JSONString<SimIamPolicyDocument>;
16
+ validateRequired(policyDocument: string | undefined, subject?: SimIamPolicyDocumentSubject): asserts policyDocument is JSONString<SimIamPolicyDocument>;
11
17
  /**
12
18
  * Validate an optional JSON IAM policy document string when present.
13
19
  */
14
- validateOptional(policyDocument: string | undefined): asserts policyDocument is JSONString<SimIamPolicyDocument> | undefined;
20
+ validateOptional(policyDocument: string | undefined, subject?: SimIamPolicyDocumentSubject): asserts policyDocument is JSONString<SimIamPolicyDocument> | undefined;
15
21
  private validate;
16
22
  private validateParsed;
23
+ private validateStatement;
17
24
  }
@@ -1,45 +1,63 @@
1
1
  import { jsonParse } from "../../../util/type-guard/json.js";
2
2
  import { SimIamMalformedPolicyDocument } from "../error/sim-iam.error.js";
3
3
  import { simIamPolicyDocumentStatements } from "../policy/sim-iam-pol-document-statements.js";
4
+ import { simIamStatementLabel, } from "../policy/sim-iam-statement-label.js";
5
+ import { simIamStatementStrings } from "../policy/sim-iam-statement-strings.js";
4
6
  /**
5
7
  * Performs basic IAM policy document validation shared by IAM policy commands.
8
+ *
9
+ * A caller can say what the document is attached to, and a rejection names it.
10
+ * Malformed documents usually arrive from a CloudFormation template, and the
11
+ * failure has to carry enough for a reader to find the template that wrote
12
+ * it.
6
13
  */
7
14
  export class SimIamPolicyDocumentValidator {
8
15
  /**
9
16
  * Validate a required JSON IAM policy document string.
10
17
  */
11
- validateRequired(policyDocument) {
18
+ validateRequired(policyDocument, subject) {
12
19
  if (policyDocument === undefined || policyDocument.length === 0) {
13
20
  throw new Error("PolicyDocument is required");
14
21
  }
15
- this.validate(policyDocument);
22
+ this.validate(policyDocument, subject);
16
23
  }
17
24
  /**
18
25
  * Validate an optional JSON IAM policy document string when present.
19
26
  */
20
- validateOptional(policyDocument) {
27
+ validateOptional(policyDocument, subject) {
21
28
  if (policyDocument === undefined || policyDocument.length === 0) {
22
29
  return;
23
30
  }
24
- this.validate(policyDocument);
31
+ this.validate(policyDocument, subject);
25
32
  }
26
- validate(policyDocument) {
33
+ validate(policyDocument, subject) {
27
34
  const parsedPolicyDocument = jsonParse(policyDocument);
28
- this.validateParsed(parsedPolicyDocument);
35
+ this.validateParsed(parsedPolicyDocument, subject);
29
36
  }
30
- validateParsed(policyDocument) {
31
- for (const statement of simIamPolicyDocumentStatements(policyDocument)) {
32
- // oxlint-disable-next-line typescript/no-unnecessary-condition
33
- if (statement.Effect !== "Allow" && statement.Effect !== "Deny") {
34
- throw new SimIamMalformedPolicyDocument('IAM policy statement Effect must be either "Allow" or "Deny"');
35
- }
36
- if (statement.Action === undefined && statement.NotAction === undefined) {
37
- throw new SimIamMalformedPolicyDocument("IAM policy statement must define either Action or NotAction");
38
- }
39
- if (statement.Resource === undefined &&
40
- statement.NotResource === undefined) {
41
- throw new SimIamMalformedPolicyDocument("IAM policy statement must define either Resource or NotResource");
42
- }
37
+ validateParsed(policyDocument, subject) {
38
+ const statements = simIamPolicyDocumentStatements(policyDocument);
39
+ for (const [index, statement] of statements.entries()) {
40
+ this.validateStatement(statement, simIamStatementLabel(index, subject));
43
41
  }
44
42
  }
43
+ validateStatement(statement, label) {
44
+ // oxlint-disable-next-line typescript/no-unnecessary-condition
45
+ if (statement.Effect !== "Allow" && statement.Effect !== "Deny") {
46
+ throw new SimIamMalformedPolicyDocument(`${label}: Effect must be either "Allow" or "Deny"`);
47
+ }
48
+ if (statement.Action === undefined && statement.NotAction === undefined) {
49
+ throw new SimIamMalformedPolicyDocument(`${label}: must define either Action or NotAction`);
50
+ }
51
+ if (statement.Resource === undefined &&
52
+ statement.NotResource === undefined) {
53
+ throw new SimIamMalformedPolicyDocument(`${label}: must define either Resource or NotResource`);
54
+ }
55
+ // Read for the types alone. A field of the wrong type throws while the
56
+ // document is still beside the call that wrote it. Left to the first
57
+ // authorization, the same fault names no policy at all.
58
+ simIamStatementStrings(statement.Action, label, "Action");
59
+ simIamStatementStrings(statement.NotAction, label, "NotAction");
60
+ simIamStatementStrings(statement.Resource, label, "Resource");
61
+ simIamStatementStrings(statement.NotResource, label, "NotResource");
62
+ }
45
63
  }
@@ -2,6 +2,7 @@ import { MappedFactory } from "@kensio/part-factory";
2
2
  import type { SimAwsAccountRegionScope } from "../../../aws/sim-aws-account-region-scope.js";
3
3
  import { SimLambdaFunction } from "../sim-lambda-function.js";
4
4
  import { type LambdaCodeZipFiles } from "./make-lambda-code-zip.js";
5
+ import type { SimLambdaVmSdkModuleProvider } from "./vm/sdk/sim-lambda-vm-sdk-module-provider.js";
5
6
  /**
6
7
  * What a test asks for when it wants a function backed by zip code running in
7
8
  * a vm sandbox.
@@ -16,6 +17,12 @@ export interface SimLambdaVmZipFunctionInput {
16
17
  readonly code: string | LambdaCodeZipFiles;
17
18
  readonly handlerName: string;
18
19
  readonly memorySizeMb: number;
20
+ /**
21
+ * What provides the modules the archive does not bundle, as the real
22
+ * runtime provides the AWS SDK. Left out, the code has none, and an SDK
23
+ * require is refused for want of one.
24
+ */
25
+ readonly sdkModuleProvider?: SimLambdaVmSdkModuleProvider | undefined;
19
26
  }
20
27
  /**
21
28
  * Builds a simulated Lambda function whose code is a real zip archive run in a
@@ -39,6 +39,7 @@ export const simLambdaVmZipFunctionFactory = new MappedFactory(() => ({
39
39
  archive,
40
40
  handlerName: input.handlerName,
41
41
  environment,
42
+ sdkModuleProvider: input.sdkModuleProvider,
42
43
  }),
43
44
  });
44
45
  });
@@ -0,0 +1,19 @@
1
+ import type { SimZipArchive } from "../../../../../../util/zip/zip-archive.js";
2
+ import type { SimLambdaVmSdkModuleProvider } from "./sim-lambda-vm-sdk-module-provider.js";
3
+ /**
4
+ * What the archive holds and who provides for what it does not. Between them
5
+ * that is enough to tell an absent package from one already accounted for.
6
+ */
7
+ interface SimLambdaMissingSdkPackagesContext {
8
+ readonly archive: SimZipArchive;
9
+ readonly sdkModuleProvider: SimLambdaVmSdkModuleProvider;
10
+ }
11
+ /**
12
+ * The module the runtime provides for a specifier the archive does not
13
+ * bundle, or undefined for a specifier the provider does not serve.
14
+ *
15
+ * A package the project has not installed is refused here naming every other
16
+ * AWS SDK package the function code imports and the project is missing too.
17
+ */
18
+ export declare function provideSdkModule(specifier: string, context: SimLambdaMissingSdkPackagesContext): unknown;
19
+ export {};