@kensio/yulin 1.20.12 → 1.20.13

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 (132) hide show
  1. package/dist/service/acm/command/delete-certificate/delete-certificate-authorizer.js +1 -0
  2. package/dist/service/acm/command/describe-certificate/describe-certificate-authorizer.js +1 -0
  3. package/dist/service/acm/command/list-certificates/list-certificates-authorizer.js +1 -0
  4. package/dist/service/acm/command/request-certificate/request-certificate-authorizer.js +1 -0
  5. package/dist/service/apigateway/serve/auth/sim-rest-api-authorizer-policy.js +3 -0
  6. package/dist/service/apigatewayv2/serve/auth/sim-http-api-authorizer-policy.js +3 -0
  7. package/dist/service/aws/factory/sim-aws-account-service-cache.d.ts +3 -0
  8. package/dist/service/aws/factory/sim-aws-account-service-cache.js +5 -0
  9. package/dist/service/aws/factory/sim-aws-service-factory.d.ts +9 -0
  10. package/dist/service/aws/factory/sim-aws-service-factory.js +10 -0
  11. package/dist/service/aws/sim-aws.d.ts +18 -0
  12. package/dist/service/aws/sim-aws.js +19 -0
  13. package/dist/service/cloudformation/resource/cfn/organizations/sim-organizations-cfn-value-adapter.d.ts +6 -0
  14. package/dist/service/cloudformation/resource/cfn/organizations/sim-organizations-cfn-value-adapter.js +23 -0
  15. package/dist/service/cloudformation/resource/cfn/organizations/sim-organizations-cfn.d.ts +66 -0
  16. package/dist/service/cloudformation/resource/cfn/organizations/sim-organizations-cfn.js +136 -0
  17. package/dist/service/cloudformation/resource/cfn/sim-cfn-service-value-adapters.js +2 -0
  18. package/dist/service/cloudformation/resource/resolve/service/sim-cfn-service-factories.js +7 -0
  19. package/dist/service/cloudfront/command/create-distribution/create-distribution-authorizer.js +1 -0
  20. package/dist/service/cloudfront/command/create-function/create-function-authorizer.js +1 -0
  21. package/dist/service/cloudfront/command/delete-distribution/delete-distribution-authorizer.js +1 -0
  22. package/dist/service/cloudfront/command/delete-function/delete-function-authorizer.js +1 -0
  23. package/dist/service/cloudfront/command/get-distribution/get-distribution-authorizer.js +1 -0
  24. package/dist/service/cloudfront/command/update-distribution/update-distribution-authorizer.js +1 -0
  25. package/dist/service/cloudfront/edge/sim-cf-edge-association-auth-z.js +1 -0
  26. package/dist/service/cloudfront/key-value-store/sim-cf-key-value-store-access.js +1 -0
  27. package/dist/service/cloudwatch/command/authorize/sim-cloudwatch-decide.js +1 -0
  28. package/dist/service/cognito/command/authorize/sim-cognito-authorizer.js +1 -0
  29. package/dist/service/dynamodb/command/authorize/sim-dynamodb-authorizer.js +1 -0
  30. package/dist/service/firehose/command/authorize/sim-firehose-authorizer.js +1 -0
  31. package/dist/service/glue/command/authorize/sim-glue-authorize-resources.js +1 -0
  32. package/dist/service/iam/authorize/allow/sim-iam-policy-evaluation.d.ts +45 -0
  33. package/dist/service/iam/authorize/allow/sim-iam-policy-evaluation.js +59 -0
  34. package/dist/service/iam/authorize/context/sim-iam-auth-z-context-builder.d.ts +15 -4
  35. package/dist/service/iam/authorize/context/sim-iam-auth-z-context-builder.js +15 -4
  36. package/dist/service/iam/authorize/context/sim-iam-auth-z-context.d.ts +31 -1
  37. package/dist/service/iam/authorize/context/sim-iam-auth-z-context.factory.js +1 -0
  38. package/dist/service/iam/authorize/context/sim-iam-auth-z-scp-source-builder.d.ts +46 -0
  39. package/dist/service/iam/authorize/context/sim-iam-auth-z-scp-source-builder.js +71 -0
  40. package/dist/service/iam/authorize/scp/sim-iam-scp-gate.d.ts +96 -0
  41. package/dist/service/iam/authorize/scp/sim-iam-scp-gate.js +148 -0
  42. package/dist/service/iam/authorize/scp/sim-iam-scp-resolver.d.ts +53 -0
  43. package/dist/service/iam/authorize/scp/sim-iam-scp-resolver.js +1 -0
  44. package/dist/service/iam/authorize/sim-iam-account-auth-z.d.ts +8 -0
  45. package/dist/service/iam/authorize/sim-iam-account-auth-z.js +1 -0
  46. package/dist/service/iam/authorize/sim-iam-action-authorizer.js +1 -0
  47. package/dist/service/iam/authorize/sim-iam-authorizer.d.ts +2 -0
  48. package/dist/service/iam/authorize/sim-iam-authorizer.js +1 -0
  49. package/dist/service/iam/authorize/sim-iam-decision-value.d.ts +13 -0
  50. package/dist/service/iam/authorize/sim-iam-decision-value.js +12 -0
  51. package/dist/service/iam/authorize/sim-iam-decision.d.ts +33 -16
  52. package/dist/service/iam/authorize/sim-iam-decision.js +64 -49
  53. package/dist/service/iam/authorize/sim-iam-inter-service-auth-z.d.ts +8 -0
  54. package/dist/service/iam/authorize/sim-iam-inter-service-auth-z.js +1 -0
  55. package/dist/service/iam/error/sim-iam.error.d.ts +8 -0
  56. package/dist/service/iam/error/sim-iam.error.js +2 -1
  57. package/dist/service/iam/sim-iam-account-parts.d.ts +9 -0
  58. package/dist/service/iam/sim-iam-account-parts.js +1 -0
  59. package/dist/service/kinesis/command/authorize/sim-kinesis-authorizer.js +1 -0
  60. package/dist/service/kms/command/authorize/sim-kms-authorizer.js +2 -0
  61. package/dist/service/lambda/command/create-function/create-function-authorizer.js +1 -0
  62. package/dist/service/lambda/command/delete-function/delete-function-authorizer.js +1 -0
  63. package/dist/service/lambda/command/event-invoke-config/event-invoke-config-authorizer.js +1 -0
  64. package/dist/service/lambda/command/function-url/function-url-authorizer.js +1 -0
  65. package/dist/service/lambda/command/get-function/get-function-authorizer.js +1 -0
  66. package/dist/service/lambda/command/invoke/invoke-authorizer.js +1 -0
  67. package/dist/service/lambda/command/list-functions/list-functions-authorizer.js +1 -0
  68. package/dist/service/lambda/command/update-function-code/update-function-code-authorizer.js +1 -0
  69. package/dist/service/lambda/command/update-function-configuration/update-function-configuration-authorizer.js +1 -0
  70. package/dist/service/lambda/command/version/version-authorizer.js +1 -0
  71. package/dist/service/logs/command/authorize/sim-logs-authorizer.js +1 -0
  72. package/dist/service/organizations/cfn/sim-cfn-organization-creator.d.ts +19 -0
  73. package/dist/service/organizations/cfn/sim-cfn-organization-creator.js +25 -0
  74. package/dist/service/organizations/cfn/sim-cfn-organizational-unit-creator.d.ts +16 -0
  75. package/dist/service/organizations/cfn/sim-cfn-organizational-unit-creator.js +21 -0
  76. package/dist/service/organizations/cfn/sim-cfn-organizations-account-creator.d.ts +20 -0
  77. package/dist/service/organizations/cfn/sim-cfn-organizations-account-creator.js +34 -0
  78. package/dist/service/organizations/cfn/sim-cfn-organizations-policy-creator.d.ts +21 -0
  79. package/dist/service/organizations/cfn/sim-cfn-organizations-policy-creator.js +40 -0
  80. package/dist/service/organizations/cfn/sim-cfn-organizations-policy-input.d.ts +20 -0
  81. package/dist/service/organizations/cfn/sim-cfn-organizations-policy-input.js +33 -0
  82. package/dist/service/organizations/cfn/sim-cfn-organizations-properties.d.ts +36 -0
  83. package/dist/service/organizations/cfn/sim-cfn-organizations-properties.js +78 -0
  84. package/dist/service/organizations/cfn/sim-cfn-organizations-record.d.ts +40 -0
  85. package/dist/service/organizations/cfn/sim-cfn-organizations-record.js +54 -0
  86. package/dist/service/organizations/cfn/sim-cfn-organizations-remover.d.ts +17 -0
  87. package/dist/service/organizations/cfn/sim-cfn-organizations-remover.js +40 -0
  88. package/dist/service/organizations/cfn/sim-organizations-cfn-resource-factory.d.ts +24 -0
  89. package/dist/service/organizations/cfn/sim-organizations-cfn-resource-factory.js +50 -0
  90. package/dist/service/organizations/index.d.ts +6 -0
  91. package/dist/service/organizations/index.js +6 -0
  92. package/dist/service/organizations/policy/sim-organizations-effective-policies.d.ts +43 -0
  93. package/dist/service/organizations/policy/sim-organizations-effective-policies.js +58 -0
  94. package/dist/service/organizations/policy/sim-organizations-scp-store.d.ts +61 -0
  95. package/dist/service/organizations/policy/sim-organizations-scp-store.js +103 -0
  96. package/dist/service/organizations/sim-organizations-structure.d.ts +94 -0
  97. package/dist/service/organizations/sim-organizations-structure.js +140 -0
  98. package/dist/service/organizations/sim-organizations.d.ts +95 -0
  99. package/dist/service/organizations/sim-organizations.js +99 -0
  100. package/dist/service/organizations/tree/sim-organizations-node.d.ts +57 -0
  101. package/dist/service/organizations/tree/sim-organizations-node.js +58 -0
  102. package/dist/service/organizations/tree/sim-organizations-tree.d.ts +91 -0
  103. package/dist/service/organizations/tree/sim-organizations-tree.js +154 -0
  104. package/dist/service/route53/command/change-resource-record-sets/change-resource-record-sets-authorizer.js +1 -0
  105. package/dist/service/route53/command/create-hosted-zone/create-hosted-zone-authorizer.js +1 -0
  106. package/dist/service/route53/command/delete-hosted-zone/delete-hosted-zone-authorizer.js +1 -0
  107. package/dist/service/route53/command/dnssec/sim-route53-dnssec-authorizer.js +1 -0
  108. package/dist/service/route53/command/get-hosted-zone/get-hosted-zone-authorizer.js +1 -0
  109. package/dist/service/route53/command/list-hosted-zones-by-name/list-hosted-zones-by-name-authorizer.js +1 -0
  110. package/dist/service/route53/command/list-resource-record-sets/list-resource-record-sets-authorizer.js +1 -0
  111. package/dist/service/s3/command/create-bucket/create-bucket.handler.js +1 -0
  112. package/dist/service/s3/command/delete-bucket/delete-bucket-authorizer.js +1 -0
  113. package/dist/service/s3/command/delete-bucket-policy/delete-bucket-policy-authorizer.js +1 -0
  114. package/dist/service/s3/command/delete-object/delete-object-authorizer.js +1 -0
  115. package/dist/service/s3/command/get-bucket-policy/get-bucket-policy-authorizer.js +1 -0
  116. package/dist/service/s3/command/get-object/get-object-authorizer.js +1 -0
  117. package/dist/service/s3/command/head-bucket/head-bucket-authorizer.js +1 -0
  118. package/dist/service/s3/command/lifecycle/sim-s3-lifecycle-authorizer.js +1 -0
  119. package/dist/service/s3/command/list-buckets/list-buckets-authorizer.js +1 -0
  120. package/dist/service/s3/command/list-objects/list-objects-authorizer.js +1 -0
  121. package/dist/service/s3/command/multipart/sim-s3-multipart-authorizer.js +1 -0
  122. package/dist/service/s3/command/notification/sim-s3-notification-authorizer.js +1 -0
  123. package/dist/service/s3/command/public-access-block/sim-s3-public-access-block-authorizer.js +1 -0
  124. package/dist/service/s3/command/put-bucket-policy/put-bucket-policy-authorizer.js +1 -0
  125. package/dist/service/s3/command/put-bucket-website/put-bucket-website-authorizer.js +1 -0
  126. package/dist/service/s3/command/put-object/put-object-authorizer.js +1 -0
  127. package/dist/service/secretsmanager/command/authorize/sim-secrets-manager-authorizer.js +1 -0
  128. package/dist/service/ses/command/authorize/sim-ses-authorizer.js +1 -0
  129. package/dist/service/sqs/command/authorize/sim-sqs-authorizer.js +1 -0
  130. package/dist/service/ssm/command/authorize/sim-ssm-authorizer.js +1 -0
  131. package/dist/service/wafv2/command/authorize/sim-wafv2-authorizer.js +1 -0
  132. package/package.json +5 -1
@@ -0,0 +1,45 @@
1
+ import type { SimIamPolicyDocumentStatement } from "../../policy/sim-iam-policy.js";
2
+ import type { SimIamPolicyDocumentParser } from "../../policy/parse/sim-iam-document-parser.js";
3
+ import type { SimIamPolicyStatementMatcher } from "../match/sim-iam-policy-statement-matcher.js";
4
+ import type { SimIamAuthZPolicySource } from "../context/sim-iam-auth-z-context.js";
5
+ import { SimIamAllowStatements } from "./sim-iam-allow-statements.js";
6
+ import type { SimIamAllowSides } from "./sim-iam-allow-requirement.js";
7
+ interface SimIamPolicyEvaluationProperties {
8
+ readonly policies: readonly SimIamAuthZPolicySource[];
9
+ readonly policyDocumentParser: SimIamPolicyDocumentParser;
10
+ readonly statementMatcher: SimIamPolicyStatementMatcher;
11
+ }
12
+ /**
13
+ * The statements of the identity and resource policies that matched one
14
+ * request.
15
+ *
16
+ * These are the two sides that can allow a request, so they are read together
17
+ * and kept apart by side afterwards. Which of them has to allow for the
18
+ * request to go ahead belongs to the allow requirement rather than here.
19
+ */
20
+ export declare class SimIamPolicyEvaluation {
21
+ private readonly explicitDenyStatementRecords;
22
+ private readonly allows;
23
+ constructor(properties: SimIamPolicyEvaluationProperties);
24
+ /**
25
+ * Whether a matching Deny statement was found.
26
+ */
27
+ get isExplicitDeny(): boolean;
28
+ /**
29
+ * Matching explicit Deny statements.
30
+ */
31
+ get explicitDenyStatements(): readonly SimIamPolicyDocumentStatement[];
32
+ /**
33
+ * The matching Allow statements, kept per side.
34
+ */
35
+ get allowStatements(): SimIamAllowStatements;
36
+ /**
37
+ * Which sides produced a matching Allow.
38
+ */
39
+ get sides(): SimIamAllowSides;
40
+ /**
41
+ * Record the matching statements of one policy.
42
+ */
43
+ private evaluate;
44
+ }
45
+ export {};
@@ -0,0 +1,59 @@
1
+ import { SimIamAllowStatements } from "./sim-iam-allow-statements.js";
2
+ /**
3
+ * The statements of the identity and resource policies that matched one
4
+ * request.
5
+ *
6
+ * These are the two sides that can allow a request, so they are read together
7
+ * and kept apart by side afterwards. Which of them has to allow for the
8
+ * request to go ahead belongs to the allow requirement rather than here.
9
+ */
10
+ export class SimIamPolicyEvaluation {
11
+ explicitDenyStatementRecords = [];
12
+ allows = new SimIamAllowStatements();
13
+ constructor(properties) {
14
+ for (const policy of properties.policies) {
15
+ this.evaluate(policy, properties);
16
+ }
17
+ }
18
+ /**
19
+ * Whether a matching Deny statement was found.
20
+ */
21
+ get isExplicitDeny() {
22
+ return this.explicitDenyStatementRecords.length > 0;
23
+ }
24
+ /**
25
+ * Matching explicit Deny statements.
26
+ */
27
+ get explicitDenyStatements() {
28
+ return this.explicitDenyStatementRecords;
29
+ }
30
+ /**
31
+ * The matching Allow statements, kept per side.
32
+ */
33
+ get allowStatements() {
34
+ return this.allows;
35
+ }
36
+ /**
37
+ * Which sides produced a matching Allow.
38
+ */
39
+ get sides() {
40
+ return this.allows.sides;
41
+ }
42
+ /**
43
+ * Record the matching statements of one policy.
44
+ */
45
+ evaluate(policy, properties) {
46
+ const parsedPolicy = properties.policyDocumentParser.parse(policy.document);
47
+ for (const statement of parsedPolicy.statements) {
48
+ const principal = properties.statementMatcher.matches(policy, statement);
49
+ if (!principal.matched) {
50
+ continue;
51
+ }
52
+ if (statement.effect === "Deny") {
53
+ this.explicitDenyStatementRecords.push(statement.source);
54
+ continue;
55
+ }
56
+ this.allows.record(policy, statement.source, principal);
57
+ }
58
+ }
59
+ }
@@ -8,6 +8,7 @@ import type { SimIamCallerConditionSource } from "./sim-iam-caller-condition-sou
8
8
  import type { SimIamAuthZContext, SimIamAuthZPolicySource, SimIamAuthZPolicySourceType } from "./sim-iam-auth-z-context.js";
9
9
  import type { SimAwsCredentialIdentityResolver } from "../../../aws/caller/sim-aws-caller-resolver.js";
10
10
  import type { SimIamUser, SimIamUsername } from "../../user/sim-iam-user.js";
11
+ import type { SimIamServiceControlPolicyResolver } from "../scp/sim-iam-scp-resolver.js";
11
12
  export interface SimIamResourcePolicyInput {
12
13
  readonly document: SimIamPolicyDocument;
13
14
  readonly sourceType?: Extract<SimIamAuthZPolicySourceType, "resource" | "trust">;
@@ -77,6 +78,11 @@ interface SimIamAuthZContextBuilderProperties {
77
78
  * of a cross-Account request.
78
79
  */
79
80
  readonly iamResolver?: SimIamAccountResolver | undefined;
81
+ /**
82
+ * Resolves the service control policies in force for an Account. A
83
+ * standalone SimIam has no organization around it and leaves this out.
84
+ */
85
+ readonly scpResolver?: SimIamServiceControlPolicyResolver | undefined;
80
86
  }
81
87
  /**
82
88
  * Builds the authorization context consumed by SimIamAuthorizer.
@@ -99,16 +105,21 @@ interface SimIamAuthZContextBuilderProperties {
99
105
  * They are passed through the authorization input rather than loaded from the
100
106
  * IAM role or managed-policy stores.
101
107
  *
102
- * Permissions boundaries, session policies, SCPs, and role trust-policy
103
- * assume-role semantics are not part of this context assembly path yet. Add
104
- * those concerns through separate policy-source builders so this class stays
105
- * focused on composing the authorization request.
108
+ * Service control policies come from the organization the caller's Account
109
+ * belongs to, read by SimIamAuthZScpSourceBuilder. They filter and grant
110
+ * nothing, so they travel apart from the sides that can allow a request.
111
+ *
112
+ * Permissions boundaries, session policies, and role trust-policy assume-role
113
+ * semantics are not part of this context assembly path yet. Add those concerns
114
+ * through separate policy-source builders so this class stays focused on
115
+ * composing the authorization request.
106
116
  */
107
117
  export declare class SimIamAuthZContextBuilder {
108
118
  private readonly callerContextBuilder;
109
119
  private readonly identityPolicyCoordinator;
110
120
  private readonly callerAccountResolver;
111
121
  private readonly allowRequirement;
122
+ private readonly scpSourceBuilder;
112
123
  constructor(properties: SimIamAuthZContextBuilderProperties);
113
124
  /**
114
125
  * Build the context consumed by SimIamAuthorizer.
@@ -3,6 +3,7 @@ import { SimIamCallerAccountResolver } from "../caller-account/sim-iam-caller-ac
3
3
  import { SimIamAuthZAllowRequirement } from "./sim-iam-auth-z-allow-requirement.js";
4
4
  import { SimIamAuthZIdentityPolicyCoordinator } from "./identity-policy-source/sim-iam-auth-z-id-pol-coordinator.js";
5
5
  import { SimIamAuthZCallerContextBuilder, } from "./sim-iam-auth-z-caller-context-builder.js";
6
+ import { SimIamAuthZScpSourceBuilder } from "./sim-iam-auth-z-scp-source-builder.js";
6
7
  /**
7
8
  * Builds the authorization context consumed by SimIamAuthorizer.
8
9
  *
@@ -24,16 +25,21 @@ import { SimIamAuthZCallerContextBuilder, } from "./sim-iam-auth-z-caller-contex
24
25
  * They are passed through the authorization input rather than loaded from the
25
26
  * IAM role or managed-policy stores.
26
27
  *
27
- * Permissions boundaries, session policies, SCPs, and role trust-policy
28
- * assume-role semantics are not part of this context assembly path yet. Add
29
- * those concerns through separate policy-source builders so this class stays
30
- * focused on composing the authorization request.
28
+ * Service control policies come from the organization the caller's Account
29
+ * belongs to, read by SimIamAuthZScpSourceBuilder. They filter and grant
30
+ * nothing, so they travel apart from the sides that can allow a request.
31
+ *
32
+ * Permissions boundaries, session policies, and role trust-policy assume-role
33
+ * semantics are not part of this context assembly path yet. Add those concerns
34
+ * through separate policy-source builders so this class stays focused on
35
+ * composing the authorization request.
31
36
  */
32
37
  export class SimIamAuthZContextBuilder {
33
38
  callerContextBuilder;
34
39
  identityPolicyCoordinator;
35
40
  callerAccountResolver;
36
41
  allowRequirement = new SimIamAuthZAllowRequirement();
42
+ scpSourceBuilder;
37
43
  constructor(properties) {
38
44
  this.callerContextBuilder = new SimIamAuthZCallerContextBuilder(makeSimAwsAccountRootPrincipal(properties.accountId), properties.credentialIdentityResolver);
39
45
  this.identityPolicyCoordinator = new SimIamAuthZIdentityPolicyCoordinator({
@@ -45,6 +51,10 @@ export class SimIamAuthZContextBuilder {
45
51
  accountId: properties.accountId,
46
52
  iamResolver: properties.iamResolver,
47
53
  });
54
+ this.scpSourceBuilder = new SimIamAuthZScpSourceBuilder({
55
+ accountId: properties.accountId,
56
+ scpResolver: properties.scpResolver,
57
+ });
48
58
  }
49
59
  /**
50
60
  * Build the context consumed by SimIamAuthorizer.
@@ -58,6 +68,7 @@ export class SimIamAuthZContextBuilder {
58
68
  ...callerAccount.identityPolicies,
59
69
  ],
60
70
  resourcePolicies: this.resourcePolicySources(input),
71
+ serviceControlPolicies: this.scpSourceBuilder.build(callerContext.caller),
61
72
  allowRequirement: this.allowRequirement.resolve(callerAccount, input.requiresResourcePolicyAllow),
62
73
  action: input.action,
63
74
  resource: input.resource,
@@ -2,7 +2,7 @@ import type { SimArn } from "../../../aws/arn.js";
2
2
  import type { SimIamConditionValue, SimIamPolicyDocument } from "../../policy/sim-iam-policy.js";
3
3
  import type { SimAwsResolvedCaller } from "../../../aws/caller/sim-aws-caller-resolver.js";
4
4
  import type { SimIamAllowRequirement } from "../allow/sim-iam-allow-requirement.js";
5
- export type SimIamAuthZPolicySourceType = "identity-inline" | "identity-managed" | "resource" | "trust" | "permissions-boundary" | "session";
5
+ export type SimIamAuthZPolicySourceType = "identity-inline" | "identity-managed" | "resource" | "trust" | "permissions-boundary" | "session" | "service-control";
6
6
  export interface SimIamAuthZPolicySource {
7
7
  readonly sourceType: SimIamAuthZPolicySourceType;
8
8
  readonly document: SimIamPolicyDocument;
@@ -16,6 +16,29 @@ export interface SimIamAuthZPolicySource {
16
16
  export type SimIamAuthZResourcePolicySource = Omit<SimIamAuthZPolicySource, "sourceType"> & {
17
17
  readonly sourceType: Extract<SimIamAuthZPolicySourceType, "resource" | "trust">;
18
18
  };
19
+ /**
20
+ * The service control policies attached at one level above the caller's
21
+ * Account, which is the root, an organizational unit, or the Account itself.
22
+ *
23
+ * Each level has to allow the action on its own. A level allowing nothing
24
+ * denies the request whatever another level allows, which is why the sources
25
+ * stay grouped rather than being read as one list.
26
+ */
27
+ export interface SimIamAuthZServiceControlPolicyLevel {
28
+ readonly nodeName: string;
29
+ readonly sources: readonly SimIamAuthZPolicySource[];
30
+ }
31
+ /**
32
+ * The service control policies in force for an authorization request.
33
+ *
34
+ * `applies` is a separate fact from how many levels there are. An Account
35
+ * inside an organization holding no policy allows nothing, while an Account
36
+ * outside every organization is unrestricted, and both can carry no levels.
37
+ */
38
+ export interface SimIamAuthZServiceControlPolicies {
39
+ readonly applies: boolean;
40
+ readonly levels: readonly SimIamAuthZServiceControlPolicyLevel[];
41
+ }
19
42
  export interface SimIamAuthZContext {
20
43
  /**
21
44
  * Identity-based policies that grant permissions to the principal.
@@ -29,6 +52,13 @@ export interface SimIamAuthZContext {
29
52
  * Resource policies are not gathered from IAM's managed policy store.
30
53
  */
31
54
  readonly resourcePolicies: readonly SimIamAuthZPolicySource[];
55
+ /**
56
+ * Service control policies in force for the caller's Account.
57
+ *
58
+ * These filter what the Account's principals may do and grant nothing, so
59
+ * they are kept apart from the two sides that can allow a request.
60
+ */
61
+ readonly serviceControlPolicies: SimIamAuthZServiceControlPolicies;
32
62
  /**
33
63
  * How an Allow from each policy side combines into the final decision.
34
64
  *
@@ -6,6 +6,7 @@ import { SimIamEitherSideAllowRequirement } from "../allow/sim-iam-allow-require
6
6
  export const simIamAuthZContextFactory = new StaticFactory({
7
7
  identityPolicies: [],
8
8
  resourcePolicies: [],
9
+ serviceControlPolicies: { applies: false, levels: [] },
9
10
  allowRequirement: new SimIamEitherSideAllowRequirement(),
10
11
  action: "s3:GetObject",
11
12
  resource: "arn:aws:s3:::test-bucket/test-key",
@@ -0,0 +1,46 @@
1
+ import type { SimAwsAccountId } from "../../../aws/sim-aws-account.js";
2
+ import type { SimAwsResolvedCaller } from "../../../aws/caller/sim-aws-caller-resolver.js";
3
+ import type { SimIamServiceControlPolicyResolver } from "../scp/sim-iam-scp-resolver.js";
4
+ import type { SimIamAuthZServiceControlPolicies } from "./sim-iam-auth-z-context.js";
5
+ interface SimIamAuthZScpSourceBuilderProperties {
6
+ /**
7
+ * The Account whose IAM is evaluating the request.
8
+ */
9
+ readonly accountId: SimAwsAccountId;
10
+ readonly scpResolver?: SimIamServiceControlPolicyResolver | undefined;
11
+ }
12
+ /**
13
+ * Finds the service control policies that apply to one request.
14
+ *
15
+ * An SCP belongs to the caller's own Account, which is the Account whose
16
+ * principal is asking. For a request within one Account that is the Account
17
+ * evaluating it. For a cross-Account request it is the other one, because AWS
18
+ * filters a principal by the organization its own account sits in and leaves
19
+ * the resource's organization to say nothing about it.
20
+ *
21
+ * A caller with no Account in its ARN, which means a service principal or an
22
+ * anonymous request, belongs to no Account and is subject to no SCP.
23
+ */
24
+ export declare class SimIamAuthZScpSourceBuilder {
25
+ /**
26
+ * What a caller no organization reaches is subject to.
27
+ */
28
+ private static readonly unrestricted;
29
+ private readonly accountId;
30
+ private readonly scpResolver?;
31
+ constructor(properties: SimIamAuthZScpSourceBuilderProperties);
32
+ /**
33
+ * The service control policies in force for a resolved caller.
34
+ */
35
+ build(caller: SimAwsResolvedCaller): SimIamAuthZServiceControlPolicies;
36
+ /**
37
+ * The Account whose organization decides this request.
38
+ *
39
+ * A caller identified only by a service name or by nothing at all has no
40
+ * Account of its own. The Account root fallback IAM applies to a request
41
+ * with no caller carries this Account's id, so a CloudFormation deployment
42
+ * is filtered like any other principal in it.
43
+ */
44
+ private callerAccountId;
45
+ }
46
+ export {};
@@ -0,0 +1,71 @@
1
+ import { isSimAwsAccountId } from "../../../aws/sim-aws-account.js";
2
+ /**
3
+ * Finds the service control policies that apply to one request.
4
+ *
5
+ * An SCP belongs to the caller's own Account, which is the Account whose
6
+ * principal is asking. For a request within one Account that is the Account
7
+ * evaluating it. For a cross-Account request it is the other one, because AWS
8
+ * filters a principal by the organization its own account sits in and leaves
9
+ * the resource's organization to say nothing about it.
10
+ *
11
+ * A caller with no Account in its ARN, which means a service principal or an
12
+ * anonymous request, belongs to no Account and is subject to no SCP.
13
+ */
14
+ export class SimIamAuthZScpSourceBuilder {
15
+ /**
16
+ * What a caller no organization reaches is subject to.
17
+ */
18
+ static unrestricted = {
19
+ applies: false,
20
+ levels: [],
21
+ };
22
+ accountId;
23
+ scpResolver;
24
+ constructor(properties) {
25
+ this.accountId = properties.accountId;
26
+ this.scpResolver = properties.scpResolver;
27
+ }
28
+ /**
29
+ * The service control policies in force for a resolved caller.
30
+ */
31
+ build(caller) {
32
+ const scpResolver = this.scpResolver;
33
+ if (scpResolver === undefined) {
34
+ return SimIamAuthZScpSourceBuilder.unrestricted;
35
+ }
36
+ const accountId = this.callerAccountId(caller);
37
+ if (accountId === undefined) {
38
+ return SimIamAuthZScpSourceBuilder.unrestricted;
39
+ }
40
+ const set = scpResolver.serviceControlPolicySetFor(accountId);
41
+ return {
42
+ applies: set.applies,
43
+ levels: set.levels.map((level) => ({
44
+ nodeName: level.nodeName,
45
+ sources: level.policies.map((policy) => ({
46
+ sourceType: "service-control",
47
+ document: policy.document,
48
+ policyName: policy.policyName,
49
+ })),
50
+ })),
51
+ };
52
+ }
53
+ /**
54
+ * The Account whose organization decides this request.
55
+ *
56
+ * A caller identified only by a service name or by nothing at all has no
57
+ * Account of its own. The Account root fallback IAM applies to a request
58
+ * with no caller carries this Account's id, so a CloudFormation deployment
59
+ * is filtered like any other principal in it.
60
+ */
61
+ callerAccountId(caller) {
62
+ if (caller.principal.kind === "anonymous" || caller.service !== undefined) {
63
+ return undefined;
64
+ }
65
+ const callerAccountId = caller.accountId;
66
+ if (callerAccountId === undefined) {
67
+ return this.accountId;
68
+ }
69
+ return isSimAwsAccountId(callerAccountId) ? callerAccountId : undefined;
70
+ }
71
+ }
@@ -0,0 +1,96 @@
1
+ import type { SimIamPolicyDocumentStatement } from "../../policy/sim-iam-policy.js";
2
+ import type { SimIamPolicyDocumentParser } from "../../policy/parse/sim-iam-document-parser.js";
3
+ import type { SimIamPolicyStatementMatcher } from "../match/sim-iam-policy-statement-matcher.js";
4
+ import type { SimIamAuthZServiceControlPolicies } from "../context/sim-iam-auth-z-context.js";
5
+ import { SimIamPolicyDecisionValue } from "../sim-iam-decision-value.js";
6
+ interface SimIamScpGateProperties {
7
+ readonly serviceControlPolicies: SimIamAuthZServiceControlPolicies;
8
+ readonly policyDocumentParser: SimIamPolicyDocumentParser;
9
+ readonly statementMatcher: SimIamPolicyStatementMatcher;
10
+ }
11
+ /**
12
+ * What an Account's service control policies say about one request.
13
+ *
14
+ * An SCP is a filter on the permissions an Account's principals can be given.
15
+ * It grants nothing, so this runs as a gate in front of the identity and
16
+ * resource policy evaluation instead of contributing Allows to it. The rules
17
+ * are the ones AWS applies at the Account boundary:
18
+ *
19
+ * - a matching Deny at any level ends the request;
20
+ * - every level between the root and the Account has to produce a matching
21
+ * Allow of its own.
22
+ *
23
+ * The second rule is what makes the levels worth keeping apart. A root
24
+ * allowing S3 and an organizational unit allowing DynamoDB leave an Account
25
+ * beneath them able to do neither, because each level is asked separately.
26
+ *
27
+ * An Account outside any organization's reach is unrestricted, and this gate
28
+ * stands open for it. An Account inside one that holds no policy is a
29
+ * different case: nothing allows it anything, so the gate is shut.
30
+ */
31
+ export declare class SimIamScpGate {
32
+ private readonly applies;
33
+ private readonly denyStatementRecords;
34
+ private readonly allowStatementRecords;
35
+ private readonly unallowedLevelNames;
36
+ constructor(properties: SimIamScpGateProperties);
37
+ /**
38
+ * Whether any service control policy applied to this request at all.
39
+ */
40
+ get isApplied(): boolean;
41
+ /**
42
+ * Whether an attached policy explicitly denied the request.
43
+ */
44
+ get isExplicitDeny(): boolean;
45
+ /**
46
+ * Whether a level left the request unallowed.
47
+ *
48
+ * A Deny is reported by `isExplicitDeny` and leaves this false, so the two
49
+ * name different denials and a reader can tell them apart.
50
+ */
51
+ get isImplicitDeny(): boolean;
52
+ /**
53
+ * Whether the service control policies denied the request either way.
54
+ */
55
+ get isDenied(): boolean;
56
+ /**
57
+ * The decision this gate forces, where it forces one.
58
+ *
59
+ * Undefined leaves the request to the identity and resource policies, which
60
+ * is what an open gate means.
61
+ */
62
+ get value(): SimIamPolicyDecisionValue | undefined;
63
+ /**
64
+ * Matching Deny statements from the attached policies.
65
+ */
66
+ get denyStatements(): readonly SimIamPolicyDocumentStatement[];
67
+ /**
68
+ * Matching Allow statements from the attached policies, across every level.
69
+ */
70
+ get allowStatements(): readonly SimIamPolicyDocumentStatement[];
71
+ /**
72
+ * The levels that allowed nothing matching the request, root first.
73
+ *
74
+ * This is what a test reads to find which node in the organization is in the
75
+ * way, which is the part of an SCP denial AWS makes hardest to work out.
76
+ */
77
+ get unallowedLevels(): readonly string[];
78
+ /**
79
+ * How an AWS error explains this denial, if this gate is what denied it.
80
+ *
81
+ * The wording follows the AccessDenied messages AWS returns for the two
82
+ * cases, so a test asserting on the message reads what it would in a real
83
+ * account.
84
+ */
85
+ denialReason(action: string): string | undefined;
86
+ /**
87
+ * Record what one level of the organization said.
88
+ */
89
+ private evaluateLevel;
90
+ /**
91
+ * Record the matching statements of one attached policy, and say whether it
92
+ * allowed the request.
93
+ */
94
+ private evaluatePolicy;
95
+ }
96
+ export {};
@@ -0,0 +1,148 @@
1
+ import { SimIamPolicyDecisionValue } from "../sim-iam-decision-value.js";
2
+ /**
3
+ * What an Account's service control policies say about one request.
4
+ *
5
+ * An SCP is a filter on the permissions an Account's principals can be given.
6
+ * It grants nothing, so this runs as a gate in front of the identity and
7
+ * resource policy evaluation instead of contributing Allows to it. The rules
8
+ * are the ones AWS applies at the Account boundary:
9
+ *
10
+ * - a matching Deny at any level ends the request;
11
+ * - every level between the root and the Account has to produce a matching
12
+ * Allow of its own.
13
+ *
14
+ * The second rule is what makes the levels worth keeping apart. A root
15
+ * allowing S3 and an organizational unit allowing DynamoDB leave an Account
16
+ * beneath them able to do neither, because each level is asked separately.
17
+ *
18
+ * An Account outside any organization's reach is unrestricted, and this gate
19
+ * stands open for it. An Account inside one that holds no policy is a
20
+ * different case: nothing allows it anything, so the gate is shut.
21
+ */
22
+ export class SimIamScpGate {
23
+ applies;
24
+ denyStatementRecords = [];
25
+ allowStatementRecords = [];
26
+ unallowedLevelNames = [];
27
+ constructor(properties) {
28
+ this.applies = properties.serviceControlPolicies.applies;
29
+ for (const level of properties.serviceControlPolicies.levels) {
30
+ this.evaluateLevel(level, properties);
31
+ }
32
+ if (this.applies && properties.serviceControlPolicies.levels.length === 0) {
33
+ this.unallowedLevelNames.push("the organization");
34
+ }
35
+ }
36
+ /**
37
+ * Whether any service control policy applied to this request at all.
38
+ */
39
+ get isApplied() {
40
+ return this.applies;
41
+ }
42
+ /**
43
+ * Whether an attached policy explicitly denied the request.
44
+ */
45
+ get isExplicitDeny() {
46
+ return this.denyStatementRecords.length > 0;
47
+ }
48
+ /**
49
+ * Whether a level left the request unallowed.
50
+ *
51
+ * A Deny is reported by `isExplicitDeny` and leaves this false, so the two
52
+ * name different denials and a reader can tell them apart.
53
+ */
54
+ get isImplicitDeny() {
55
+ return (this.applies &&
56
+ !this.isExplicitDeny &&
57
+ this.unallowedLevelNames.length > 0);
58
+ }
59
+ /**
60
+ * Whether the service control policies denied the request either way.
61
+ */
62
+ get isDenied() {
63
+ return this.isExplicitDeny || this.isImplicitDeny;
64
+ }
65
+ /**
66
+ * The decision this gate forces, where it forces one.
67
+ *
68
+ * Undefined leaves the request to the identity and resource policies, which
69
+ * is what an open gate means.
70
+ */
71
+ get value() {
72
+ if (this.isExplicitDeny) {
73
+ return SimIamPolicyDecisionValue.ExplicitDeny;
74
+ }
75
+ return this.isImplicitDeny
76
+ ? SimIamPolicyDecisionValue.ImplicitDeny
77
+ : undefined;
78
+ }
79
+ /**
80
+ * Matching Deny statements from the attached policies.
81
+ */
82
+ get denyStatements() {
83
+ return this.denyStatementRecords;
84
+ }
85
+ /**
86
+ * Matching Allow statements from the attached policies, across every level.
87
+ */
88
+ get allowStatements() {
89
+ return this.allowStatementRecords;
90
+ }
91
+ /**
92
+ * The levels that allowed nothing matching the request, root first.
93
+ *
94
+ * This is what a test reads to find which node in the organization is in the
95
+ * way, which is the part of an SCP denial AWS makes hardest to work out.
96
+ */
97
+ get unallowedLevels() {
98
+ return this.unallowedLevelNames;
99
+ }
100
+ /**
101
+ * How an AWS error explains this denial, if this gate is what denied it.
102
+ *
103
+ * The wording follows the AccessDenied messages AWS returns for the two
104
+ * cases, so a test asserting on the message reads what it would in a real
105
+ * account.
106
+ */
107
+ denialReason(action) {
108
+ if (this.isExplicitDeny) {
109
+ return "with an explicit deny in a service control policy";
110
+ }
111
+ if (this.isImplicitDeny) {
112
+ return `because no service control policy allows the ${action} action`;
113
+ }
114
+ return undefined;
115
+ }
116
+ /**
117
+ * Record what one level of the organization said.
118
+ */
119
+ evaluateLevel(level, properties) {
120
+ let allowed = false;
121
+ for (const policy of level.sources) {
122
+ allowed = this.evaluatePolicy(policy, properties) || allowed;
123
+ }
124
+ if (!allowed) {
125
+ this.unallowedLevelNames.push(level.nodeName);
126
+ }
127
+ }
128
+ /**
129
+ * Record the matching statements of one attached policy, and say whether it
130
+ * allowed the request.
131
+ */
132
+ evaluatePolicy(policy, properties) {
133
+ const parsedPolicy = properties.policyDocumentParser.parse(policy.document);
134
+ let allowed = false;
135
+ for (const statement of parsedPolicy.statements) {
136
+ if (!properties.statementMatcher.matches(policy, statement).matched) {
137
+ continue;
138
+ }
139
+ if (statement.effect === "Deny") {
140
+ this.denyStatementRecords.push(statement.source);
141
+ continue;
142
+ }
143
+ this.allowStatementRecords.push(statement.source);
144
+ allowed = true;
145
+ }
146
+ return allowed;
147
+ }
148
+ }