@guardian/cdk 63.0.0 → 63.0.1
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/lib/experimental/constructs/iam/policies/developer-policy.d.ts +4 -0
- package/lib/experimental/constructs/iam/policies/developer-policy.d.ts.map +1 -1
- package/lib/experimental/constructs/iam/policies/developer-policy.js +6 -3
- package/lib/experimental/constructs/iam/policies/developer-policy.js.map +1 -1
- package/package.json +1 -1
|
@@ -17,6 +17,10 @@ export type GuWorkloadPolicyProps = {
|
|
|
17
17
|
* An optional description of the policy which will be displayed if present.
|
|
18
18
|
*/
|
|
19
19
|
readonly description?: string;
|
|
20
|
+
/**
|
|
21
|
+
* An optional marker which suppresses the check and warnings on overbroad permissions
|
|
22
|
+
*/
|
|
23
|
+
readonly withoutPolicyChecks?: boolean;
|
|
20
24
|
};
|
|
21
25
|
/**
|
|
22
26
|
* Creates a structured `AWS::IAM::ManagedPolicy` resource to manage arbitrary permissions on general account
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"developer-policy.d.ts","sourceRoot":"","sources":["../../../../../src/experimental/constructs/iam/policies/developer-policy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAoB,aAAa,EAAuB,MAAM,qBAAqB,CAAC;AAE3F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IACxC;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"developer-policy.d.ts","sourceRoot":"","sources":["../../../../../src/experimental/constructs/iam/policies/developer-policy.ts"],"names":[],"mappings":"AAEA,OAAO,EAAU,KAAK,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,EAAoB,aAAa,EAAuB,MAAM,qBAAqB,CAAC;AAE3F,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAE3D,MAAM,MAAM,qBAAqB,GAAG;IAClC;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IACxC;;OAEG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;OAEG;IACH,QAAQ,CAAC,WAAW,CAAC,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,qBAAqB;CAiBrE"}
|
|
@@ -48,8 +48,10 @@ class GuDeveloperPolicyExperimental extends aws_iam_2.ManagedPolicy {
|
|
|
48
48
|
if (props.statements?.length == 0) {
|
|
49
49
|
throw new Error("Empty statements array passed to GuDeveloperPolicyExperimental");
|
|
50
50
|
}
|
|
51
|
-
|
|
52
|
-
|
|
51
|
+
if (!props.withoutPolicyChecks) {
|
|
52
|
+
// Later, apply to the stack and check for specific errors
|
|
53
|
+
aws_cdk_lib_1.Aspects.of(this).add(new GuDeveloperPolicyExperimentalChecker());
|
|
54
|
+
}
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
exports.GuDeveloperPolicyExperimental = GuDeveloperPolicyExperimental;
|
|
@@ -84,6 +86,7 @@ class GuDeveloperPolicyExperimentalChecker {
|
|
|
84
86
|
}
|
|
85
87
|
}
|
|
86
88
|
if (!("Resource" in statement)) {
|
|
89
|
+
// Typescript requires us to check this, because the data model doesn't guarantee it
|
|
87
90
|
aws_cdk_lib_1.Annotations.of(node).addError("Statement is missing an Resource");
|
|
88
91
|
}
|
|
89
92
|
else {
|
|
@@ -116,7 +119,7 @@ class GuDeveloperPolicyExperimentalChecker {
|
|
|
116
119
|
*/
|
|
117
120
|
check(checkString, checkType, node) {
|
|
118
121
|
if (checkString === "*" || checkString.indexOf(":*") || checkString.indexOf("/*") > 0) {
|
|
119
|
-
aws_cdk_lib_1.Annotations.of(node).addError(`Statement ${checkType} is too broad: ${checkString}`);
|
|
122
|
+
aws_cdk_lib_1.Annotations.of(node).addError(`Statement ${checkType} is too broad: ${checkString}. If this is necessary and intended, use withoutPolicyChecks: true in properties to turn off this check`);
|
|
120
123
|
}
|
|
121
124
|
}
|
|
122
125
|
checkAction(checkString, node) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"developer-policy.js","sourceRoot":"","sources":["../../../../../src/experimental/constructs/iam/policies/developer-policy.ts"],"names":[],"mappings":";;;AACA,6CAAmD;AACnD,iDAAmE;AACnE,iDAA2F;
|
|
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 PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { CfnManagedPolicy, ManagedPolicy, type PolicyDocument } from \"aws-cdk-lib/aws-iam\";\nimport type { IConstruct } from \"constructs\";\nimport type { GuStack } from \"../../../../constructs/core\";\n\nexport type GuWorkloadPolicyProps = {\n /**\n * Initial set of permissions to add to this policy document.\n * You can also use `addPermission(statement)` to add permissions later.\n *\n * @default - No statements.\n */\n readonly statements?: PolicyStatement[];\n /**\n * The unique identifier of the policy, which will be displayed when creating credentials.\n */\n readonly permission: string;\n /**\n * An optional description of the policy which will be displayed if present.\n */\n readonly description?: 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 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: GuWorkloadPolicyProps) {\n super(scope, id, {\n description: `${props.permission} developer policy`,\n ...props,\n path: `/developer-policy/${props.permission}/`,\n });\n\n // Don't mind if it's missing, but if it's used it must not be empty\n if (props.statements?.length == 0) {\n throw new Error(\"Empty statements array passed to GuDeveloperPolicyExperimental\");\n }\n\n if (!props.withoutPolicyChecks) {\n // Later, apply to the stack and check for specific errors\n Aspects.of(this).add(new GuDeveloperPolicyExperimentalChecker());\n }\n }\n}\n\nclass GuDeveloperPolicyExperimentalChecker 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) || 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 an 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 resource or action\n * @param node\n * @private\n */\n private check(checkString: string, checkType: string, node: CfnManagedPolicy) {\n if (checkString === \"*\" || checkString.indexOf(\":*\") || checkString.indexOf(\"/*\") > 0) {\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"]}
|