aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.81k stars 819 forks source link

IAM policy missing s3:PutPublicAccessBlock action for adding custom resource that includes an S3 bucket via CDK #10062

Closed acusti closed 2 years ago

acusti commented 2 years ago

Before opening, please confirm:

How did you install the Amplify CLI?

yarn

If applicable, what version of Node.js are you using?

v17.3.0

Amplify CLI Version

7.6.26

What operating system are you using?

Mac

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

No manual changes made

Amplify Categories

custom

Amplify Commands

push

Describe the bug

i am trying to add a custom CDK stack to my amplify app. in the cdk-stack.ts file, i am creating a few different S3 buckets. here’s an example of one of those:

        const logsBucket = new s3.Bucket(this, 'Logs', {
            encryption: s3.BucketEncryption.S3_MANAGED,
            publicReadAccess: false,
            blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
        });

however, with that setup, when i try to deploy the stack using amplify push, i see this error in the logs:

CREATE_FAILED Logs1234AA11                              AWS::S3::Bucket           Thu Mar 24 2022 10:00:00 GMT-0700 (Pacific Daylight Time) API: s3:PutPublicAccessBlock Access Denied

it looks like this error is due to initializing the bucket with the blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL option, and it seems like the fix is just to add that action to the amplify IAM policy. the docs reference for the IAM policy states:

You can grant or restrict category permissions by including or removing items from the Action section as appropriate

however, i’m not sure how i’m supposed to update that policy. when i look in IAM in the console, AdministratorAccess-Amplify policy is read-only because it is an AWS Managed Policy. is there some place in the docs that covers this? should this permission be a part of the main amplify IAM policy? i added a new policy that included that action and attached it amplify-user alongside the AdministratorAccess-Amplify policy, but i still get the same error on running amplify push.

an aside: the logs refer to PutPublicAccessBlock, the S3 Actions API Reference includes it, but IAM doesn’t recognize it; instead, it has PutAccessPointPublicAccessBlock, PutAccountPublicAccessBlock, and PutBucketPublicAccessBlock. i’m guessing that PutBucketPublicAccessBlock is the action i need for my particular use case, but i’m not sure about that. i added all 3 permissions to the policy i created.


i ran into two other access denied permissions issues while trying to deploy the custom stack. one is with creating a CloudFront instance; when i use insertHttpSecurityHeaders: true, i get:

Access denied for operation 'User: arn:aws:sts::012345678901:assumed-role/us-east-1_ABcdef0Ab_Full-access/amplifyadmin is not authorized to perform: cloudfront:CreateFunction on resource: arn:aws:cloudfront::012345678901:function/* because no identity-based policy allows the cloudfront:CreateFunction action

lastly, adapting the scaffolded code to create a SNS topic and add an email subscription to it for my purposes, i get:

User: arn:aws:sts::012345678901:assumed-role/us-east-1_ABcdef0Ab_Full-access/amplifyadmin is not authorized to perform: SNS:GetTopicAttributes on resource: arn:aws:sns:us-east-1:012345678901:sns-topic-main because no identity-based policy allows the SNS:GetTopicAttributes action

the only addition i made to the default code was to output the SNS topic:

        new cdk.CfnOutput(this, 'SnsTopic', {
            value: snsTopic.topicName,
            description: 'SNS Topic used for the custom resources stack',
            exportName: `${projectName}-SnsTopic`,
        });

Expected behavior

i expected to be able to amplify push my custom CDK stack including S3 buckets, a CloudFront instance, and an SNS topic and subscription, without errors.

Reproduction steps

  1. in an existing amplify app, run amplify add custom

  2. give it a name and choose CDK

  3. add/uncomment import * as s3 from '@aws-cdk/aws-s3'; in cdk-stack.ts and add to the constructor:

        const bucket = new s3.Bucket(this, 'Bucket', {
            encryption: s3.BucketEncryption.S3_MANAGED,
            publicReadAccess: false,
            blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
        });
  4. run amplify push


my code for creating the SNS topic and subscribing to it (where EMAIL ADDRESS HERE is an actual email address):

import * as subs from '@aws-cdk/aws-sns-subscriptions';
import * as sns from '@aws-cdk/aws-sns';
// ... then in the constructor:
        const snsTopicResourceNamePrefix = `sns-topic-${amplifyProjectInfo.projectName}`;
        const snsTopic = new sns.Topic(this, 'sns-topic', {
            topicName: `${snsTopicResourceNamePrefix}-${cdk.Fn.ref('env')}`,
        });

        /**
         * Subscribe the admin email address to the SNS topic
         */
        snsTopic.addSubscription(new subs.EmailSubscription('<EMAIL ADDRESS HERE>'));

        new cdk.CfnOutput(this, 'SnsTopic', {
            value: snsTopic.topicName,
            description:
                'SNS Topic used to capture the VOD workflow outputs including errors',
            exportName: `${projectName}-SnsTopic`,
        });

and for creating the CloudFront distribution connected to an S3 bucket (resulting in access denied due to missing cloudfront:CreateFunction permission):

import * as s3 from '@aws-cdk/aws-s3';
import { CloudFrontToS3 } from '@aws-solutions-constructs/aws-cloudfront-s3';
// ... then in the constructor:
        /**
         * Destination S3 bucket
         */
        const destination = new s3.Bucket(this, 'Destination', {
            serverAccessLogsBucket: logsBucket,
            serverAccessLogsPrefix: 'destination-bucket-logs/',
            encryption: s3.BucketEncryption.S3_MANAGED,
            publicReadAccess: false,
            blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
            cors: [
                {
                    maxAge: 3000,
                    allowedOrigins: ['*'],
                    allowedHeaders: ['*'],
                    allowedMethods: [s3.HttpMethods.GET],
                },
            ],
        });
        /**
         * Solution construct to create CloudFront with an S3 bucket as the origin
         * https://docs.aws.amazon.com/solutions/latest/constructs/aws-cloudfront-s3.html
         */
        const cloudFront = new CloudFrontToS3(this, 'CloudFront', {
            // @ts-ignore CloudFrontToS3Props is missing this key:
            existingBucketObj: destination,
            insertHttpSecurityHeaders: true, // set to false if region isn’t us-east-1
            cloudFrontDistributionProps: {
                comment: `${projectName} CloudFront Distribution`,
                defaultCacheBehavior: {
                    allowedMethods: ['GET', 'HEAD', 'OPTIONS'],
                    Compress: false,
                    forwardedValues: {
                        queryString: false,
                        headers: [
                            'Origin',
                            'Access-Control-Request-Method',
                            'Access-Control-Request-Headers',
                        ],
                        cookies: { forward: 'none' },
                    },
                    viewerProtocolPolicy: 'allow-all',
                },
            },
        });

GraphQL schema(s)

```graphql # Put schemas below this line ```

Log output

``` # Put your logs below this line ```

Additional information

No response

acusti commented 2 years ago

i just tried commenting out blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL, and now i get an error due to specifying serverAccessLogsBucket when creating a bucket, e.g.:

        const destination = new s3.Bucket(this, 'Destination', {
            serverAccessLogsBucket: logsBucket,
            serverAccessLogsPrefix: 'destination-bucket-logs/',
            encryption: s3.BucketEncryption.S3_MANAGED,
            publicReadAccess: false,
            // blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
            cors: [
                {
                    maxAge: 3000,
                    allowedOrigins: ['*'],
                    allowedHeaders: ['*'],
                    allowedMethods: [s3.HttpMethods.GET],
                },
            ],
        });

the error logs:

CREATE_FAILED Destination123AB456 AWS::S3::Bucket Thu Mar 24 2022 17:00:00 GMT-0700 (Pacific Daylight Time) API: s3:PutBucketLogging Access Denied

i also tried removing the SnsTopic Cfn.Output, but i still get the amplifyadmin is not authorized to perform: SNS:GetTopicAttributes error when running amplify push.

ykethan commented 2 years ago

Hello @acusti, Thank you for reaching out. Apologies for the delay in a response. Could you please check your current IAM polices to see they are similar to the IAM permissions outlined the following document. https://docs.amplify.aws/cli/reference/iam/

Additonally, from the information provided the application currently requires 3 permissions added as a inline policy item to your CLI IAM user. As when using custom the AdministratorAccess-Amplify managed policy may not have all the permissions required to add the custom resource.

Could you please let me know if your project is using a profile based access. If it is not using a profile, I would suggest using a profile based access and modifying your IAM user with the required permissions.

acusti commented 2 years ago

@ykethan thanks for the reply! i dug into this further based on your questions and discovered that the IAM user that i thought was being used by the amplify CLI actually hasn’t been active for over 6 months. that led me to use the amplify managed policy (arn:aws:iam::aws:policy/AdministratorAccess-Amplify) Policy Usage tab to see what IAM entities use that policy, and i was then able to figure out which role is being used by the CLI (it’s named like <AWS region>_AbcdE1234_Full-access). when i attached my custom policy to that role and granted it a bunch of mediaconvert permissions plus the missing S3 privileges, the custom-policies.json started working, though there were still a bunch of gotchas. for example, when i tried to grant iam:PassRole for a wildcard resource ARN, it didn’t work. i needed to included my account number in it to get it to be translated to a permission that i could then see when looking at the lambda in the console.

ykethan commented 2 years ago

hello @acusti, glad to hear to hear your are back up and running. I am interested to see what the current IAM polices are, Could you please provide me an example of your IAM policies attached. As i noticed that the full-access role is a role created by amplify studio.

acusti commented 2 years ago

my Full-access role by default has the AdministratorAccess-Amplify policy, which is an AWS managed policy, and a Full-access-Policy policy, which is of type Customer inline.

here’s the complete policy JSON for the AdministratorAccess-Amplify policy: ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "CLICloudformationPolicy", "Effect": "Allow", "Action": [ "cloudformation:CreateChangeSet", "cloudformation:CreateStack", "cloudformation:DeleteStack", "cloudformation:DescribeChangeSet", "cloudformation:DescribeStackEvents", "cloudformation:DescribeStackResource", "cloudformation:DescribeStackResources", "cloudformation:DescribeStacks", "cloudformation:ExecuteChangeSet", "cloudformation:GetTemplate", "cloudformation:UpdateStack", "cloudformation:ListStackResources", "cloudformation:DeleteStackSet", "cloudformation:DescribeStackSet", "cloudformation:UpdateStackSet" ], "Resource": [ "arn:aws:cloudformation:*:*:stack/amplify-*" ] }, { "Sid": "CLIManageviaCFNPolicy", "Effect": "Allow", "Action": [ "iam:ListRoleTags", "iam:TagRole", "iam:AttachRolePolicy", "iam:CreatePolicy", "iam:DeletePolicy", "iam:DeleteRole", "iam:DeleteRolePolicy", "iam:DetachRolePolicy", "iam:PutRolePolicy", "iam:UpdateRole", "iam:GetRole", "iam:GetPolicy", "iam:GetRolePolicy", "iam:PassRole", "iam:ListPolicyVersions", "iam:CreatePolicyVersion", "iam:DeletePolicyVersion", "iam:CreateRole", "iam:ListRolePolicies", "iam:PutRolePermissionsBoundary", "iam:DeleteRolePermissionsBoundary", "appsync:CreateApiKey", "appsync:CreateDataSource", "appsync:CreateFunction", "appsync:CreateResolver", "appsync:CreateType", "appsync:DeleteApiKey", "appsync:DeleteDataSource", "appsync:DeleteFunction", "appsync:DeleteResolver", "appsync:DeleteType", "appsync:GetDataSource", "appsync:GetFunction", "appsync:GetIntrospectionSchema", "appsync:GetResolver", "appsync:GetSchemaCreationStatus", "appsync:GetType", "appsync:GraphQL", "appsync:ListApiKeys", "appsync:ListDataSources", "appsync:ListFunctions", "appsync:ListGraphqlApis", "appsync:ListResolvers", "appsync:ListResolversByFunction", "appsync:ListTypes", "appsync:StartSchemaCreation", "appsync:UpdateApiKey", "appsync:UpdateDataSource", "appsync:UpdateFunction", "appsync:UpdateResolver", "appsync:UpdateType", "appsync:TagResource", "appsync:CreateGraphqlApi", "appsync:DeleteGraphqlApi", "appsync:GetGraphqlApi", "appsync:ListTagsForResource", "appsync:UpdateGraphqlApi", "apigateway:DELETE", "apigateway:GET", "apigateway:PATCH", "apigateway:POST", "apigateway:PUT", "cognito-idp:CreateUserPool", "cognito-identity:CreateIdentityPool", "cognito-identity:DeleteIdentityPool", "cognito-identity:DescribeIdentity", "cognito-identity:DescribeIdentityPool", "cognito-identity:SetIdentityPoolRoles", "cognito-identity:GetIdentityPoolRoles", "cognito-identity:UpdateIdentityPool", "cognito-idp:CreateUserPoolClient", "cognito-idp:DeleteUserPool", "cognito-idp:DeleteUserPoolClient", "cognito-idp:DescribeUserPool", "cognito-idp:DescribeUserPoolClient", "cognito-idp:ListTagsForResource", "cognito-idp:ListUserPoolClients", "cognito-idp:UpdateUserPoolClient", "cognito-idp:CreateGroup", "cognito-idp:DeleteGroup", "cognito-identity:TagResource", "cognito-idp:TagResource", "cognito-idp:UpdateUserPool", "cognito-idp:SetUserPoolMfaConfig", "lambda:AddPermission", "lambda:CreateFunction", "lambda:DeleteFunction", "lambda:GetFunction", "lambda:GetFunctionConfiguration", "lambda:InvokeAsync", "lambda:InvokeFunction", "lambda:RemovePermission", "lambda:UpdateFunctionCode", "lambda:UpdateFunctionConfiguration", "lambda:ListTags", "lambda:TagResource", "lambda:UntagResource", "lambda:AddLayerVersionPermission", "lambda:CreateEventSourceMapping", "lambda:DeleteEventSourceMapping", "lambda:DeleteLayerVersion", "lambda:GetEventSourceMapping", "lambda:GetLayerVersion", "lambda:ListEventSourceMappings", "lambda:ListLayerVersions", "lambda:PublishLayerVersion", "lambda:RemoveLayerVersionPermission", "lambda:UpdateEventSourceMapping", "dynamodb:CreateTable", "dynamodb:DeleteItem", "dynamodb:DeleteTable", "dynamodb:DescribeContinuousBackups", "dynamodb:DescribeTable", "dynamodb:DescribeTimeToLive", "dynamodb:ListStreams", "dynamodb:PutItem", "dynamodb:TagResource", "dynamodb:ListTagsOfResource", "dynamodb:UpdateContinuousBackups", "dynamodb:UpdateItem", "dynamodb:UpdateTable", "dynamodb:UpdateTimeToLive", "s3:CreateBucket", "s3:ListBucket", "s3:PutBucketAcl", "s3:PutBucketCORS", "s3:PutBucketNotification", "s3:PutBucketPolicy", "s3:PutBucketWebsite", "s3:PutObjectAcl", "cloudfront:CreateCloudFrontOriginAccessIdentity", "cloudfront:CreateDistribution", "cloudfront:DeleteCloudFrontOriginAccessIdentity", "cloudfront:DeleteDistribution", "cloudfront:GetCloudFrontOriginAccessIdentity", "cloudfront:GetCloudFrontOriginAccessIdentityConfig", "cloudfront:GetDistribution", "cloudfront:GetDistributionConfig", "cloudfront:TagResource", "cloudfront:UntagResource", "cloudfront:UpdateCloudFrontOriginAccessIdentity", "cloudfront:UpdateDistribution", "events:DeleteRule", "events:DescribeRule", "events:ListRuleNamesByTarget", "events:PutRule", "events:PutTargets", "events:RemoveTargets", "mobiletargeting:GetApp", "kinesis:AddTagsToStream", "kinesis:CreateStream", "kinesis:DeleteStream", "kinesis:DescribeStream", "kinesis:DescribeStreamSummary", "kinesis:ListTagsForStream", "kinesis:PutRecords", "es:AddTags", "es:CreateElasticsearchDomain", "es:DeleteElasticsearchDomain", "es:DescribeElasticsearchDomain", "s3:PutEncryptionConfiguration" ], "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "aws:CalledVia": [ "cloudformation.amazonaws.com" ] } } }, { "Sid": "CLISDKCalls", "Effect": "Allow", "Action": [ "appsync:GetIntrospectionSchema", "appsync:GraphQL", "appsync:UpdateApiKey", "appsync:ListApiKeys", "amplify:*", "amplifybackend:*", "amplifyuibuilder:*", "sts:AssumeRole", "mobiletargeting:*", "cognito-idp:AdminAddUserToGroup", "cognito-idp:AdminCreateUser", "cognito-idp:CreateGroup", "cognito-idp:DeleteGroup", "cognito-idp:DeleteUser", "cognito-idp:ListUsers", "cognito-idp:AdminGetUser", "cognito-idp:ListUsersInGroup", "cognito-idp:AdminDisableUser", "cognito-idp:AdminRemoveUserFromGroup", "cognito-idp:AdminResetUserPassword", "cognito-idp:AdminListGroupsForUser", "cognito-idp:ListGroups", "cognito-idp:AdminListUserAuthEvents", "cognito-idp:AdminDeleteUser", "cognito-idp:AdminConfirmSignUp", "cognito-idp:AdminEnableUser", "cognito-idp:AdminUpdateUserAttributes", "cognito-idp:DescribeIdentityProvider", "cognito-idp:DescribeUserPool", "cognito-idp:DeleteUserPool", "cognito-idp:DescribeUserPoolClient", "cognito-idp:CreateUserPool", "cognito-idp:CreateUserPoolClient", "cognito-idp:UpdateUserPool", "cognito-idp:AdminSetUserPassword", "cognito-idp:ListUserPools", "cognito-idp:ListUserPoolClients", "cognito-idp:ListIdentityProviders", "cognito-idp:GetUserPoolMfaConfig", "cognito-identity:GetIdentityPoolRoles", "cognito-identity:SetIdentityPoolRoles", "cognito-identity:CreateIdentityPool", "cognito-identity:DeleteIdentityPool", "cognito-identity:ListIdentityPools", "cognito-identity:DescribeIdentityPool", "dynamodb:DescribeTable", "dynamodb:ListTables", "lambda:GetFunction", "lambda:CreateFunction", "lambda:AddPermission", "lambda:DeleteFunction", "lambda:DeleteLayerVersion", "lambda:InvokeFunction", "lambda:ListLayerVersions", "iam:PutRolePolicy", "iam:CreatePolicy", "iam:AttachRolePolicy", "iam:ListPolicyVersions", "iam:ListAttachedRolePolicies", "iam:CreateRole", "iam:PassRole", "iam:ListRolePolicies", "iam:DeleteRolePolicy", "iam:CreatePolicyVersion", "iam:DeletePolicyVersion", "iam:DeleteRole", "iam:DetachRolePolicy", "cloudformation:ListStacks", "sns:CreateSMSSandboxPhoneNumber", "sns:GetSMSSandboxAccountStatus", "sns:VerifySMSSandboxPhoneNumber", "sns:DeleteSMSSandboxPhoneNumber", "sns:ListSMSSandboxPhoneNumbers", "sns:ListOriginationNumbers", "rekognition:DescribeCollection", "logs:DescribeLogStreams", "logs:GetLogEvents", "lex:GetBot", "lex:GetBuiltinIntent", "lex:GetBuiltinIntents", "lex:GetBuiltinSlotTypes", "cloudformation:GetTemplateSummary", "codecommit:GitPull" ], "Resource": "*" }, { "Sid": "AmplifySSMCalls", "Effect": "Allow", "Action": [ "ssm:PutParameter", "ssm:DeleteParameter", "ssm:GetParametersByPath", "ssm:GetParameters", "ssm:GetParameter", "ssm:DeleteParameters" ], "Resource": "arn:aws:ssm:*:*:parameter/amplify/*" }, { "Sid": "GeoPowerUser", "Effect": "Allow", "Action": [ "geo:*" ], "Resource": "*" }, { "Sid": "AmplifyStorageSDKCalls", "Effect": "Allow", "Action": [ "s3:CreateBucket", "s3:DeleteBucket", "s3:DeleteBucketPolicy", "s3:DeleteBucketWebsite", "s3:DeleteObject", "s3:DeleteObjectVersion", "s3:GetBucketLocation", "s3:GetObject", "s3:ListAllMyBuckets", "s3:ListBucket", "s3:ListBucketVersions", "s3:PutBucketAcl", "s3:PutBucketCORS", "s3:PutBucketNotification", "s3:PutBucketPolicy", "s3:PutBucketVersioning", "s3:PutBucketWebsite", "s3:PutEncryptionConfiguration", "s3:PutLifecycleConfiguration", "s3:PutObject", "s3:PutObjectAcl" ], "Resource": "*" }, { "Sid": "AmplifySSRCalls", "Effect": "Allow", "Action": [ "cloudfront:CreateCloudFrontOriginAccessIdentity", "cloudfront:CreateDistribution", "cloudfront:CreateInvalidation", "cloudfront:GetDistribution", "cloudfront:GetDistributionConfig", "cloudfront:ListCloudFrontOriginAccessIdentities", "cloudfront:ListDistributions", "cloudfront:ListDistributionsByLambdaFunction", "cloudfront:ListDistributionsByWebACLId", "cloudfront:ListFieldLevelEncryptionConfigs", "cloudfront:ListFieldLevelEncryptionProfiles", "cloudfront:ListInvalidations", "cloudfront:ListPublicKeys", "cloudfront:ListStreamingDistributions", "cloudfront:UpdateDistribution", "cloudfront:TagResource", "cloudfront:UntagResource", "cloudfront:ListTagsForResource", "cloudfront:DeleteDistribution", "iam:AttachRolePolicy", "iam:CreateRole", "iam:CreateServiceLinkedRole", "iam:GetRole", "iam:PutRolePolicy", "iam:PassRole", "lambda:CreateFunction", "lambda:EnableReplication", "lambda:DeleteFunction", "lambda:GetFunction", "lambda:GetFunctionConfiguration", "lambda:PublishVersion", "lambda:UpdateFunctionCode", "lambda:UpdateFunctionConfiguration", "lambda:ListTags", "lambda:TagResource", "lambda:UntagResource", "route53:ChangeResourceRecordSets", "route53:ListHostedZonesByName", "route53:ListResourceRecordSets", "s3:CreateBucket", "s3:GetAccelerateConfiguration", "s3:GetObject", "s3:ListBucket", "s3:PutAccelerateConfiguration", "s3:PutBucketPolicy", "s3:PutObject", "s3:PutBucketTagging", "s3:GetBucketTagging", "lambda:ListEventSourceMappings", "lambda:CreateEventSourceMapping", "iam:UpdateAssumeRolePolicy", "iam:DeleteRolePolicy", "sqs:CreateQueue", "sqs:DeleteQueue", "sqs:GetQueueAttributes", "sqs:SetQueueAttributes", "amplify:GetApp", "amplify:GetBranch", "amplify:UpdateApp", "amplify:UpdateBranch" ], "Resource": "*" } ] } ```
and here’s the policy JSON for the inline Full-access-Policy: ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "CLICloudformationPolicy", "Effect": "Allow", "Action": [ "cloudformation:DeleteStackSet", "cloudformation:DescribeStackSet", "cloudformation:UpdateStackSet" ], "Resource": [ "arn:aws:cloudformation:*:*:stack/amplify-*" ] }, { "Sid": "CLIManageviaCFNPolicy", "Effect": "Allow", "Action": [ "cognito-idp:SetUserPoolMfaConfig" ], "Resource": "*", "Condition": { "ForAnyValue:StringEquals": { "aws:CalledVia": [ "cloudformation.amazonaws.com" ] } } }, { "Sid": "CLISDKCalls", "Effect": "Allow", "Action": [ "lambda:GetLayerVersionByArn", "rekognition:DescribeCollection", "logs:DescribeLogStreams", "logs:GetLogEvents", "lex:GetBot", "lex:GetBuiltinIntent", "lex:GetBuiltinIntents", "lex:GetBuiltinSlotTypes", "lambda:InvokeFunction", "cognito-idp:ListIdentityProviders", "cognito-idp:AddCustomAttributes", "cloudformation:ListStackResources", "lambda:UpdateEventSourceMapping" ], "Resource": "*" }, { "Sid": "CLISSMSDKCalls", "Effect": "Allow", "Action": [ "ssm:DeleteParameter", "ssm:DeleteParameters", "ssm:GetParameter", "ssm:GetParameters", "ssm:GetParametersByPath", "ssm:PutParameter" ], "Resource": "arn:aws:ssm:*:*:parameter/amplify/*" }, { "Sid": "GeoPowerUser", "Effect": "Allow", "Action": [ "geo:*" ], "Resource": "*" } ] } ```

in my application, i have added a video processing pipeline based on https://github.com/aws-solutions/video-on-demand-on-aws-foundations. the source S3 bucket is the one i added to amplify via amplify add storage, while the destination S3 bucket is created within a custom CDK stack (added via amplify add custom).

in order to make that all work, i created a “customer managed” policy that i added to the Full-access role that contains the following permissions: ```json { "Version": "2012-10-17", "Statement": [ { "Sid": "VisualEditor0", "Effect": "Allow", "Action": [ "mediaconvert:CancelJob", "mediaconvert:CreateJob", "mediaconvert:CreateJobTemplate", "mediaconvert:CreateQueue", "mediaconvert:DeleteJobTemplate", "mediaconvert:DeleteQueue", "mediaconvert:GetJob", "mediaconvert:UpdateJobTemplate", "mediaconvert:UpdateQueue" ], "Resource": [ "arn:aws:mediaconvert:*:000123456789:jobs/*", "arn:aws:mediaconvert:*:000123456789:jobTemplates/*", "arn:aws:mediaconvert:*:000123456789:presets/*", "arn:aws:mediaconvert:*:000123456789:queues/*" ] }, { "Sid": "VisualEditor1", "Effect": "Allow", "Action": [ "cloudfront:CreateFunction", "events:CreateEventBus", "events:TagResource", "s3:PutAccessPointPublicAccessBlock", "s3:PutAccountPublicAccessBlock", "s3:PutBucketPublicAccessBlock", "sns:GetTopicAttributes" ], "Resource": "*" } ] } ```
ykethan commented 2 years ago

hey, thank you for the information. This would make a great clarification on the documentation. where we will need to add custom polices for customer managed resources.

ykethan commented 2 years ago

The documentation has been updated clarifying the permissions required for custom resources. https://docs.amplify.aws/cli/custom/cdk/

closing the issue for now, please do reach out to us again.