From 0243d405d0c3248fd99910f6156c590235f93299 Mon Sep 17 00:00:00 2001 From: Samson Keung Date: Fri, 17 Jan 2025 15:43:46 -0800 Subject: [PATCH 1/4] raise awareness for default policy risk --- .../@aws-cdk/aws-scheduler-targets-alpha/README.md | 11 +++++++---- .../aws-scheduler-targets-alpha/lib/universal.ts | 4 +++- .../test/universal.test.ts | 7 ++++++- 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md b/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md index 81858cd76e76f..bf59a5599d03b 100644 --- a/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md +++ b/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md @@ -316,7 +316,7 @@ new Schedule(this, 'Schedule', { ## Invoke a wider set of AWS API -Use the `Universal` target to invoke AWS API. +Use the `Universal` target to invoke AWS API. See https://docs.aws.amazon.com/scheduler/latest/UserGuide/managing-targets-universal.html The code snippet below creates an event rule with AWS API as the target which is called at midnight every day by EventBridge Scheduler. @@ -339,9 +339,9 @@ new Schedule(this, 'Schedule', { The `service` must be in lowercase and the `action` must be in camelCase. -By default, an IAM policy for the Scheduler is extracted from the API call. - -You can control the IAM policy for the Scheduler by specifying the `policyStatements` property. +By default, an IAM policy for the Scheduler is extracted from the API call. The action is the policy is constructed using the `service` and `action` prop. +Re-using the example above, the action will be `rds:stopDBCluster`. Note that not all IAM actions follow the same pattern. In such scenario, please use the +`policyStatments` prop to override the policy: ```ts new Schedule(this, 'Schedule', { @@ -362,3 +362,6 @@ new Schedule(this, 'Schedule', { }), }); ``` + +> Note: The default policy uses `*` in the resources field as CDK does not have a straight forward way to auto-discover the resources permission required. +> It is recommended that you scope the field down to specific resources to have a better security posture. diff --git a/packages/@aws-cdk/aws-scheduler-targets-alpha/lib/universal.ts b/packages/@aws-cdk/aws-scheduler-targets-alpha/lib/universal.ts index 03b8f6734d19f..cd0f3af5c3454 100644 --- a/packages/@aws-cdk/aws-scheduler-targets-alpha/lib/universal.ts +++ b/packages/@aws-cdk/aws-scheduler-targets-alpha/lib/universal.ts @@ -1,5 +1,5 @@ import { IScheduleTarget } from '@aws-cdk/aws-scheduler-alpha'; -import { Aws, Token } from 'aws-cdk-lib'; +import { Annotations, Aws, Token } from 'aws-cdk-lib'; import { IRole, PolicyStatement } from 'aws-cdk-lib/aws-iam'; import { awsSdkToIamAction } from 'aws-cdk-lib/custom-resources/lib/helpers-internal'; import { ScheduleTargetBase, ScheduleTargetBaseProps } from './target'; @@ -95,6 +95,8 @@ export class Universal extends ScheduleTargetBase implements IScheduleTarget { protected addTargetActionToRole(role: IRole): void { if (!this.props.policyStatements?.length) { + Annotations.of(role).addWarningV2('@aws-cdk/aws-scheduler-alpha:defaultWildcardResourcePolicy', + 'Default policy with * for resources is used. Use custom policy for better security posture.'); role.addToPrincipalPolicy(new PolicyStatement({ actions: [awsSdkToIamAction(this.props.service, this.props.action)], resources: ['*'], diff --git a/packages/@aws-cdk/aws-scheduler-targets-alpha/test/universal.test.ts b/packages/@aws-cdk/aws-scheduler-targets-alpha/test/universal.test.ts index 3f6ed17061c66..469181dafdeba 100644 --- a/packages/@aws-cdk/aws-scheduler-targets-alpha/test/universal.test.ts +++ b/packages/@aws-cdk/aws-scheduler-targets-alpha/test/universal.test.ts @@ -1,7 +1,7 @@ import * as scheduler from '@aws-cdk/aws-scheduler-alpha'; import { Group } from '@aws-cdk/aws-scheduler-alpha'; import { App, Duration, Stack } from 'aws-cdk-lib'; -import { Template } from 'aws-cdk-lib/assertions'; +import { Annotations, Template, Match } from 'aws-cdk-lib/assertions'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as sqs from 'aws-cdk-lib/aws-sqs'; import { Universal } from '../lib/universal'; @@ -105,6 +105,11 @@ describe('Universal schedule target', () => { ], }, }); + + Annotations.fromStack(stack).hasWarning( + '*', + 'Default policy with * for resources is used. Use custom policy for better security posture. [ack: @aws-cdk/aws-scheduler-alpha:defaultWildcardResourcePolicy]', + ); }); test('creates IAM policy for provided IAM role', () => { From 334bae984d312cd6eea9faad95f36253a31f4eb6 Mon Sep 17 00:00:00 2001 From: Samson Keung Date: Fri, 17 Jan 2025 15:46:20 -0800 Subject: [PATCH 2/4] typo fix --- packages/@aws-cdk/aws-scheduler-targets-alpha/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md b/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md index bf59a5599d03b..fde5ee574b1bf 100644 --- a/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md +++ b/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md @@ -339,7 +339,7 @@ new Schedule(this, 'Schedule', { The `service` must be in lowercase and the `action` must be in camelCase. -By default, an IAM policy for the Scheduler is extracted from the API call. The action is the policy is constructed using the `service` and `action` prop. +By default, an IAM policy for the Scheduler is extracted from the API call. The action in the policy is constructed using the `service` and `action` prop. Re-using the example above, the action will be `rds:stopDBCluster`. Note that not all IAM actions follow the same pattern. In such scenario, please use the `policyStatments` prop to override the policy: From 3e121a754b292a5aaf4cfef178c4c57ad4d2e2fb Mon Sep 17 00:00:00 2001 From: Samson Keung Date: Fri, 17 Jan 2025 15:47:16 -0800 Subject: [PATCH 3/4] Remove extra import that is not needed --- .../@aws-cdk/aws-scheduler-targets-alpha/test/universal.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-scheduler-targets-alpha/test/universal.test.ts b/packages/@aws-cdk/aws-scheduler-targets-alpha/test/universal.test.ts index 469181dafdeba..48dac4c693d5e 100644 --- a/packages/@aws-cdk/aws-scheduler-targets-alpha/test/universal.test.ts +++ b/packages/@aws-cdk/aws-scheduler-targets-alpha/test/universal.test.ts @@ -1,7 +1,7 @@ import * as scheduler from '@aws-cdk/aws-scheduler-alpha'; import { Group } from '@aws-cdk/aws-scheduler-alpha'; import { App, Duration, Stack } from 'aws-cdk-lib'; -import { Annotations, Template, Match } from 'aws-cdk-lib/assertions'; +import { Annotations, Template } from 'aws-cdk-lib/assertions'; import * as iam from 'aws-cdk-lib/aws-iam'; import * as sqs from 'aws-cdk-lib/aws-sqs'; import { Universal } from '../lib/universal'; From 2ad13ca88f6d989a9051a3a74a860f890ff75ba1 Mon Sep 17 00:00:00 2001 From: Samson Keung Date: Fri, 17 Jan 2025 16:09:51 -0800 Subject: [PATCH 4/4] Typo fix Co-authored-by: Grace Luo <54298030+gracelu0@users.noreply.github.com> --- packages/@aws-cdk/aws-scheduler-targets-alpha/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md b/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md index fde5ee574b1bf..1758f6e2fb87b 100644 --- a/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md +++ b/packages/@aws-cdk/aws-scheduler-targets-alpha/README.md @@ -341,7 +341,7 @@ The `service` must be in lowercase and the `action` must be in camelCase. By default, an IAM policy for the Scheduler is extracted from the API call. The action in the policy is constructed using the `service` and `action` prop. Re-using the example above, the action will be `rds:stopDBCluster`. Note that not all IAM actions follow the same pattern. In such scenario, please use the -`policyStatments` prop to override the policy: +`policyStatements` prop to override the policy: ```ts new Schedule(this, 'Schedule', {