fix: scope staging release bucket access

This commit is contained in:
Alexandre Brandizzi 2026-08-27 20:45:12 -03:00
parent 2fb9540aa0
commit caa8970b17
2 changed files with 16 additions and 18 deletions

View file

@ -291,9 +291,10 @@ instantiated in `app.ts` as stack `shoc-backend-deploy-staging`
`shoc-backend-staging`, CloudFormation mutations scoped to the EB-managed `shoc-backend-staging`, CloudFormation mutations scoped to the EB-managed
stack `awseb-e-6c9m4vb62z-stack`, Auto Scaling mutations scoped to the stack `awseb-e-6c9m4vb62z-stack`, Auto Scaling mutations scoped to the
`awseb-e-6c9m4vb62z-stack-*` ASG name prefix, and S3 limited to the existing `awseb-e-6c9m4vb62z-stack-*` ASG name prefix, and S3 limited to the existing
Elastic Beanstalk bucket namespace. It grants no dev resource, no IAM account bucket and `shoc-backend/` release-object prefix. The role can check
mutation, no `PassRole`, and no RDS/Secrets Manager access to the deploy that bucket and upload a version bundle; it cannot read, delete, or mutate
role. other objects or buckets. It grants no dev resource, no IAM mutation, no
`PassRole`, and no RDS/Secrets Manager access to the deploy role.
It references — and never creates, imports as CDK constructs, or modifies — the It references — and never creates, imports as CDK constructs, or modifies — the
existing Elastic Beanstalk application `shoc-backend`, environment existing Elastic Beanstalk application `shoc-backend`, environment

View file

@ -114,28 +114,25 @@ export class DeployStagingStack extends cdk.Stack {
deployRole.addToPolicy( deployRole.addToPolicy(
new iam.PolicyStatement({ new iam.PolicyStatement({
effect: iam.Effect.ALLOW, effect: iam.Effect.ALLOW,
actions: ['s3:Delete*', 's3:Get*', 's3:Put*'], actions: ['s3:PutObject'],
// AWS Support case 178526484500047 confirmed that UpdateEnvironment // The pinned deployment action writes exactly
// reads, writes, versions, ACL-checks, and removes objects in both the // shoc-backend/<version-label>.zip to the explicitly configured,
// account bucket and AWS-owned Elastic Beanstalk service buckets. // pre-existing account bucket. It never reads or deletes objects.
resources: ['arn:aws:s3:::elasticbeanstalk-*/*'], resources: [
`arn:aws:s3:::elasticbeanstalk-${REGION}-${ACCOUNT_ID}/${APPLICATION_NAME}/*`,
],
}), }),
); );
deployRole.addToPolicy( deployRole.addToPolicy(
new iam.PolicyStatement({ new iam.PolicyStatement({
effect: iam.Effect.ALLOW, effect: iam.Effect.ALLOW,
actions: [ // HeadBucket on the explicit existing bucket requires ListBucket.
's3:GetBucket*', // GetBucketLocation is retained for regional SDK compatibility.
's3:ListBucket', actions: ['s3:GetBucketLocation', 's3:ListBucket'],
's3:PutBucketOwnershipControls', resources: [
's3:PutBucketPolicy', `arn:aws:s3:::elasticbeanstalk-${REGION}-${ACCOUNT_ID}`,
's3:PutBucketPublicAccessBlock',
], ],
// This is AWS Support's bucket-level UpdateEnvironment set, excluding
// CreateBucket because the workflow deploys only to an existing
// application/environment and disables bucket creation.
resources: ['arn:aws:s3:::elasticbeanstalk-*'],
}), }),
); );