@guardian/cdk 64.7.0 → 65.0.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,35 @@
1
1
  # @guardian/cdk
2
2
 
3
+ ## 65.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - a0ec968: BREAKING CHANGE: `GuDeveloperPolicyExperimental` has been promoted to stable and renamed `GuDeveloperPolicy`
8
+
9
+ Example usage:
10
+
11
+ ```ts
12
+ // Before
13
+ import { GuDeveloperPolicyExperimental } from "@guardian/cdk/lib/experimental/constructs/iam/policies";
14
+ new GuDeveloperPolicyExperimental(this, "ExampleDeveloperPolicy", {
15
+ grantId: "ExamplePolicy",
16
+ friendlyName: "An example policy",
17
+ statements: [
18
+ /* ... */
19
+ ],
20
+ });
21
+
22
+ // After
23
+ import { GuDeveloperPolicy } from "@guardian/cdk/iam/policies";
24
+ new GuDeveloperPolicy(this, "ExampleDeveloperPolicy", {
25
+ grantId: "ExamplePolicy",
26
+ friendlyName: "An example policy",
27
+ statements: [
28
+ /* ... */
29
+ ],
30
+ });
31
+ ```
32
+
3
33
  ## 64.7.0
4
34
 
5
35
  ### Minor Changes
@@ -1,7 +1,7 @@
1
1
  import { type PolicyStatement } from "aws-cdk-lib/aws-iam";
2
2
  import { ManagedPolicy } from "aws-cdk-lib/aws-iam";
3
- import type { GuStack } from "../../../../constructs/core";
4
- export type GuDeveloperPolicyExperimentalProps = {
3
+ import type { GuStack } from "../../core";
4
+ export type GuDeveloperPolicyProps = {
5
5
  /**
6
6
  * IAM policy statements to include in the developer policy.
7
7
  *
@@ -55,9 +55,8 @@ export type GuDeveloperPolicyExperimentalProps = {
55
55
  * aws:cdk:path: janus-resources-for-testing-managed-policy-tagging/justin-testing/Resource* ```
56
56
  * ```
57
57
  *
58
- * @experimental
59
58
  */
60
- export declare class GuDeveloperPolicyExperimental extends ManagedPolicy {
61
- constructor(scope: GuStack, id: string, props: GuDeveloperPolicyExperimentalProps);
59
+ export declare class GuDeveloperPolicy extends ManagedPolicy {
60
+ constructor(scope: GuStack, id: string, props: GuDeveloperPolicyProps);
62
61
  }
63
62
  //# sourceMappingURL=developer-policy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"developer-policy.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/developer-policy.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAoB,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,MAAM,sBAAsB,GAAG;IACnC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,eAAe,EAAE,GAAG,eAAe,EAAE,CAAC,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,sBAAsB;CAetE"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GuDeveloperPolicyExperimental = void 0;
3
+ exports.GuDeveloperPolicy = void 0;
4
4
  const aws_cdk_lib_1 = require("aws-cdk-lib");
5
5
  const aws_iam_1 = require("aws-cdk-lib/aws-iam");
6
6
  const aws_iam_2 = require("aws-cdk-lib/aws-iam");
@@ -35,9 +35,8 @@ const aws_iam_2 = require("aws-cdk-lib/aws-iam");
35
35
  * aws:cdk:path: janus-resources-for-testing-managed-policy-tagging/justin-testing/Resource* ```
36
36
  * ```
37
37
  *
38
- * @experimental
39
38
  */
40
- class GuDeveloperPolicyExperimental extends aws_iam_2.ManagedPolicy {
39
+ class GuDeveloperPolicy extends aws_iam_2.ManagedPolicy {
41
40
  constructor(scope, id, props) {
42
41
  super(scope, id, {
43
42
  ...props,
@@ -45,16 +44,16 @@ class GuDeveloperPolicyExperimental extends aws_iam_2.ManagedPolicy {
45
44
  path: `/developer-policy/${scope.repositoryName}/${scope.stack}/${scope.stage}/${props.grantId}/`,
46
45
  description: props.friendlyName,
47
46
  });
48
- aws_cdk_lib_1.Aspects.of(this).add(new GuDeveloperPolicyExperimentalRequiredChecker());
47
+ aws_cdk_lib_1.Aspects.of(this).add(new GuDeveloperPolicyRequiredChecker());
49
48
  if (!props.withoutPolicyChecks) {
50
49
  // Later, apply to the stack and check for specific errors
51
- aws_cdk_lib_1.Aspects.of(this).add(new GuDeveloperPolicyExperimentalOptionalChecker());
50
+ aws_cdk_lib_1.Aspects.of(this).add(new GuDeveloperPolicyOptionalChecker());
52
51
  }
53
52
  }
54
53
  }
55
- exports.GuDeveloperPolicyExperimental = GuDeveloperPolicyExperimental;
54
+ exports.GuDeveloperPolicy = GuDeveloperPolicy;
56
55
  // Add checks here that we require and don't allow users to opt out of.
57
- class GuDeveloperPolicyExperimentalRequiredChecker {
56
+ class GuDeveloperPolicyRequiredChecker {
58
57
  visit(node) {
59
58
  if (node instanceof aws_iam_2.CfnManagedPolicy) {
60
59
  const description = node.description;
@@ -69,7 +68,7 @@ class GuDeveloperPolicyExperimentalRequiredChecker {
69
68
  }
70
69
  }
71
70
  // Add checks here that we recommend for most scenarios but don't require.
72
- class GuDeveloperPolicyExperimentalOptionalChecker {
71
+ class GuDeveloperPolicyOptionalChecker {
73
72
  visit(node) {
74
73
  if (node instanceof aws_iam_2.CfnManagedPolicy) {
75
74
  const policyDocumentJson = node.policyDocument.toJSON();
@@ -0,0 +1 @@
1
+ {"version":3,"file":"developer-policy.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/developer-policy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IAspect } from \"aws-cdk-lib\";\nimport { Annotations, Aspects } from \"aws-cdk-lib\";\nimport { Effect, type PolicyDocument, type PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { CfnManagedPolicy, ManagedPolicy } from \"aws-cdk-lib/aws-iam\";\nimport type { IConstruct } from \"constructs\";\nimport type { GuStack } from \"../../core\";\n\nexport type GuDeveloperPolicyProps = {\n /**\n * IAM policy statements to include in the developer policy.\n *\n * At least one statement is required.\n */\n readonly statements: [PolicyStatement, ...PolicyStatement[]];\n /**\n * Unique identifier of the developer policy grant.\n * This must match the grant ID used in Janus DeveloperPolicyGrant!\n */\n readonly grantId: string;\n /**\n * A brief description to help choose the correct developer policy in Janus or elsewhere.\n *\n * In AWS this will appear as the managed policy description.\n */\n readonly friendlyName: string;\n /**\n * An optional marker which suppresses the check and warnings on overbroad permissions\n */\n readonly withoutPolicyChecks?: boolean;\n};\n\n/**\n * Creates a structured `AWS::IAM::ManagedPolicy` resource to manage arbitrary permissions on general account\n * resources which can then be used to create limited permission credentials for use with specific activities.\n *\n * The permission scope is not controlled. This class should be used with care to create minimal permissions.\n * To that end, broad ALLOW permissions can be pruned with narrower optional DENY permissions.\n *\n * `permission` is prefixed with `/developer-policy/` and postfixed with `/` to construct the path. This will\n * be used for discovery and display. It is restricted to the same character set as AWS `path`.\n *\n * `description` is optionally used to construct the AWS Managed Policy description and used for display.\n *\n * ```yaml\n * TestingECAE2E87:\n * Type: AWS::IAM::ManagedPolicy\n * Properties:\n * Description: This is testing stuff\n * Path: /developer-policy/read-from-mybucket-under-mypath/\n * PolicyDocument:\n * Statement:\n * - Action: s3:GetObject\n * Effect: Allow\n * Resource: arn:aws:s3:::mybucket/mypath\n * - Action: s3:GetObject\n * Effect: Deny\n * Resource: arn:aws:s3:::mybucket/mypath/butnotthispath\n * Version: \"2012-10-17\"\n * Metadata:\n * aws:cdk:path: janus-resources-for-testing-managed-policy-tagging/justin-testing/Resource* ```\n * ```\n *\n */\nexport class GuDeveloperPolicy extends ManagedPolicy {\n constructor(scope: GuStack, id: string, props: GuDeveloperPolicyProps) {\n super(scope, id, {\n ...props,\n // Bear in mind that path has max length 512 chars\n path: `/developer-policy/${scope.repositoryName}/${scope.stack}/${scope.stage}/${props.grantId}/`,\n description: props.friendlyName,\n });\n\n Aspects.of(this).add(new GuDeveloperPolicyRequiredChecker());\n\n if (!props.withoutPolicyChecks) {\n // Later, apply to the stack and check for specific errors\n Aspects.of(this).add(new GuDeveloperPolicyOptionalChecker());\n }\n }\n}\n\n// Add checks here that we require and don't allow users to opt out of.\nclass GuDeveloperPolicyRequiredChecker implements IAspect {\n public visit(node: IConstruct): void {\n if (node instanceof CfnManagedPolicy) {\n const description = node.description;\n const maxLength = 60;\n\n if (!description?.length) {\n Annotations.of(node).addError(\"friendlyName must be filled in\");\n } else if (description.length > maxLength) {\n Annotations.of(node).addError(\n `friendlyName must be no more than ${maxLength} characters long, but was ${description.length} characters`,\n );\n }\n }\n }\n}\n\n// Add checks here that we recommend for most scenarios but don't require.\nclass GuDeveloperPolicyOptionalChecker implements IAspect {\n public visit(node: IConstruct): void {\n if (node instanceof CfnManagedPolicy) {\n const policyDocumentJson: unknown = (node.policyDocument as PolicyDocument).toJSON();\n\n // These conditions will result in failures from the AWS classes themselves, so we don't need to validate them.\n if (policyDocumentJson === null || typeof policyDocumentJson !== \"object\") {\n return;\n }\n if (!(\"Statement\" in policyDocumentJson)) {\n return;\n }\n if (!Array.isArray(policyDocumentJson.Statement)) {\n return;\n }\n if (policyDocumentJson.Statement.length === 0) {\n return;\n }\n\n // For the following conditions, we want to make a strong assertions: you cannot \"Allow\" with wildcards.\n for (const statement of policyDocumentJson.Statement) {\n if (!(\"Effect\" in statement) || (statement as { Effect: unknown }).Effect === Effect.ALLOW) {\n if (!(\"Action\" in statement)) {\n Annotations.of(node).addError(\"Statement is missing an Action\");\n } else {\n const action = (statement as { Action: unknown }).Action;\n\n if (typeof action === \"string\") {\n this.checkAction(action, node);\n } else if (Array.isArray(action)) {\n const actionArray = action as string[];\n actionArray.forEach((action) => this.checkAction(action, node));\n }\n }\n\n if (!(\"Resource\" in statement)) {\n // Typescript requires us to check this, because the data model doesn't guarantee it\n Annotations.of(node).addError(\"Statement is missing a Resource\");\n } else {\n const resource = (statement as { Resource: unknown }).Resource;\n\n if (typeof resource === \"string\") {\n this.checkResource(resource, node);\n } else if (Array.isArray(resource)) {\n const resourceArray = resource as string[];\n resourceArray.forEach((resource) => {\n this.checkResource(resource, node);\n });\n }\n }\n }\n }\n }\n }\n\n /**\n * Ensure that we don't have either actions or resources of the following forms:\n *\n * *\n * s3:*\n * arn:aws:dynamodb:us-east-2:account-ID-without-hyphens:table/*\n * arn:aws:s3:::*\n *\n * @param checkString Action or resource value to validate.\n * @param checkType Label used in validation error messages (for example, Action or Resource).\n * @param node Policy node used to attach validation annotations.\n * @private\n */\n private check(checkString: string, checkType: string, node: CfnManagedPolicy) {\n if (checkString === \"*\" || checkString.includes(\":*\") || checkString.includes(\"/*\")) {\n Annotations.of(node).addError(\n `Statement ${checkType} is too broad: ${checkString}. If this is necessary and intended, use withoutPolicyChecks: true in properties to turn off this check`,\n );\n }\n }\n private checkAction(checkString: string, node: CfnManagedPolicy) {\n this.check(checkString, \"Action\", node);\n }\n private checkResource(checkString: string, node: CfnManagedPolicy) {\n this.check(checkString, \"Resource\", node);\n }\n}\n"]}
@@ -10,4 +10,5 @@ export * from "./parameter-store-read";
10
10
  export * from "./s3-get-object";
11
11
  export * from "./s3-put-object";
12
12
  export * from "./ses";
13
+ export * from "./developer-policy";
13
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,OAAO,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC;AACtB,cAAc,oBAAoB,CAAC"}
@@ -26,4 +26,5 @@ __exportStar(require("./parameter-store-read"), exports);
26
26
  __exportStar(require("./s3-get-object"), exports);
27
27
  __exportStar(require("./s3-put-object"), exports);
28
28
  __exportStar(require("./ses"), exports);
29
+ __exportStar(require("./developer-policy"), exports);
29
30
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,gDAA8B;AAC9B,gDAA8B;AAC9B,+CAA6B;AAC7B,iDAA+B;AAC/B,6CAA2B;AAC3B,wCAAsB;AACtB,iDAA+B;AAC/B,yDAAuC;AACvC,kDAAgC;AAChC,kDAAgC;AAChC,wCAAsB","sourcesContent":["export * from \"./anghammarad\";\nexport * from \"./assume-role\";\nexport * from \"./base-policy\";\nexport * from \"./cloudwatch\";\nexport * from \"./describe-ec2\";\nexport * from \"./dynamodb\";\nexport * from \"./kcl\";\nexport * from \"./log-shipping\";\nexport * from \"./parameter-store-read\";\nexport * from \"./s3-get-object\";\nexport * from \"./s3-put-object\";\nexport * from \"./ses\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,gDAA8B;AAC9B,gDAA8B;AAC9B,gDAA8B;AAC9B,+CAA6B;AAC7B,iDAA+B;AAC/B,6CAA2B;AAC3B,wCAAsB;AACtB,iDAA+B;AAC/B,yDAAuC;AACvC,kDAAgC;AAChC,kDAAgC;AAChC,wCAAsB;AACtB,qDAAmC","sourcesContent":["export * from \"./anghammarad\";\nexport * from \"./assume-role\";\nexport * from \"./base-policy\";\nexport * from \"./cloudwatch\";\nexport * from \"./describe-ec2\";\nexport * from \"./dynamodb\";\nexport * from \"./kcl\";\nexport * from \"./log-shipping\";\nexport * from \"./parameter-store-read\";\nexport * from \"./s3-get-object\";\nexport * from \"./s3-put-object\";\nexport * from \"./ses\";\nexport * from \"./developer-policy\";\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@guardian/cdk",
3
3
  "description": "Generic Guardian flavoured AWS CDK components",
4
- "version": "64.7.0",
4
+ "version": "65.0.0",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [
@@ -1 +0,0 @@
1
- {"version":3,"file":"developer-policy.d.ts","sourceRoot":"","sources":["../../../../../src/experimental/constructs/iam/policies/developer-policy.ts"],"names":[],"mappings":"AAEA,OAAO,EAA+B,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACxF,OAAO,EAAoB,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,MAAM,kCAAkC,GAAG;IAC/C;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,eAAe,EAAE,GAAG,eAAe,EAAE,CAAC,CAAC;IAC7D;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B;;OAEG;IACH,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CACxC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,qBAAa,6BAA8B,SAAQ,aAAa;gBAClD,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kCAAkC;CAelF"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"developer-policy.js","sourceRoot":"","sources":["../../../../../src/experimental/constructs/iam/policies/developer-policy.ts"],"names":[],"mappings":"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","sourcesContent":["import type { IAspect } from \"aws-cdk-lib\";\nimport { Annotations, Aspects } from \"aws-cdk-lib\";\nimport { Effect, type PolicyDocument, type PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { CfnManagedPolicy, ManagedPolicy } from \"aws-cdk-lib/aws-iam\";\nimport type { IConstruct } from \"constructs\";\nimport type { GuStack } from \"../../../../constructs/core\";\n\nexport type GuDeveloperPolicyExperimentalProps = {\n /**\n * IAM policy statements to include in the developer policy.\n *\n * At least one statement is required.\n */\n readonly statements: [PolicyStatement, ...PolicyStatement[]];\n /**\n * Unique identifier of the developer policy grant.\n * This must match the grant ID used in Janus DeveloperPolicyGrant!\n */\n readonly grantId: string;\n /**\n * A brief description to help choose the correct developer policy in Janus or elsewhere.\n *\n * In AWS this will appear as the managed policy description.\n */\n readonly friendlyName: string;\n /**\n * An optional marker which suppresses the check and warnings on overbroad permissions\n */\n readonly withoutPolicyChecks?: boolean;\n};\n\n/**\n * Creates a structured `AWS::IAM::ManagedPolicy` resource to manage arbitrary permissions on general account\n * resources which can then be used to create limited permission credentials for use with specific activities.\n *\n * The permission scope is not controlled. This class should be used with care to create minimal permissions.\n * To that end, broad ALLOW permissions can be pruned with narrower optional DENY permissions.\n *\n * `permission` is prefixed with `/developer-policy/` and postfixed with `/` to construct the path. This will\n * be used for discovery and display. It is restricted to the same character set as AWS `path`.\n *\n * `description` is optionally used to construct the AWS Managed Policy description and used for display.\n *\n * ```yaml\n * TestingECAE2E87:\n * Type: AWS::IAM::ManagedPolicy\n * Properties:\n * Description: This is testing stuff\n * Path: /developer-policy/read-from-mybucket-under-mypath/\n * PolicyDocument:\n * Statement:\n * - Action: s3:GetObject\n * Effect: Allow\n * Resource: arn:aws:s3:::mybucket/mypath\n * - Action: s3:GetObject\n * Effect: Deny\n * Resource: arn:aws:s3:::mybucket/mypath/butnotthispath\n * Version: \"2012-10-17\"\n * Metadata:\n * aws:cdk:path: janus-resources-for-testing-managed-policy-tagging/justin-testing/Resource* ```\n * ```\n *\n * @experimental\n */\nexport class GuDeveloperPolicyExperimental extends ManagedPolicy {\n constructor(scope: GuStack, id: string, props: GuDeveloperPolicyExperimentalProps) {\n super(scope, id, {\n ...props,\n // Bear in mind that path has max length 512 chars\n path: `/developer-policy/${scope.repositoryName}/${scope.stack}/${scope.stage}/${props.grantId}/`,\n description: props.friendlyName,\n });\n\n Aspects.of(this).add(new GuDeveloperPolicyExperimentalRequiredChecker());\n\n if (!props.withoutPolicyChecks) {\n // Later, apply to the stack and check for specific errors\n Aspects.of(this).add(new GuDeveloperPolicyExperimentalOptionalChecker());\n }\n }\n}\n\n// Add checks here that we require and don't allow users to opt out of.\nclass GuDeveloperPolicyExperimentalRequiredChecker implements IAspect {\n public visit(node: IConstruct): void {\n if (node instanceof CfnManagedPolicy) {\n const description = node.description;\n const maxLength = 60;\n\n if (!description?.length) {\n Annotations.of(node).addError(\"friendlyName must be filled in\");\n } else if (description.length > maxLength) {\n Annotations.of(node).addError(\n `friendlyName must be no more than ${maxLength} characters long, but was ${description.length} characters`,\n );\n }\n }\n }\n}\n\n// Add checks here that we recommend for most scenarios but don't require.\nclass GuDeveloperPolicyExperimentalOptionalChecker implements IAspect {\n public visit(node: IConstruct): void {\n if (node instanceof CfnManagedPolicy) {\n const policyDocumentJson: unknown = (node.policyDocument as PolicyDocument).toJSON();\n\n // These conditions will result in failures from the AWS classes themselves, so we don't need to validate them.\n if (policyDocumentJson === null || typeof policyDocumentJson !== \"object\") {\n return;\n }\n if (!(\"Statement\" in policyDocumentJson)) {\n return;\n }\n if (!Array.isArray(policyDocumentJson.Statement)) {\n return;\n }\n if (policyDocumentJson.Statement.length === 0) {\n return;\n }\n\n // For the following conditions, we want to make a strong assertions: you cannot \"Allow\" with wildcards.\n for (const statement of policyDocumentJson.Statement) {\n if (!(\"Effect\" in statement) || (statement as { Effect: unknown }).Effect === Effect.ALLOW) {\n if (!(\"Action\" in statement)) {\n Annotations.of(node).addError(\"Statement is missing an Action\");\n } else {\n const action = (statement as { Action: unknown }).Action;\n\n if (typeof action === \"string\") {\n this.checkAction(action, node);\n } else if (Array.isArray(action)) {\n const actionArray = action as string[];\n actionArray.forEach((action) => this.checkAction(action, node));\n }\n }\n\n if (!(\"Resource\" in statement)) {\n // Typescript requires us to check this, because the data model doesn't guarantee it\n Annotations.of(node).addError(\"Statement is missing a Resource\");\n } else {\n const resource = (statement as { Resource: unknown }).Resource;\n\n if (typeof resource === \"string\") {\n this.checkResource(resource, node);\n } else if (Array.isArray(resource)) {\n const resourceArray = resource as string[];\n resourceArray.forEach((resource) => {\n this.checkResource(resource, node);\n });\n }\n }\n }\n }\n }\n }\n\n /**\n * Ensure that we don't have either actions or resources of the following forms:\n *\n * *\n * s3:*\n * arn:aws:dynamodb:us-east-2:account-ID-without-hyphens:table/*\n * arn:aws:s3:::*\n *\n * @param checkString Action or resource value to validate.\n * @param checkType Label used in validation error messages (for example, Action or Resource).\n * @param node Policy node used to attach validation annotations.\n * @private\n */\n private check(checkString: string, checkType: string, node: CfnManagedPolicy) {\n if (checkString === \"*\" || checkString.includes(\":*\") || checkString.includes(\"/*\")) {\n Annotations.of(node).addError(\n `Statement ${checkType} is too broad: ${checkString}. If this is necessary and intended, use withoutPolicyChecks: true in properties to turn off this check`,\n );\n }\n }\n private checkAction(checkString: string, node: CfnManagedPolicy) {\n this.check(checkString, \"Action\", node);\n }\n private checkResource(checkString: string, node: CfnManagedPolicy) {\n this.check(checkString, \"Resource\", node);\n }\n}\n"]}
@@ -1,2 +0,0 @@
1
- export * from "./developer-policy";
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/experimental/constructs/iam/policies/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC"}
@@ -1,18 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
- };
16
- Object.defineProperty(exports, "__esModule", { value: true });
17
- __exportStar(require("./developer-policy"), exports);
18
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/experimental/constructs/iam/policies/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC","sourcesContent":["export * from \"./developer-policy\";\n"]}