@jaypie/constructs 1.2.53 → 1.2.55

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.
@@ -8,6 +8,17 @@ import { LambdaDestination } from "aws-cdk-lib/aws-s3-notifications";
8
8
  import * as wafv2 from "aws-cdk-lib/aws-wafv2";
9
9
  import { Construct } from "constructs";
10
10
  import { HostConfig } from "./helpers";
11
+ /**
12
+ * One entry in a `waf.allow` list. Names one or more URL paths and, for each
13
+ * managed rule group key, the sub-rule names to flip from `block` to `count`
14
+ * on that path set. See JaypieWafConfig.allow.
15
+ */
16
+ export interface JaypieWafAllowEntry {
17
+ /** URL path or paths. Trailing `*` → STARTS_WITH; otherwise EXACTLY. */
18
+ path: string | string[];
19
+ /** Managed-rule-group keys (e.g. AWSManagedRulesCommonRuleSet) → sub-rule names. */
20
+ [ruleGroupKey: string]: string | string[] | undefined;
21
+ }
11
22
  export interface JaypieWafConfig {
12
23
  /**
13
24
  * Unique name for this distribution's WAF resources. Required when passing a
@@ -76,6 +87,26 @@ export interface JaypieWafConfig {
76
87
  * @default 2000
77
88
  */
78
89
  rateLimitPerIp?: number;
90
+ /**
91
+ * Path-scoped relaxations layered on top of the default managed-rule groups.
92
+ * Each entry names one or more URL paths and, for each managed rule group
93
+ * key, the sub-rule names to flip from `block` to `count` on that path set.
94
+ * Strict default action is preserved on every other path.
95
+ *
96
+ * Composes with `managedRuleOverrides`: the baseline override list applies
97
+ * to both the relaxed and strict emissions of a group; entries in `allow`
98
+ * additionally relax specific (path × sub-rule) intersections.
99
+ *
100
+ * @example
101
+ * allow: [
102
+ * {
103
+ * path: "/hooks/*",
104
+ * AWSManagedRulesCommonRuleSet: ["ExploitablePaths_URIPATH"],
105
+ * AWSManagedRulesKnownBadInputsRuleSet: ["CrossSiteScripting_BODY"],
106
+ * },
107
+ * ]
108
+ */
109
+ allow?: JaypieWafAllowEntry | JaypieWafAllowEntry[];
79
110
  /**
80
111
  * Use an existing WebACL ARN instead of creating one
81
112
  */
@@ -1,4 +1,5 @@
1
1
  import { Construct } from "constructs";
2
+ import * as cdk from "aws-cdk-lib";
2
3
  import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
3
4
  import * as lambda from "aws-cdk-lib/aws-lambda";
4
5
  import { JaypieLambda } from "./JaypieLambda";
@@ -16,6 +17,8 @@ export interface JaypieMigrationProps {
16
17
  secrets?: SecretsArrayItem[];
17
18
  /** DynamoDB tables to grant read/write access */
18
19
  tables?: dynamodb.ITable[];
20
+ /** Lambda timeout. Defaults to 15 minutes (Lambda max). */
21
+ timeout?: cdk.Duration;
19
22
  }
20
23
  export declare class JaypieMigration extends Construct {
21
24
  readonly lambda: JaypieLambda;
@@ -9,7 +9,7 @@ var route53Targets = require('aws-cdk-lib/aws-route53-targets');
9
9
  var secretsmanager = require('aws-cdk-lib/aws-secretsmanager');
10
10
  var datadogCdkConstructsV2 = require('datadog-cdk-constructs-v2');
11
11
  var errors = require('@jaypie/errors');
12
- var awsIam = require('aws-cdk-lib/aws-iam');
12
+ var iam = require('aws-cdk-lib/aws-iam');
13
13
  var acm = require('aws-cdk-lib/aws-certificatemanager');
14
14
  var logs = require('aws-cdk-lib/aws-logs');
15
15
  var lambda = require('aws-cdk-lib/aws-lambda');
@@ -56,6 +56,7 @@ var apiGateway__namespace = /*#__PURE__*/_interopNamespaceDefault(apiGateway);
56
56
  var route53__namespace = /*#__PURE__*/_interopNamespaceDefault(route53);
57
57
  var route53Targets__namespace = /*#__PURE__*/_interopNamespaceDefault(route53Targets);
58
58
  var secretsmanager__namespace = /*#__PURE__*/_interopNamespaceDefault(secretsmanager);
59
+ var iam__namespace = /*#__PURE__*/_interopNamespaceDefault(iam);
59
60
  var acm__namespace = /*#__PURE__*/_interopNamespaceDefault(acm);
60
61
  var logs__namespace = /*#__PURE__*/_interopNamespaceDefault(logs);
61
62
  var lambda__namespace = /*#__PURE__*/_interopNamespaceDefault(lambda);
@@ -476,22 +477,22 @@ function extendDatadogRole(scope, options) {
476
477
  }
477
478
  const { id = "DatadogCustomPolicy", project, service = CDK$2.SERVICE.DATADOG, } = options || {};
478
479
  // Lookup the Datadog role
479
- const datadogRole = awsIam.Role.fromRoleArn(scope, "DatadogRole", datadogRoleArn);
480
+ const datadogRole = iam.Role.fromRoleArn(scope, "DatadogRole", datadogRoleArn);
480
481
  // Build policy statements
481
482
  const statements = [
482
483
  // Allow view budget
483
- new awsIam.PolicyStatement({
484
+ new iam.PolicyStatement({
484
485
  actions: ["budgets:ViewBudget"],
485
486
  resources: ["*"],
486
487
  }),
487
488
  // Allow describe log groups
488
- new awsIam.PolicyStatement({
489
+ new iam.PolicyStatement({
489
490
  actions: ["logs:DescribeLogGroups"],
490
491
  resources: ["*"],
491
492
  }),
492
493
  ];
493
494
  // Create the custom policy
494
- const datadogCustomPolicy = new awsIam.Policy(scope, id, {
495
+ const datadogCustomPolicy = new iam.Policy(scope, id, {
495
496
  roles: [datadogRole],
496
497
  statements,
497
498
  });
@@ -2327,22 +2328,22 @@ class JaypieDatadogBucket extends constructs.Construct {
2327
2328
  }
2328
2329
  const { project, service = CDK$2.SERVICE.DATADOG } = options || {};
2329
2330
  // Lookup the Datadog role
2330
- const datadogRole = awsIam.Role.fromRoleArn(this, "DatadogRole", datadogRoleArn);
2331
+ const datadogRole = iam.Role.fromRoleArn(this, "DatadogRole", datadogRoleArn);
2331
2332
  // Build policy statements for bucket access
2332
2333
  const statements = [
2333
2334
  // Allow list bucket
2334
- new awsIam.PolicyStatement({
2335
+ new iam.PolicyStatement({
2335
2336
  actions: ["s3:ListBucket"],
2336
2337
  resources: [this.bucket.bucketArn],
2337
2338
  }),
2338
2339
  // Allow read and write to the bucket
2339
- new awsIam.PolicyStatement({
2340
+ new iam.PolicyStatement({
2340
2341
  actions: ["s3:GetObject", "s3:PutObject"],
2341
2342
  resources: [`${this.bucket.bucketArn}/*`],
2342
2343
  }),
2343
2344
  ];
2344
2345
  // Create the custom policy
2345
- const datadogBucketPolicy = new awsIam.Policy(this, "DatadogBucketPolicy", {
2346
+ const datadogBucketPolicy = new iam.Policy(this, "DatadogBucketPolicy", {
2346
2347
  roles: [datadogRole],
2347
2348
  statements,
2348
2349
  });
@@ -2716,13 +2717,110 @@ class JaypieDistribution extends constructs.Construct {
2716
2717
  }
2717
2718
  else {
2718
2719
  // Create new WebACL
2719
- const { managedRuleOverrides, managedRuleScopeDowns, managedRules = DEFAULT_MANAGED_RULES$1, rateLimitPerIp = DEFAULT_RATE_LIMIT$1, } = wafConfig;
2720
+ const { allow, managedRuleOverrides, managedRuleScopeDowns, managedRules = DEFAULT_MANAGED_RULES$1, rateLimitPerIp = DEFAULT_RATE_LIMIT$1, } = wafConfig;
2721
+ const allowEntries = allow
2722
+ ? Array.isArray(allow)
2723
+ ? allow
2724
+ : [allow]
2725
+ : [];
2726
+ const groupAllowances = {};
2727
+ for (const entry of allowEntries) {
2728
+ const paths = Array.isArray(entry.path) ? entry.path : [entry.path];
2729
+ for (const key of Object.keys(entry)) {
2730
+ if (key === "path")
2731
+ continue;
2732
+ const raw = entry[key];
2733
+ if (raw == null)
2734
+ continue;
2735
+ const ruleNames = Array.isArray(raw) ? raw : [raw];
2736
+ if (!groupAllowances[key])
2737
+ groupAllowances[key] = [];
2738
+ groupAllowances[key].push({ paths, ruleNames });
2739
+ }
2740
+ }
2741
+ const pathToStatement = (path) => {
2742
+ const isPrefix = path.endsWith("*");
2743
+ return {
2744
+ byteMatchStatement: {
2745
+ fieldToMatch: { uriPath: {} },
2746
+ positionalConstraint: isPrefix ? "STARTS_WITH" : "EXACTLY",
2747
+ searchString: isPrefix ? path.slice(0, -1) : path,
2748
+ textTransformations: [{ priority: 0, type: "NONE" }],
2749
+ },
2750
+ };
2751
+ };
2752
+ const pathsToStatement = (paths) => {
2753
+ if (paths.length === 1)
2754
+ return pathToStatement(paths[0]);
2755
+ return {
2756
+ orStatement: { statements: paths.map(pathToStatement) },
2757
+ };
2758
+ };
2759
+ const andScopeDown = (base, extra) => base ? { andStatement: { statements: [base, extra] } } : extra;
2720
2760
  let priority = 0;
2721
2761
  const rules = [];
2722
2762
  // Add managed rule groups
2723
2763
  for (const ruleName of managedRules) {
2724
- const ruleActionOverrides = managedRuleOverrides?.[ruleName];
2725
- const scopeDownStatement = managedRuleScopeDowns?.[ruleName];
2764
+ const baseOverrides = managedRuleOverrides?.[ruleName];
2765
+ const baseScopeDown = managedRuleScopeDowns?.[ruleName];
2766
+ const allowances = groupAllowances[ruleName];
2767
+ if (!allowances || allowances.length === 0) {
2768
+ rules.push({
2769
+ name: ruleName,
2770
+ priority: priority++,
2771
+ overrideAction: { none: {} },
2772
+ statement: {
2773
+ managedRuleGroupStatement: {
2774
+ name: ruleName,
2775
+ vendorName: "AWS",
2776
+ ...(baseOverrides && { ruleActionOverrides: baseOverrides }),
2777
+ ...(baseScopeDown && { scopeDownStatement: baseScopeDown }),
2778
+ },
2779
+ },
2780
+ visibilityConfig: {
2781
+ cloudWatchMetricsEnabled: true,
2782
+ metricName: ruleName,
2783
+ sampledRequestsEnabled: true,
2784
+ },
2785
+ });
2786
+ continue;
2787
+ }
2788
+ // Emit one relaxed rule per allow entry that names this group
2789
+ allowances.forEach(({ paths, ruleNames }, index) => {
2790
+ const entryOverrides = ruleNames.map((n) => ({
2791
+ name: n,
2792
+ actionToUse: { count: {} },
2793
+ }));
2794
+ const combinedOverrides = [
2795
+ ...(baseOverrides ?? []),
2796
+ ...entryOverrides,
2797
+ ];
2798
+ const relaxedScopeDown = andScopeDown(baseScopeDown, pathsToStatement(paths));
2799
+ const relaxedName = `${ruleName}-allow-${index}`;
2800
+ rules.push({
2801
+ name: relaxedName,
2802
+ priority: priority++,
2803
+ overrideAction: { none: {} },
2804
+ statement: {
2805
+ managedRuleGroupStatement: {
2806
+ name: ruleName,
2807
+ vendorName: "AWS",
2808
+ ruleActionOverrides: combinedOverrides,
2809
+ scopeDownStatement: relaxedScopeDown,
2810
+ },
2811
+ },
2812
+ visibilityConfig: {
2813
+ cloudWatchMetricsEnabled: true,
2814
+ metricName: relaxedName,
2815
+ sampledRequestsEnabled: true,
2816
+ },
2817
+ });
2818
+ });
2819
+ // Emit one strict rule whose scope-down excludes every relaxed path
2820
+ const allPaths = allowances.flatMap((a) => a.paths);
2821
+ const strictScopeDown = andScopeDown(baseScopeDown, {
2822
+ notStatement: { statement: pathsToStatement(allPaths) },
2823
+ });
2726
2824
  rules.push({
2727
2825
  name: ruleName,
2728
2826
  priority: priority++,
@@ -2731,8 +2829,8 @@ class JaypieDistribution extends constructs.Construct {
2731
2829
  managedRuleGroupStatement: {
2732
2830
  name: ruleName,
2733
2831
  vendorName: "AWS",
2734
- ...(ruleActionOverrides && { ruleActionOverrides }),
2735
- ...(scopeDownStatement && { scopeDownStatement }),
2832
+ ...(baseOverrides && { ruleActionOverrides: baseOverrides }),
2833
+ scopeDownStatement: strictScopeDown,
2736
2834
  },
2737
2835
  },
2738
2836
  visibilityConfig: {
@@ -3348,8 +3446,8 @@ class JaypieGitHubDeployRole extends constructs.Construct {
3348
3446
  }
3349
3447
  const sponsor = propsSponsor || process.env.PROJECT_SPONSOR || envRepoOrganization;
3350
3448
  // Create the IAM role
3351
- this._role = new awsIam.Role(this, "GitHubActionsRole", {
3352
- assumedBy: new awsIam.FederatedPrincipal(oidcProviderArn, {
3449
+ this._role = new iam.Role(this, "GitHubActionsRole", {
3450
+ assumedBy: new iam.FederatedPrincipal(oidcProviderArn, {
3353
3451
  StringLike: {
3354
3452
  "token.actions.githubusercontent.com:sub": repoRestriction,
3355
3453
  },
@@ -3359,12 +3457,12 @@ class JaypieGitHubDeployRole extends constructs.Construct {
3359
3457
  });
3360
3458
  cdk.Tags.of(this._role).add(CDK$2.TAG.ROLE, CDK$2.ROLE.DEPLOY);
3361
3459
  // Allow the role to access the GitHub OIDC provider
3362
- this._role.addToPolicy(new awsIam.PolicyStatement({
3460
+ this._role.addToPolicy(new iam.PolicyStatement({
3363
3461
  actions: ["sts:AssumeRoleWithWebIdentity"],
3364
3462
  resources: [`arn:aws:iam::${accountId}:oidc-provider/*`],
3365
3463
  }));
3366
3464
  // Allow the role to deploy CDK apps
3367
- this._role.addToPolicy(new awsIam.PolicyStatement({
3465
+ this._role.addToPolicy(new iam.PolicyStatement({
3368
3466
  actions: [
3369
3467
  "cloudformation:CreateStack",
3370
3468
  "cloudformation:DeleteStack",
@@ -3381,12 +3479,12 @@ class JaypieGitHubDeployRole extends constructs.Construct {
3381
3479
  "ssm:GetParameter",
3382
3480
  "ssm:GetParameters",
3383
3481
  ],
3384
- effect: awsIam.Effect.ALLOW,
3482
+ effect: iam.Effect.ALLOW,
3385
3483
  resources: ["*"],
3386
3484
  }));
3387
- this._role.addToPolicy(new awsIam.PolicyStatement({
3485
+ this._role.addToPolicy(new iam.PolicyStatement({
3388
3486
  actions: ["iam:PassRole", "sts:AssumeRole"],
3389
- effect: awsIam.Effect.ALLOW,
3487
+ effect: iam.Effect.ALLOW,
3390
3488
  resources: [
3391
3489
  "arn:aws:iam::*:role/cdk-hnb659fds-deploy-role-*",
3392
3490
  "arn:aws:iam::*:role/cdk-hnb659fds-file-publishing-*",
@@ -3399,14 +3497,14 @@ class JaypieGitHubDeployRole extends constructs.Construct {
3399
3497
  if (!sponsor) {
3400
3498
  throw new errors.ConfigurationError("Cannot grant default ECR permissions without a sponsor. Set sponsor prop, PROJECT_SPONSOR, CDK_ENV_REPO, or PROJECT_REPO, or pass `ecr: false`");
3401
3499
  }
3402
- this._role.addToPolicy(new awsIam.PolicyStatement({
3500
+ this._role.addToPolicy(new iam.PolicyStatement({
3403
3501
  actions: ["ecr:GetAuthorizationToken"],
3404
- effect: awsIam.Effect.ALLOW,
3502
+ effect: iam.Effect.ALLOW,
3405
3503
  resources: ["*"],
3406
3504
  }));
3407
- this._role.addToPolicy(new awsIam.PolicyStatement({
3505
+ this._role.addToPolicy(new iam.PolicyStatement({
3408
3506
  actions: ECR_PUSH_ACTIONS,
3409
- effect: awsIam.Effect.ALLOW,
3507
+ effect: iam.Effect.ALLOW,
3410
3508
  resources: [`arn:aws:ecr:*:${accountId}:repository/${sponsor}-*`],
3411
3509
  }));
3412
3510
  }
@@ -3560,11 +3658,18 @@ class JaypieInfrastructureStack extends JaypieStack {
3560
3658
  }
3561
3659
  }
3562
3660
 
3661
+ const DYNAMODB_CONTROL_PLANE_ACTIONS = [
3662
+ "dynamodb:DescribeContinuousBackups",
3663
+ "dynamodb:DescribeTable",
3664
+ "dynamodb:DescribeTimeToLive",
3665
+ "dynamodb:UpdateContinuousBackups",
3666
+ "dynamodb:UpdateTable",
3667
+ "dynamodb:UpdateTimeToLive",
3668
+ ];
3563
3669
  class JaypieMigration extends constructs.Construct {
3564
3670
  constructor(scope, id, props) {
3565
3671
  super(scope, id);
3566
- const { code, dependencies = [], environment, handler = "index.handler", secrets = [], tables = [], } = props;
3567
- // Migration Lambda — 5 minute timeout for long-running migrations
3672
+ const { code, dependencies = [], environment, handler = "index.handler", secrets = [], tables = [], timeout = cdk__namespace.Duration.minutes(15), } = props;
3568
3673
  this.lambda = new JaypieLambda(this, "MigrationLambda", {
3569
3674
  code,
3570
3675
  description: "DynamoDB migration custom resource",
@@ -3573,8 +3678,20 @@ class JaypieMigration extends constructs.Construct {
3573
3678
  roleTag: CDK$2.ROLE.PROCESSING,
3574
3679
  secrets,
3575
3680
  tables,
3576
- timeout: cdk__namespace.Duration.minutes(5),
3681
+ timeout,
3577
3682
  });
3683
+ // Grant control-plane perms on the passed tables so migrations that
3684
+ // alter table shape (GSIs, TTL, streams, backups) succeed. JaypieLambda
3685
+ // only grants data-plane access via grantReadWriteData. Issue #339.
3686
+ if (tables.length > 0) {
3687
+ this.lambda.addToRolePolicy(new iam__namespace.PolicyStatement({
3688
+ actions: DYNAMODB_CONTROL_PLANE_ACTIONS,
3689
+ resources: tables.flatMap((table) => [
3690
+ table.tableArn,
3691
+ `${table.tableArn}/index/*`,
3692
+ ]),
3693
+ }));
3694
+ }
3578
3695
  // Custom Resource provider wrapping the Lambda
3579
3696
  const provider = new cr__namespace.Provider(this, "MigrationProvider", {
3580
3697
  onEventHandler: this.lambda,
@@ -3837,21 +3954,21 @@ class JaypieOrganizationTrail extends constructs.Construct {
3837
3954
  ],
3838
3955
  });
3839
3956
  // Add CloudTrail bucket policies
3840
- this.bucket.addToResourcePolicy(new awsIam.PolicyStatement({
3957
+ this.bucket.addToResourcePolicy(new iam.PolicyStatement({
3841
3958
  actions: ["s3:GetBucketAcl"],
3842
- effect: awsIam.Effect.ALLOW,
3843
- principals: [new awsIam.ServicePrincipal("cloudtrail.amazonaws.com")],
3959
+ effect: iam.Effect.ALLOW,
3960
+ principals: [new iam.ServicePrincipal("cloudtrail.amazonaws.com")],
3844
3961
  resources: [this.bucket.bucketArn],
3845
3962
  }));
3846
- this.bucket.addToResourcePolicy(new awsIam.PolicyStatement({
3963
+ this.bucket.addToResourcePolicy(new iam.PolicyStatement({
3847
3964
  actions: ["s3:PutObject"],
3848
3965
  conditions: {
3849
3966
  StringEquals: {
3850
3967
  "s3:x-amz-acl": "bucket-owner-full-control",
3851
3968
  },
3852
3969
  },
3853
- effect: awsIam.Effect.ALLOW,
3854
- principals: [new awsIam.ServicePrincipal("cloudtrail.amazonaws.com")],
3970
+ effect: iam.Effect.ALLOW,
3971
+ principals: [new iam.ServicePrincipal("cloudtrail.amazonaws.com")],
3855
3972
  resources: [`${this.bucket.bucketArn}/*`],
3856
3973
  }));
3857
3974
  // Add tags to bucket
@@ -3966,9 +4083,9 @@ class JaypieSsoPermissions extends constructs.Construct {
3966
4083
  ],
3967
4084
  },
3968
4085
  managedPolicies: [
3969
- awsIam.ManagedPolicy.fromAwsManagedPolicyName("AdministratorAccess")
4086
+ iam.ManagedPolicy.fromAwsManagedPolicyName("AdministratorAccess")
3970
4087
  .managedPolicyArn,
3971
- awsIam.ManagedPolicy.fromAwsManagedPolicyName("AWSManagementConsoleBasicUserAccess").managedPolicyArn,
4088
+ iam.ManagedPolicy.fromAwsManagedPolicyName("AWSManagementConsoleBasicUserAccess").managedPolicyArn,
3972
4089
  ],
3973
4090
  sessionDuration: cdk.Duration.hours(1).toIsoString(),
3974
4091
  tags: [
@@ -4047,10 +4164,10 @@ class JaypieSsoPermissions extends constructs.Construct {
4047
4164
  ],
4048
4165
  },
4049
4166
  managedPolicies: [
4050
- awsIam.ManagedPolicy.fromAwsManagedPolicyName("AmazonQDeveloperAccess")
4167
+ iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonQDeveloperAccess")
4051
4168
  .managedPolicyArn,
4052
- awsIam.ManagedPolicy.fromAwsManagedPolicyName("AWSManagementConsoleBasicUserAccess").managedPolicyArn,
4053
- awsIam.ManagedPolicy.fromAwsManagedPolicyName("ReadOnlyAccess")
4169
+ iam.ManagedPolicy.fromAwsManagedPolicyName("AWSManagementConsoleBasicUserAccess").managedPolicyArn,
4170
+ iam.ManagedPolicy.fromAwsManagedPolicyName("ReadOnlyAccess")
4054
4171
  .managedPolicyArn,
4055
4172
  ],
4056
4173
  sessionDuration: cdk.Duration.hours(12).toIsoString(),
@@ -4109,12 +4226,12 @@ class JaypieSsoPermissions extends constructs.Construct {
4109
4226
  ],
4110
4227
  },
4111
4228
  managedPolicies: [
4112
- awsIam.ManagedPolicy.fromAwsManagedPolicyName("AmazonQDeveloperAccess")
4229
+ iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonQDeveloperAccess")
4113
4230
  .managedPolicyArn,
4114
- awsIam.ManagedPolicy.fromAwsManagedPolicyName("AWSManagementConsoleBasicUserAccess").managedPolicyArn,
4115
- awsIam.ManagedPolicy.fromAwsManagedPolicyName("ReadOnlyAccess")
4231
+ iam.ManagedPolicy.fromAwsManagedPolicyName("AWSManagementConsoleBasicUserAccess").managedPolicyArn,
4232
+ iam.ManagedPolicy.fromAwsManagedPolicyName("ReadOnlyAccess")
4116
4233
  .managedPolicyArn,
4117
- awsIam.ManagedPolicy.fromAwsManagedPolicyName("job-function/SystemAdministrator").managedPolicyArn,
4234
+ iam.ManagedPolicy.fromAwsManagedPolicyName("job-function/SystemAdministrator").managedPolicyArn,
4118
4235
  ],
4119
4236
  sessionDuration: cdk.Duration.hours(4).toIsoString(),
4120
4237
  tags: [
@@ -4345,8 +4462,8 @@ class JaypieWebDeploymentBucket extends constructs.Construct {
4345
4462
  }
4346
4463
  let bucketDeployRole;
4347
4464
  if (repo) {
4348
- bucketDeployRole = new awsIam.Role(this, "DestinationBucketDeployRole", {
4349
- assumedBy: new awsIam.FederatedPrincipal(cdk.Fn.importValue(CDK$2.IMPORT.OIDC_PROVIDER), {
4465
+ bucketDeployRole = new iam.Role(this, "DestinationBucketDeployRole", {
4466
+ assumedBy: new iam.FederatedPrincipal(cdk.Fn.importValue(CDK$2.IMPORT.OIDC_PROVIDER), {
4350
4467
  StringLike: {
4351
4468
  "token.actions.githubusercontent.com:sub": repo,
4352
4469
  },
@@ -4355,8 +4472,8 @@ class JaypieWebDeploymentBucket extends constructs.Construct {
4355
4472
  });
4356
4473
  cdk.Tags.of(bucketDeployRole).add(CDK$2.TAG.ROLE, CDK$2.ROLE.DEPLOY);
4357
4474
  // Allow the role to write to the bucket
4358
- bucketDeployRole.addToPolicy(new awsIam.PolicyStatement({
4359
- effect: awsIam.Effect.ALLOW,
4475
+ bucketDeployRole.addToPolicy(new iam.PolicyStatement({
4476
+ effect: iam.Effect.ALLOW,
4360
4477
  actions: [
4361
4478
  "s3:DeleteObject",
4362
4479
  "s3:GetObject",
@@ -4365,16 +4482,16 @@ class JaypieWebDeploymentBucket extends constructs.Construct {
4365
4482
  ],
4366
4483
  resources: [`${this.bucket.bucketArn}/*`],
4367
4484
  }));
4368
- bucketDeployRole.addToPolicy(new awsIam.PolicyStatement({
4369
- effect: awsIam.Effect.ALLOW,
4485
+ bucketDeployRole.addToPolicy(new iam.PolicyStatement({
4486
+ effect: iam.Effect.ALLOW,
4370
4487
  actions: ["s3:ListBucket"],
4371
4488
  resources: [this.bucket.bucketArn],
4372
4489
  }));
4373
4490
  // Allow the role to describe the current stack
4374
4491
  const stack = cdk.Stack.of(this);
4375
- bucketDeployRole.addToPolicy(new awsIam.PolicyStatement({
4492
+ bucketDeployRole.addToPolicy(new iam.PolicyStatement({
4376
4493
  actions: ["cloudformation:DescribeStacks"],
4377
- effect: awsIam.Effect.ALLOW,
4494
+ effect: iam.Effect.ALLOW,
4378
4495
  resources: [
4379
4496
  `arn:aws:cloudformation:${stack.region}:${stack.account}:stack/${stack.stackName}/*`,
4380
4497
  ],
@@ -4561,8 +4678,8 @@ class JaypieWebDeploymentBucket extends constructs.Construct {
4561
4678
  });
4562
4679
  // Add CloudFront invalidation permission to deploy role if it exists
4563
4680
  if (bucketDeployRole) {
4564
- bucketDeployRole.addToPolicy(new awsIam.PolicyStatement({
4565
- effect: awsIam.Effect.ALLOW,
4681
+ bucketDeployRole.addToPolicy(new iam.PolicyStatement({
4682
+ effect: iam.Effect.ALLOW,
4566
4683
  actions: ["cloudfront:CreateInvalidation"],
4567
4684
  resources: [
4568
4685
  `arn:aws:cloudfront::${cdk.Stack.of(this).account}:distribution/${this.distribution.distributionId}`,