@guardian/cdk 53.1.1 → 54.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.
@@ -0,0 +1,19 @@
1
+ import type { GuStack } from "../../core";
2
+ import { GuAllowPolicy } from "./base-policy";
3
+ /**
4
+ * A minimal policy enabling SSM+SSH access to EC2 instances.
5
+ *
6
+ * This is favoured over the AWS Managed Policy `AmazonSSMManagedInstanceCore`,
7
+ * `AmazonSSMManagedInstanceCore` provides read access to all SSM Parameters.
8
+ * This is not required for SSM+SSH, and given our usage of SSM Parameters for configuration, is not following least privilege.
9
+ * Access to SSM Parameters should be scoped to the Stack, Stage, and Application.
10
+ *
11
+ * @see https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html
12
+ * @see https://github.com/guardian/ssm-scala
13
+ */
14
+ export declare class GuSsmSshPolicy extends GuAllowPolicy {
15
+ private static instance;
16
+ private constructor();
17
+ static getInstance(stack: GuStack): GuSsmSshPolicy;
18
+ }
19
+ //# sourceMappingURL=ssm-ssh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssm-ssh.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ssm-ssh.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C;;;;;;;;;;GAUG;AACH,qBAAa,cAAe,SAAQ,aAAa;IAC/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA6B;IAEpD,OAAO;WAyBO,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc;CAO1D"}
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GuSsmSshPolicy = void 0;
4
+ const singleton_1 = require("../../../utils/singleton");
5
+ const base_policy_1 = require("./base-policy");
6
+ /**
7
+ * A minimal policy enabling SSM+SSH access to EC2 instances.
8
+ *
9
+ * This is favoured over the AWS Managed Policy `AmazonSSMManagedInstanceCore`,
10
+ * `AmazonSSMManagedInstanceCore` provides read access to all SSM Parameters.
11
+ * This is not required for SSM+SSH, and given our usage of SSM Parameters for configuration, is not following least privilege.
12
+ * Access to SSM Parameters should be scoped to the Stack, Stage, and Application.
13
+ *
14
+ * @see https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html
15
+ * @see https://github.com/guardian/ssm-scala
16
+ */
17
+ class GuSsmSshPolicy extends base_policy_1.GuAllowPolicy {
18
+ constructor(scope) {
19
+ super(scope, "SsmSshPolicy", {
20
+ policyName: "ssm-ssh-policy",
21
+ actions: [
22
+ "ec2messages:AcknowledgeMessage",
23
+ "ec2messages:DeleteMessage",
24
+ "ec2messages:FailMessage",
25
+ "ec2messages:GetEndpoint",
26
+ "ec2messages:GetMessages",
27
+ "ec2messages:SendReply",
28
+ "ssm:UpdateInstanceInformation",
29
+ "ssm:ListInstanceAssociations",
30
+ "ssm:DescribeInstanceProperties",
31
+ "ssm:DescribeDocumentParameters",
32
+ "ssmmessages:CreateControlChannel",
33
+ "ssmmessages:CreateDataChannel",
34
+ "ssmmessages:OpenControlChannel",
35
+ "ssmmessages:OpenDataChannel",
36
+ ],
37
+ // TODO can this be scoped to the stack, stage, and application? If so, it won't make sense to be a singleton.
38
+ resources: ["*"],
39
+ });
40
+ }
41
+ static getInstance(stack) {
42
+ if (!this.instance || !(0, singleton_1.isSingletonPresentInStack)(stack, this.instance)) {
43
+ this.instance = new GuSsmSshPolicy(stack);
44
+ }
45
+ return this.instance;
46
+ }
47
+ }
48
+ exports.GuSsmSshPolicy = GuSsmSshPolicy;
49
+ //# sourceMappingURL=ssm-ssh.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssm-ssh.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ssm-ssh.ts"],"names":[],"mappings":";;;AAAA,wDAAqE;AAErE,+CAA8C;AAE9C;;;;;;;;;;GAUG;AACH,MAAa,cAAe,SAAQ,2BAAa;IAG/C,YAAoB,KAAc;QAChC,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE;YAC3B,UAAU,EAAE,gBAAgB;YAC5B,OAAO,EAAE;gBACP,gCAAgC;gBAChC,2BAA2B;gBAC3B,yBAAyB;gBACzB,yBAAyB;gBACzB,yBAAyB;gBACzB,uBAAuB;gBACvB,+BAA+B;gBAC/B,8BAA8B;gBAC9B,gCAAgC;gBAChC,gCAAgC;gBAChC,kCAAkC;gBAClC,+BAA+B;gBAC/B,gCAAgC;gBAChC,6BAA6B;aAC9B;YAED,8GAA8G;YAC9G,SAAS,EAAE,CAAC,GAAG,CAAC;SACjB,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,WAAW,CAAC,KAAc;QACtC,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAA,qCAAyB,EAAC,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,EAAE;YACtE,IAAI,CAAC,QAAQ,GAAG,IAAI,cAAc,CAAC,KAAK,CAAC,CAAC;SAC3C;QAED,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAnCD,wCAmCC","sourcesContent":["import { isSingletonPresentInStack } from \"../../../utils/singleton\";\nimport type { GuStack } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\n/**\n * A minimal policy enabling SSM+SSH access to EC2 instances.\n *\n * This is favoured over the AWS Managed Policy `AmazonSSMManagedInstanceCore`,\n * `AmazonSSMManagedInstanceCore` provides read access to all SSM Parameters.\n * This is not required for SSM+SSH, and given our usage of SSM Parameters for configuration, is not following least privilege.\n * Access to SSM Parameters should be scoped to the Stack, Stage, and Application.\n *\n * @see https://docs.aws.amazon.com/aws-managed-policy/latest/reference/AmazonSSMManagedInstanceCore.html\n * @see https://github.com/guardian/ssm-scala\n */\nexport class GuSsmSshPolicy extends GuAllowPolicy {\n private static instance: GuSsmSshPolicy | undefined;\n\n private constructor(scope: GuStack) {\n super(scope, \"SsmSshPolicy\", {\n policyName: \"ssm-ssh-policy\",\n actions: [\n \"ec2messages:AcknowledgeMessage\",\n \"ec2messages:DeleteMessage\",\n \"ec2messages:FailMessage\",\n \"ec2messages:GetEndpoint\",\n \"ec2messages:GetMessages\",\n \"ec2messages:SendReply\",\n \"ssm:UpdateInstanceInformation\",\n \"ssm:ListInstanceAssociations\",\n \"ssm:DescribeInstanceProperties\",\n \"ssm:DescribeDocumentParameters\",\n \"ssmmessages:CreateControlChannel\",\n \"ssmmessages:CreateDataChannel\",\n \"ssmmessages:OpenControlChannel\",\n \"ssmmessages:OpenDataChannel\",\n ],\n\n // TODO can this be scoped to the stack, stage, and application? If so, it won't make sense to be a singleton.\n resources: [\"*\"],\n });\n }\n\n public static getInstance(stack: GuStack): GuSsmSshPolicy {\n if (!this.instance || !isSingletonPresentInStack(stack, this.instance)) {\n this.instance = new GuSsmSshPolicy(stack);\n }\n\n return this.instance;\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"instance-role.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/instance-role.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAOvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC;CACjC;AAED,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG,WAAW,CAAC;;;;;;AAE3E;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAe,SAAQ,mBAA2B;gBACjD,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,0BAA0B;CAwB9D"}
1
+ {"version":3,"file":"instance-role.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/instance-role.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAOvD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,kBAAkB,CAAC,EAAE,QAAQ,EAAE,CAAC;CACjC;AAED,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG,WAAW,CAAC;;;;;;AAE3E;;;;;;;;;;;;;;GAcG;AACH,qBAAa,cAAe,SAAQ,mBAA2B;gBACjD,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,0BAA0B;CAsB9D"}
@@ -4,6 +4,7 @@ exports.GuInstanceRole = void 0;
4
4
  const aws_iam_1 = require("aws-cdk-lib/aws-iam");
5
5
  const app_aware_construct_1 = require("../../../utils/mixin/app-aware-construct");
6
6
  const policies_1 = require("../policies");
7
+ const ssm_ssh_1 = require("../policies/ssm-ssh");
7
8
  const roles_1 = require("./roles");
8
9
  /**
9
10
  * Creates an IAM role with common policies that are needed by most Guardian applications.
@@ -28,6 +29,7 @@ class GuInstanceRole extends (0, app_aware_construct_1.GuAppAwareConstruct)(role
28
29
  ...props,
29
30
  });
30
31
  const sharedPolicies = [
32
+ ssm_ssh_1.GuSsmSshPolicy.getInstance(scope),
31
33
  policies_1.GuDescribeEC2Policy.getInstance(scope),
32
34
  ...(props.withoutLogShipping ? [] : [policies_1.GuLogShippingPolicy.getInstance(scope)]),
33
35
  ];
@@ -37,9 +39,7 @@ class GuInstanceRole extends (0, app_aware_construct_1.GuAppAwareConstruct)(role
37
39
  new policies_1.GuParameterStoreReadPolicy(scope, props),
38
40
  ...(props.additionalPolicies ? props.additionalPolicies : []),
39
41
  ];
40
- const managedPolicies = [aws_iam_1.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMManagedInstanceCore")];
41
42
  policies.forEach((p) => p.attachToRole(this));
42
- managedPolicies.forEach((p) => this.addManagedPolicy(p));
43
43
  }
44
44
  }
45
45
  exports.GuInstanceRole = GuInstanceRole;
@@ -1 +1 @@
1
- {"version":3,"file":"instance-role.js","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/instance-role.ts"],"names":[],"mappings":";;;AAAA,iDAAsE;AACtE,kFAA+E;AAE/E,0CAKqB;AAErB,mCAAiC;AAgBjC;;;;;;;;;;;;;;GAcG;AACH,MAAa,cAAe,SAAQ,IAAA,yCAAmB,EAAC,cAAM,CAAC;IAC7D,YAAY,KAAc,EAAE,KAAiC;QAC3D,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE;YAC3B,IAAI,EAAE,GAAG;YACT,SAAS,EAAE,IAAI,0BAAgB,CAAC,mBAAmB,CAAC;YACpD,GAAG,KAAK;SACT,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG;YACrB,8BAAmB,CAAC,WAAW,CAAC,KAAK,CAAC;YACtC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,8BAAmB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;SAC9E,CAAC;QAEF,MAAM,QAAQ,GAAG;YACf,GAAG,cAAc;YACjB,IAAI,mCAAwB,CAAC,KAAK,EAAE,KAAK,CAAC;YAC1C,IAAI,qCAA0B,CAAC,KAAK,EAAE,KAAK,CAAC;YAC5C,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC;QAEF,MAAM,eAAe,GAAG,CAAC,uBAAa,CAAC,wBAAwB,CAAC,8BAA8B,CAAC,CAAC,CAAC;QAEjG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9C,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3D,CAAC;CACF;AAzBD,wCAyBC","sourcesContent":["import { ManagedPolicy, ServicePrincipal } from \"aws-cdk-lib/aws-iam\";\nimport { GuAppAwareConstruct } from \"../../../utils/mixin/app-aware-construct\";\nimport type { AppIdentity, GuStack } from \"../../core\";\nimport {\n GuDescribeEC2Policy,\n GuGetDistributablePolicy,\n GuLogShippingPolicy,\n GuParameterStoreReadPolicy,\n} from \"../policies\";\nimport type { GuPolicy } from \"../policies\";\nimport { GuRole } from \"./roles\";\n\nexport interface GuInstanceRoleProps {\n /**\n * By default, instances are given permissions to write to Kinesis. Set to\n * 'true' to prevent this. Note, disabling will prevent not just application\n * logs being shipped but also anything else - for example, automatic log\n * shipping of Cloud Init and other logs by the cdk-base role in your AMI.\n */\n withoutLogShipping?: boolean;\n\n additionalPolicies?: GuPolicy[];\n}\n\nexport type GuInstanceRolePropsWithApp = GuInstanceRoleProps & AppIdentity;\n\n/**\n * Creates an IAM role with common policies that are needed by most Guardian applications.\n *\n * More specifically:\n * 1. Allows for `ssh` access to an EC2 instance via [ssm-scala](https://github.com/guardian/ssm-scala) (instead of standard `ssh`).\n * 2. Allows EC2 instances to communicate with Wazuh, for security monitoring.\n * 3. Allows EC2 instances to download an artifact from AWS S3, for application deployment.\n * 4. Allows EC2 instances to download private configuration from AWS Parameter Store. See [[`GuParameterStoreReadPolicy`]]\n * for specific details.\n * 5. Allows EC2 instances to write logs into our central ELK stack via Kinesis.\n *\n * If additional IAM permissions are required, create custom policies and pass them in via the `additionalPolicies` prop.\n *\n * If log shipping is not required, opt out by setting the `withoutLogShipping` prop to `true`.\n */\nexport class GuInstanceRole extends GuAppAwareConstruct(GuRole) {\n constructor(scope: GuStack, props: GuInstanceRolePropsWithApp) {\n super(scope, \"InstanceRole\", {\n path: \"/\",\n assumedBy: new ServicePrincipal(\"ec2.amazonaws.com\"),\n ...props,\n });\n\n const sharedPolicies = [\n GuDescribeEC2Policy.getInstance(scope),\n ...(props.withoutLogShipping ? [] : [GuLogShippingPolicy.getInstance(scope)]),\n ];\n\n const policies = [\n ...sharedPolicies,\n new GuGetDistributablePolicy(scope, props),\n new GuParameterStoreReadPolicy(scope, props),\n ...(props.additionalPolicies ? props.additionalPolicies : []),\n ];\n\n const managedPolicies = [ManagedPolicy.fromAwsManagedPolicyName(\"AmazonSSMManagedInstanceCore\")];\n\n policies.forEach((p) => p.attachToRole(this));\n managedPolicies.forEach((p) => this.addManagedPolicy(p));\n }\n}\n"]}
1
+ {"version":3,"file":"instance-role.js","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/instance-role.ts"],"names":[],"mappings":";;;AAAA,iDAAuD;AACvD,kFAA+E;AAE/E,0CAKqB;AAErB,iDAAqD;AACrD,mCAAiC;AAgBjC;;;;;;;;;;;;;;GAcG;AACH,MAAa,cAAe,SAAQ,IAAA,yCAAmB,EAAC,cAAM,CAAC;IAC7D,YAAY,KAAc,EAAE,KAAiC;QAC3D,KAAK,CAAC,KAAK,EAAE,cAAc,EAAE;YAC3B,IAAI,EAAE,GAAG;YACT,SAAS,EAAE,IAAI,0BAAgB,CAAC,mBAAmB,CAAC;YACpD,GAAG,KAAK;SACT,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG;YACrB,wBAAc,CAAC,WAAW,CAAC,KAAK,CAAC;YACjC,8BAAmB,CAAC,WAAW,CAAC,KAAK,CAAC;YACtC,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,8BAAmB,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC;SAC9E,CAAC;QAEF,MAAM,QAAQ,GAAG;YACf,GAAG,cAAc;YACjB,IAAI,mCAAwB,CAAC,KAAK,EAAE,KAAK,CAAC;YAC1C,IAAI,qCAA0B,CAAC,KAAK,EAAE,KAAK,CAAC;YAC5C,GAAG,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9D,CAAC;QAEF,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;IAChD,CAAC;CACF;AAvBD,wCAuBC","sourcesContent":["import { ServicePrincipal } from \"aws-cdk-lib/aws-iam\";\nimport { GuAppAwareConstruct } from \"../../../utils/mixin/app-aware-construct\";\nimport type { AppIdentity, GuStack } from \"../../core\";\nimport {\n GuDescribeEC2Policy,\n GuGetDistributablePolicy,\n GuLogShippingPolicy,\n GuParameterStoreReadPolicy,\n} from \"../policies\";\nimport type { GuPolicy } from \"../policies\";\nimport { GuSsmSshPolicy } from \"../policies/ssm-ssh\";\nimport { GuRole } from \"./roles\";\n\nexport interface GuInstanceRoleProps {\n /**\n * By default, instances are given permissions to write to Kinesis. Set to\n * 'true' to prevent this. Note, disabling will prevent not just application\n * logs being shipped but also anything else - for example, automatic log\n * shipping of Cloud Init and other logs by the cdk-base role in your AMI.\n */\n withoutLogShipping?: boolean;\n\n additionalPolicies?: GuPolicy[];\n}\n\nexport type GuInstanceRolePropsWithApp = GuInstanceRoleProps & AppIdentity;\n\n/**\n * Creates an IAM role with common policies that are needed by most Guardian applications.\n *\n * More specifically:\n * 1. Allows for `ssh` access to an EC2 instance via [ssm-scala](https://github.com/guardian/ssm-scala) (instead of standard `ssh`).\n * 2. Allows EC2 instances to communicate with Wazuh, for security monitoring.\n * 3. Allows EC2 instances to download an artifact from AWS S3, for application deployment.\n * 4. Allows EC2 instances to download private configuration from AWS Parameter Store. See [[`GuParameterStoreReadPolicy`]]\n * for specific details.\n * 5. Allows EC2 instances to write logs into our central ELK stack via Kinesis.\n *\n * If additional IAM permissions are required, create custom policies and pass them in via the `additionalPolicies` prop.\n *\n * If log shipping is not required, opt out by setting the `withoutLogShipping` prop to `true`.\n */\nexport class GuInstanceRole extends GuAppAwareConstruct(GuRole) {\n constructor(scope: GuStack, props: GuInstanceRolePropsWithApp) {\n super(scope, \"InstanceRole\", {\n path: \"/\",\n assumedBy: new ServicePrincipal(\"ec2.amazonaws.com\"),\n ...props,\n });\n\n const sharedPolicies = [\n GuSsmSshPolicy.getInstance(scope),\n GuDescribeEC2Policy.getInstance(scope),\n ...(props.withoutLogShipping ? [] : [GuLogShippingPolicy.getInstance(scope)]),\n ];\n\n const policies = [\n ...sharedPolicies,\n new GuGetDistributablePolicy(scope, props),\n new GuParameterStoreReadPolicy(scope, props),\n ...(props.additionalPolicies ? props.additionalPolicies : []),\n ];\n\n policies.forEach((p) => p.attachToRole(this));\n }\n}\n"]}