@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,58 @@
1
+ /**
2
+ * Works out which service control policies an Account is actually subject to.
3
+ *
4
+ * The tree says which nodes lie above an Account and the store says what hangs
5
+ * on each of them. Putting the two together is the whole of what sim IAM asks
6
+ * an organization, so it lives here rather than in the facade.
7
+ */
8
+ export class SimOrganizationsEffectivePolicies {
9
+ tree;
10
+ scpStore;
11
+ managementAccountId;
12
+ constructor(properties) {
13
+ this.tree = properties.tree;
14
+ this.scpStore = properties.scpStore;
15
+ }
16
+ /**
17
+ * Name the Account AWS exempts from every service control policy.
18
+ */
19
+ setManagementAccount(accountId) {
20
+ this.managementAccountId = accountId;
21
+ }
22
+ /**
23
+ * The policies in force for an Account, level by level, root first.
24
+ */
25
+ setFor(accountId) {
26
+ if (accountId === this.managementAccountId) {
27
+ return { applies: false, levels: [] };
28
+ }
29
+ const path = this.pathFor(accountId);
30
+ if (path.length === 0) {
31
+ return { applies: false, levels: [] };
32
+ }
33
+ return { applies: true, levels: path.map((node) => this.levelAt(node)) };
34
+ }
35
+ /**
36
+ * The nodes filtering an Account's requests.
37
+ *
38
+ * An Account placed in the organization is filtered by the path down to it.
39
+ * An Account only ever named by having a policy attached to it is filtered
40
+ * by that policy alone, which is what attaching to an Account meant before
41
+ * the organization had a shape.
42
+ */
43
+ pathFor(accountId) {
44
+ if (this.tree.holds(accountId)) {
45
+ return this.tree.pathTo(accountId);
46
+ }
47
+ return this.scpStore.holds(accountId) ? [accountId] : [];
48
+ }
49
+ /**
50
+ * What one node contributes to an Account's decision.
51
+ */
52
+ levelAt(nodeId) {
53
+ return {
54
+ nodeName: this.tree.nameOf(nodeId),
55
+ policies: this.scpStore.policiesAt(nodeId),
56
+ };
57
+ }
58
+ }
@@ -0,0 +1,61 @@
1
+ import type { SimIamServiceControlPolicy } from "../../iam/authorize/scp/sim-iam-scp-resolver.js";
2
+ import type { SimIamPolicyDocument } from "../../iam/policy/sim-iam-policy.js";
3
+ import type { SimOrganizationsNodeId } from "../tree/sim-organizations-node.js";
4
+ /**
5
+ * The AWS-managed policy attached to every organization node by default.
6
+ *
7
+ * Turning service control policies on in an organization leaves every
8
+ * account's permissions as they were, because this policy comes with them. A
9
+ * simulated node gets the same treatment, so attaching one Deny statement
10
+ * denies that one action and leaves the rest working.
11
+ */
12
+ export declare const SIM_ORGANIZATIONS_FULL_AWS_ACCESS: SimIamServiceControlPolicy;
13
+ /**
14
+ * The service control policies attached to each node of an organization.
15
+ *
16
+ * A node holds FullAWSAccess along with whatever was attached to it, until a
17
+ * test detaches FullAWSAccess to write an allow list at that node. A node
18
+ * nothing was attached to still holds FullAWSAccess, so an organizational unit
19
+ * a test never mentions allows everything through it.
20
+ */
21
+ export declare class SimOrganizationsScpStore {
22
+ private readonly byNodeId;
23
+ /**
24
+ * Attach a service control policy to a node under an id of its own.
25
+ *
26
+ * The id is what takes the policy off again. One policy attached to several
27
+ * nodes carries the same id at each of them, the way an AWS policy attached
28
+ * to several targets is one policy.
29
+ */
30
+ attach(nodeId: SimOrganizationsNodeId, policyId: string, document: SimIamPolicyDocument, policyName?: string): void;
31
+ /**
32
+ * Take one service control policy off a node, leaving the rest.
33
+ *
34
+ * A node can hold policies from more than one source, so taking the wrong
35
+ * ones off would change what an Account may do behind the caller's back.
36
+ */
37
+ detach(nodeId: SimOrganizationsNodeId, policyId: string): void;
38
+ /**
39
+ * Take the AWS-managed FullAWSAccess policy off a node.
40
+ *
41
+ * What remains at that node has to allow an action for a request through it
42
+ * to go ahead, which is how a level is turned into an allow list.
43
+ */
44
+ detachFullAwsAccess(nodeId: SimOrganizationsNodeId): void;
45
+ /**
46
+ * Put a node back to holding FullAWSAccess and nothing else.
47
+ */
48
+ detachAll(nodeId: SimOrganizationsNodeId): void;
49
+ /**
50
+ * The policies in force at one node, FullAWSAccess first.
51
+ */
52
+ policiesAt(nodeId: SimOrganizationsNodeId): readonly SimIamServiceControlPolicy[];
53
+ /**
54
+ * Whether anything has been attached to or detached from a node.
55
+ */
56
+ holds(nodeId: SimOrganizationsNodeId): boolean;
57
+ /**
58
+ * The record for a node, created on first use.
59
+ */
60
+ private nodePolicies;
61
+ }
@@ -0,0 +1,103 @@
1
+ /**
2
+ * The AWS-managed policy attached to every organization node by default.
3
+ *
4
+ * Turning service control policies on in an organization leaves every
5
+ * account's permissions as they were, because this policy comes with them. A
6
+ * simulated node gets the same treatment, so attaching one Deny statement
7
+ * denies that one action and leaves the rest working.
8
+ */
9
+ export const SIM_ORGANIZATIONS_FULL_AWS_ACCESS = {
10
+ policyName: "FullAWSAccess",
11
+ document: {
12
+ Version: "2012-10-17",
13
+ Statement: { Effect: "Allow", Action: "*", Resource: "*" },
14
+ },
15
+ };
16
+ /**
17
+ * The service control policies attached to each node of an organization.
18
+ *
19
+ * A node holds FullAWSAccess along with whatever was attached to it, until a
20
+ * test detaches FullAWSAccess to write an allow list at that node. A node
21
+ * nothing was attached to still holds FullAWSAccess, so an organizational unit
22
+ * a test never mentions allows everything through it.
23
+ */
24
+ export class SimOrganizationsScpStore {
25
+ byNodeId = new Map();
26
+ /**
27
+ * Attach a service control policy to a node under an id of its own.
28
+ *
29
+ * The id is what takes the policy off again. One policy attached to several
30
+ * nodes carries the same id at each of them, the way an AWS policy attached
31
+ * to several targets is one policy.
32
+ */
33
+ attach(nodeId, policyId, document, policyName) {
34
+ this.nodePolicies(nodeId).attached.push({
35
+ policyId,
36
+ policy: { document, policyName },
37
+ });
38
+ }
39
+ /**
40
+ * Take one service control policy off a node, leaving the rest.
41
+ *
42
+ * A node can hold policies from more than one source, so taking the wrong
43
+ * ones off would change what an Account may do behind the caller's back.
44
+ */
45
+ detach(nodeId, policyId) {
46
+ const node = this.byNodeId.get(nodeId);
47
+ if (node === undefined) {
48
+ return;
49
+ }
50
+ const remaining = node.attached.filter((attached) => attached.policyId !== policyId);
51
+ node.attached.length = 0;
52
+ node.attached.push(...remaining);
53
+ }
54
+ /**
55
+ * Take the AWS-managed FullAWSAccess policy off a node.
56
+ *
57
+ * What remains at that node has to allow an action for a request through it
58
+ * to go ahead, which is how a level is turned into an allow list.
59
+ */
60
+ detachFullAwsAccess(nodeId) {
61
+ this.nodePolicies(nodeId).fullAwsAccess = false;
62
+ }
63
+ /**
64
+ * Put a node back to holding FullAWSAccess and nothing else.
65
+ */
66
+ detachAll(nodeId) {
67
+ this.byNodeId.delete(nodeId);
68
+ }
69
+ /**
70
+ * The policies in force at one node, FullAWSAccess first.
71
+ */
72
+ policiesAt(nodeId) {
73
+ const node = this.byNodeId.get(nodeId);
74
+ if (node === undefined) {
75
+ return [SIM_ORGANIZATIONS_FULL_AWS_ACCESS];
76
+ }
77
+ const attached = node.attached.map((entry) => entry.policy);
78
+ return node.fullAwsAccess
79
+ ? [SIM_ORGANIZATIONS_FULL_AWS_ACCESS, ...attached]
80
+ : attached;
81
+ }
82
+ /**
83
+ * Whether anything has been attached to or detached from a node.
84
+ */
85
+ holds(nodeId) {
86
+ return this.byNodeId.has(nodeId);
87
+ }
88
+ /**
89
+ * The record for a node, created on first use.
90
+ */
91
+ nodePolicies(nodeId) {
92
+ const existing = this.byNodeId.get(nodeId);
93
+ if (existing !== undefined) {
94
+ return existing;
95
+ }
96
+ const created = {
97
+ attached: [],
98
+ fullAwsAccess: true,
99
+ };
100
+ this.byNodeId.set(nodeId, created);
101
+ return created;
102
+ }
103
+ }
@@ -0,0 +1,94 @@
1
+ import { SimOrganizationsEffectivePolicies } from "./policy/sim-organizations-effective-policies.js";
2
+ import { SimOrganizationsScpStore } from "./policy/sim-organizations-scp-store.js";
3
+ import { type SimOrganizationsNodeId, type SimOrganizationsOrganizationalUnit, type SimOrganizationsRoot, type SimOrganizationsTarget } from "./tree/sim-organizations-node.js";
4
+ import { SimOrganizationsTree } from "./tree/sim-organizations-tree.js";
5
+ /**
6
+ * The shape of one simulated organization: its root, the organizational units
7
+ * under it, and where its Accounts sit.
8
+ *
9
+ * SimOrganizations is the facade a test reaches through, and this is the half
10
+ * of it concerned with structure. The policies that hang on that structure are
11
+ * the other half.
12
+ */
13
+ export declare abstract class SimOrganizationsStructure {
14
+ protected readonly scpStore: SimOrganizationsScpStore;
15
+ protected readonly tree: SimOrganizationsTree;
16
+ protected readonly effectivePolicies: SimOrganizationsEffectivePolicies;
17
+ /**
18
+ * The root of this organization, which every Account sits under.
19
+ */
20
+ root(): SimOrganizationsRoot;
21
+ /**
22
+ * Create an organizational unit, under the root unless a parent unit is
23
+ * given.
24
+ */
25
+ createOrganizationalUnit(name: string, parent?: SimOrganizationsTarget): SimOrganizationsOrganizationalUnit;
26
+ /**
27
+ * Put an Account in the organization, under an organizational unit or under
28
+ * the root.
29
+ */
30
+ moveAccount(accountId: string, parent?: SimOrganizationsTarget): void;
31
+ /**
32
+ * Name the Account that pays the organization's bills.
33
+ *
34
+ * AWS exempts the management account from every service control policy, and
35
+ * so does this. An Account named here is decided by its identity and
36
+ * resource policies alone, whatever is attached above it.
37
+ */
38
+ setManagementAccount(accountId: string): void;
39
+ /**
40
+ * Every Account this organization holds.
41
+ *
42
+ * A test tracking down where a denial came from reads this to see which
43
+ * Accounts the organization is filtering at all.
44
+ */
45
+ accountIds(): readonly string[];
46
+ /**
47
+ * Take an Account out of the organization.
48
+ *
49
+ * Nothing then filters its requests, whatever is attached above where it
50
+ * sat. This is how an Account leaves an organization, and it is a different
51
+ * thing from taking the policies off it.
52
+ */
53
+ removeAccount(accountId: string): void;
54
+ /**
55
+ * Take an organizational unit out of the organization.
56
+ *
57
+ * Anything still under it moves up to its parent, so every Account keeps a
58
+ * path back to the root.
59
+ */
60
+ removeOrganizationalUnit(target: SimOrganizationsTarget): void;
61
+ /**
62
+ * The node a target names.
63
+ *
64
+ * An Account is named by its twelve-digit id and needs no place in the
65
+ * organization yet, because attaching a policy to one is what puts it there.
66
+ * A root or organizational unit, whether given as a handle or as the `r-` or
67
+ * `ou-` id a template carries, has to be this organization's own. One from
68
+ * another organization is refused rather than attached to and never read.
69
+ */
70
+ protected nodeIdOf(target: SimOrganizationsTarget): SimOrganizationsNodeId;
71
+ /**
72
+ * Refuse the whole set unless every target names a node this organization
73
+ * has.
74
+ *
75
+ * Attaching one policy to several nodes is one act, so it either reaches all
76
+ * of them or none. Failing partway would leave a policy attached where
77
+ * nothing knows to take it off.
78
+ */
79
+ requireTargets(targets: readonly SimOrganizationsTarget[]): void;
80
+ /**
81
+ * The node a target names, or nothing where this organization has no such
82
+ * node.
83
+ *
84
+ * Taking something off a node that has already gone is what a Stack teardown
85
+ * asks for when a unit came down before the policy pointing at it. There is
86
+ * nothing to take off, and refusing would fail a teardown over work already
87
+ * done.
88
+ */
89
+ protected knownNodeIdOf(target: SimOrganizationsTarget): SimOrganizationsNodeId | undefined;
90
+ /**
91
+ * The node something sits under, defaulting to the root.
92
+ */
93
+ private parentIdOf;
94
+ }
@@ -0,0 +1,140 @@
1
+ import { simAwsAccountId } from "../aws/sim-aws-account.js";
2
+ import { SimOrganizationsEffectivePolicies } from "./policy/sim-organizations-effective-policies.js";
3
+ import { SimOrganizationsScpStore } from "./policy/sim-organizations-scp-store.js";
4
+ import { isSimOrganizationsUnitId, } from "./tree/sim-organizations-node.js";
5
+ import { SimOrganizationsTree } from "./tree/sim-organizations-tree.js";
6
+ /**
7
+ * The shape of one simulated organization: its root, the organizational units
8
+ * under it, and where its Accounts sit.
9
+ *
10
+ * SimOrganizations is the facade a test reaches through, and this is the half
11
+ * of it concerned with structure. The policies that hang on that structure are
12
+ * the other half.
13
+ */
14
+ export class SimOrganizationsStructure {
15
+ scpStore = new SimOrganizationsScpStore();
16
+ tree = new SimOrganizationsTree();
17
+ effectivePolicies = new SimOrganizationsEffectivePolicies({
18
+ tree: this.tree,
19
+ scpStore: this.scpStore,
20
+ });
21
+ /**
22
+ * The root of this organization, which every Account sits under.
23
+ */
24
+ root() {
25
+ return this.tree.root;
26
+ }
27
+ /**
28
+ * Create an organizational unit, under the root unless a parent unit is
29
+ * given.
30
+ */
31
+ createOrganizationalUnit(name, parent) {
32
+ return this.tree.createOrganizationalUnit(name, this.parentIdOf(parent));
33
+ }
34
+ /**
35
+ * Put an Account in the organization, under an organizational unit or under
36
+ * the root.
37
+ */
38
+ moveAccount(accountId, parent) {
39
+ this.tree.placeAccount(simAwsAccountId(accountId), this.parentIdOf(parent));
40
+ }
41
+ /**
42
+ * Name the Account that pays the organization's bills.
43
+ *
44
+ * AWS exempts the management account from every service control policy, and
45
+ * so does this. An Account named here is decided by its identity and
46
+ * resource policies alone, whatever is attached above it.
47
+ */
48
+ setManagementAccount(accountId) {
49
+ const account = simAwsAccountId(accountId);
50
+ this.effectivePolicies.setManagementAccount(account);
51
+ this.tree.placeAccount(account);
52
+ }
53
+ /**
54
+ * Every Account this organization holds.
55
+ *
56
+ * A test tracking down where a denial came from reads this to see which
57
+ * Accounts the organization is filtering at all.
58
+ */
59
+ accountIds() {
60
+ return this.tree.accountIds();
61
+ }
62
+ /**
63
+ * Take an Account out of the organization.
64
+ *
65
+ * Nothing then filters its requests, whatever is attached above where it
66
+ * sat. This is how an Account leaves an organization, and it is a different
67
+ * thing from taking the policies off it.
68
+ */
69
+ removeAccount(accountId) {
70
+ this.tree.removeAccount(simAwsAccountId(accountId));
71
+ }
72
+ /**
73
+ * Take an organizational unit out of the organization.
74
+ *
75
+ * Anything still under it moves up to its parent, so every Account keeps a
76
+ * path back to the root.
77
+ */
78
+ removeOrganizationalUnit(target) {
79
+ const nodeId = this.knownNodeIdOf(target);
80
+ if (nodeId !== undefined) {
81
+ this.tree.removeOrganizationalUnit(nodeId);
82
+ }
83
+ }
84
+ /**
85
+ * The node a target names.
86
+ *
87
+ * An Account is named by its twelve-digit id and needs no place in the
88
+ * organization yet, because attaching a policy to one is what puts it there.
89
+ * A root or organizational unit, whether given as a handle or as the `r-` or
90
+ * `ou-` id a template carries, has to be this organization's own. One from
91
+ * another organization is refused rather than attached to and never read.
92
+ */
93
+ nodeIdOf(target) {
94
+ if (typeof target !== "string") {
95
+ this.tree.requireNode(target.id);
96
+ return target.id;
97
+ }
98
+ if (!isSimOrganizationsUnitId(target)) {
99
+ return simAwsAccountId(target);
100
+ }
101
+ const nodeId = target;
102
+ this.tree.requireNode(nodeId);
103
+ return nodeId;
104
+ }
105
+ /**
106
+ * Refuse the whole set unless every target names a node this organization
107
+ * has.
108
+ *
109
+ * Attaching one policy to several nodes is one act, so it either reaches all
110
+ * of them or none. Failing partway would leave a policy attached where
111
+ * nothing knows to take it off.
112
+ */
113
+ requireTargets(targets) {
114
+ for (const target of targets) {
115
+ this.nodeIdOf(target);
116
+ }
117
+ }
118
+ /**
119
+ * The node a target names, or nothing where this organization has no such
120
+ * node.
121
+ *
122
+ * Taking something off a node that has already gone is what a Stack teardown
123
+ * asks for when a unit came down before the policy pointing at it. There is
124
+ * nothing to take off, and refusing would fail a teardown over work already
125
+ * done.
126
+ */
127
+ knownNodeIdOf(target) {
128
+ if (typeof target === "string" && !isSimOrganizationsUnitId(target)) {
129
+ return simAwsAccountId(target);
130
+ }
131
+ const nodeId = (typeof target === "string" ? target : target.id);
132
+ return this.tree.hasNode(nodeId) ? nodeId : undefined;
133
+ }
134
+ /**
135
+ * The node something sits under, defaulting to the root.
136
+ */
137
+ parentIdOf(parent) {
138
+ return parent === undefined ? undefined : this.nodeIdOf(parent);
139
+ }
140
+ }
@@ -0,0 +1,95 @@
1
+ import { type SimAwsAccountId } from "../aws/sim-aws-account.js";
2
+ import type { SimIamPolicyDocument } from "../iam/policy/sim-iam-policy.js";
3
+ import type { SimIamServiceControlPolicy, SimIamServiceControlPolicyResolver, SimIamServiceControlPolicySet } from "../iam/authorize/scp/sim-iam-scp-resolver.js";
4
+ import { SimOrganizationsStructure } from "./sim-organizations-structure.js";
5
+ import { type SimOrganizationsTarget } from "./tree/sim-organizations-node.js";
6
+ /**
7
+ * Options for one attached service control policy.
8
+ */
9
+ export interface SimOrganizationsAttachOptions {
10
+ /**
11
+ * What to call the policy in a denial. Defaults to `ServiceControlPolicy`.
12
+ */
13
+ readonly policyName?: string | undefined;
14
+ /**
15
+ * The id to attach the policy under, for taking it off again later.
16
+ *
17
+ * One policy attached to several nodes takes the same id at each of them.
18
+ * Defaults to an id of this attachment's own.
19
+ */
20
+ readonly policyId?: string | undefined;
21
+ }
22
+ /**
23
+ * Simulated AWS Organizations, holding the organization structure and the
24
+ * service control policies that decide what its Accounts may do.
25
+ *
26
+ * An organization spans Accounts, so one of these belongs to a SimAws rather
27
+ * than to an Account scope, and it is reached as `simAws.organizations()`.
28
+ *
29
+ * A service control policy filters permissions and grants none. Every level
30
+ * between the root and an Account has to allow an action for the Account to be
31
+ * allowed it, and a Deny at any level ends the request whatever else allows
32
+ * it. That applies to the Account root as well as to its Roles and Users, so
33
+ * it catches a CloudFormation deployment and an intercepted SDK call alike.
34
+ *
35
+ * The root, the organizational units and where the Accounts sit come from
36
+ * SimOrganizationsStructure, which this extends.
37
+ */
38
+ export declare class SimOrganizations extends SimOrganizationsStructure implements SimIamServiceControlPolicyResolver {
39
+ /**
40
+ * Attach a service control policy to the root, an organizational unit, or an
41
+ * Account.
42
+ *
43
+ * The node also holds AWS's own FullAWSAccess policy, as it would in a real
44
+ * organization, so one Deny statement denies that action and leaves the rest
45
+ * of the node's Accounts working.
46
+ */
47
+ attachServiceControlPolicy(target: SimOrganizationsTarget, document: SimIamPolicyDocument, options?: SimOrganizationsAttachOptions): string;
48
+ /**
49
+ * Take one service control policy off a node, leaving whatever else is
50
+ * attached there.
51
+ *
52
+ * This is what a CloudFormation teardown uses, because a node can hold
53
+ * policies from more than one Stack and clearing it would take another
54
+ * Stack's guardrail away.
55
+ */
56
+ detachServiceControlPolicy(target: SimOrganizationsTarget, policyId: string): void;
57
+ /**
58
+ * Take AWS's FullAWSAccess policy off a node, leaving only the policies
59
+ * attached to it to allow anything through that level.
60
+ *
61
+ * This turns the node into an allow list. An action no policy attached there
62
+ * allows is denied for every Account beneath it.
63
+ */
64
+ detachFullAwsAccess(target: SimOrganizationsTarget): void;
65
+ /**
66
+ * Remove every service control policy attached to a node.
67
+ *
68
+ * Only that node is cleared. An Account sitting in an organizational unit
69
+ * goes on inheriting what the levels above it say, as it does in AWS, where
70
+ * detaching a policy from an account leaves the account where it is. Take an
71
+ * Account out of the organization with `removeAccount`.
72
+ *
73
+ * A node that has already gone leaves nothing to take off, so this does
74
+ * nothing rather than refusing. A Stack teardown reaches that case whenever
75
+ * a unit came down before the policy pointing at it.
76
+ */
77
+ detachServiceControlPolicies(target: SimOrganizationsTarget): void;
78
+ /**
79
+ * The service control policies in force for an Account, root level first.
80
+ *
81
+ * This flattens the levels, so it says what was evaluated without saying
82
+ * which level each policy came from. `serviceControlPolicySetFor` keeps that
83
+ * apart, and a denial needs it, because a level allowing nothing denies the
84
+ * Account whatever another level allows.
85
+ */
86
+ serviceControlPoliciesFor(accountId: SimAwsAccountId | string): readonly SimIamServiceControlPolicy[];
87
+ /**
88
+ * The policies in force for an Account, level by level, along with whether
89
+ * the Account is inside this organization at all.
90
+ *
91
+ * Sim IAM reads this rather than the flattened list, because each level has
92
+ * to allow an action on its own.
93
+ */
94
+ serviceControlPolicySetFor(accountId: SimAwsAccountId | string): SimIamServiceControlPolicySet;
95
+ }
@@ -0,0 +1,99 @@
1
+ import { simAwsAccountId, } from "../aws/sim-aws-account.js";
2
+ import { SimOrganizationsStructure } from "./sim-organizations-structure.js";
3
+ import { makeSimOrganizationsPolicyId, } from "./tree/sim-organizations-node.js";
4
+ /**
5
+ * Simulated AWS Organizations, holding the organization structure and the
6
+ * service control policies that decide what its Accounts may do.
7
+ *
8
+ * An organization spans Accounts, so one of these belongs to a SimAws rather
9
+ * than to an Account scope, and it is reached as `simAws.organizations()`.
10
+ *
11
+ * A service control policy filters permissions and grants none. Every level
12
+ * between the root and an Account has to allow an action for the Account to be
13
+ * allowed it, and a Deny at any level ends the request whatever else allows
14
+ * it. That applies to the Account root as well as to its Roles and Users, so
15
+ * it catches a CloudFormation deployment and an intercepted SDK call alike.
16
+ *
17
+ * The root, the organizational units and where the Accounts sit come from
18
+ * SimOrganizationsStructure, which this extends.
19
+ */
20
+ export class SimOrganizations extends SimOrganizationsStructure {
21
+ /**
22
+ * Attach a service control policy to the root, an organizational unit, or an
23
+ * Account.
24
+ *
25
+ * The node also holds AWS's own FullAWSAccess policy, as it would in a real
26
+ * organization, so one Deny statement denies that action and leaves the rest
27
+ * of the node's Accounts working.
28
+ */
29
+ attachServiceControlPolicy(target, document, options = {}) {
30
+ const policyName = options.policyName ?? "ServiceControlPolicy";
31
+ const policyId = options.policyId ?? makeSimOrganizationsPolicyId();
32
+ this.scpStore.attach(this.nodeIdOf(target), policyId, document, policyName);
33
+ return policyId;
34
+ }
35
+ /**
36
+ * Take one service control policy off a node, leaving whatever else is
37
+ * attached there.
38
+ *
39
+ * This is what a CloudFormation teardown uses, because a node can hold
40
+ * policies from more than one Stack and clearing it would take another
41
+ * Stack's guardrail away.
42
+ */
43
+ detachServiceControlPolicy(target, policyId) {
44
+ const nodeId = this.knownNodeIdOf(target);
45
+ if (nodeId !== undefined) {
46
+ this.scpStore.detach(nodeId, policyId);
47
+ }
48
+ }
49
+ /**
50
+ * Take AWS's FullAWSAccess policy off a node, leaving only the policies
51
+ * attached to it to allow anything through that level.
52
+ *
53
+ * This turns the node into an allow list. An action no policy attached there
54
+ * allows is denied for every Account beneath it.
55
+ */
56
+ detachFullAwsAccess(target) {
57
+ this.scpStore.detachFullAwsAccess(this.nodeIdOf(target));
58
+ }
59
+ /**
60
+ * Remove every service control policy attached to a node.
61
+ *
62
+ * Only that node is cleared. An Account sitting in an organizational unit
63
+ * goes on inheriting what the levels above it say, as it does in AWS, where
64
+ * detaching a policy from an account leaves the account where it is. Take an
65
+ * Account out of the organization with `removeAccount`.
66
+ *
67
+ * A node that has already gone leaves nothing to take off, so this does
68
+ * nothing rather than refusing. A Stack teardown reaches that case whenever
69
+ * a unit came down before the policy pointing at it.
70
+ */
71
+ detachServiceControlPolicies(target) {
72
+ const nodeId = this.knownNodeIdOf(target);
73
+ if (nodeId !== undefined) {
74
+ this.scpStore.detachAll(nodeId);
75
+ }
76
+ }
77
+ /**
78
+ * The service control policies in force for an Account, root level first.
79
+ *
80
+ * This flattens the levels, so it says what was evaluated without saying
81
+ * which level each policy came from. `serviceControlPolicySetFor` keeps that
82
+ * apart, and a denial needs it, because a level allowing nothing denies the
83
+ * Account whatever another level allows.
84
+ */
85
+ serviceControlPoliciesFor(accountId) {
86
+ const set = this.serviceControlPolicySetFor(accountId);
87
+ return set.levels.flatMap((level) => level.policies);
88
+ }
89
+ /**
90
+ * The policies in force for an Account, level by level, along with whether
91
+ * the Account is inside this organization at all.
92
+ *
93
+ * Sim IAM reads this rather than the flattened list, because each level has
94
+ * to allow an action on its own.
95
+ */
96
+ serviceControlPolicySetFor(accountId) {
97
+ return this.effectivePolicies.setFor(simAwsAccountId(accountId));
98
+ }
99
+ }