mirror of
https://github.com/Sea-Haven-Industries/shoc-backend.git
synced 2026-10-07 16:19:07 +00:00
fix(cdk): model EB deployment capability
This commit is contained in:
parent
487684e3c9
commit
fa99240af5
2 changed files with 80 additions and 16 deletions
|
|
@ -77,9 +77,11 @@ The role grants only:
|
|||
`githubdeploy-shoc-backend-dev/GitHubActions` and was denied. It is scoped to
|
||||
the exact bucket-level ARN and grants no object access.
|
||||
|
||||
- `cloudformation:GetTemplate`, `cloudformation:DescribeStackResources`, and
|
||||
`cloudformation:ListStackResources` on the Elastic Beanstalk-managed
|
||||
CloudFormation stack `awseb-e-hehnrqjjrt-stack`, scoped to
|
||||
- The six CloudFormation discovery calls observed across the failed OIDC and
|
||||
successful administrator deployments (`DescribeStackEvents`,
|
||||
`DescribeStackResource`, `DescribeStackResources`, `DescribeStacks`,
|
||||
`GetTemplate`, and `ListStackResources`) on the Elastic Beanstalk-managed
|
||||
stack `awseb-e-hehnrqjjrt-stack`, scoped to
|
||||
`arn:aws:cloudformation:us-east-1:396287094661:stack/awseb-e-hehnrqjjrt-stack/*`.
|
||||
These read-only calls are emitted by Elastic Beanstalk's
|
||||
`UpdateEnvironment` path under the GitHub deploy role. `GetTemplate` was
|
||||
|
|
@ -95,20 +97,39 @@ The role grants only:
|
|||
mutate that stack; it is owned by Elastic Beanstalk and referenced by
|
||||
identifier only.
|
||||
|
||||
- `ec2:DescribeSubnets` as a read-only account-level query. Elastic Beanstalk
|
||||
emitted this call during run 30375409934 attempt 3 after the environment
|
||||
update started. EC2 does not support resource-level constraints for this
|
||||
Describe action, so IAM requires `Resource: "*"`. No EC2 mutation action is
|
||||
granted.
|
||||
- `ec2:DescribeAvailabilityZones`, `ec2:DescribeImages`, and
|
||||
`ec2:DescribeSubnets` as read-only account-level discovery queries.
|
||||
CloudTrail identified the GitHub deploy role as the caller during run
|
||||
`30375409934`; attempt 5 confirmed the first two denials after
|
||||
`DescribeSubnets` was allowed. EC2 does not support resource-level
|
||||
constraints for these Describe actions, so IAM requires `Resource: "*"`.
|
||||
No EC2 mutation action is granted.
|
||||
- The Auto Scaling discovery calls `DescribeAutoScalingGroups` and
|
||||
`DescribeScalingActivities` on `Resource: "*"` plus
|
||||
`PutNotificationConfiguration`, `ResumeProcesses`, and `SuspendProcesses`
|
||||
on only Auto Scaling groups whose name starts with
|
||||
`awseb-e-hehnrqjjrt-stack-`. These are the exact calls recorded during the
|
||||
successful administrator deployment. AWS supports resource-level
|
||||
constraints for all three mutations, so replacement ASGs remain covered
|
||||
without granting access to another environment.
|
||||
- `s3:GetObjectAcl` under the existing
|
||||
`elasticbeanstalk-us-east-1-396287094661/shoc-backend/*` object prefix.
|
||||
Elastic Beanstalk emitted this read during the same attempt while validating
|
||||
the uploaded application bundle. It grants no bucket-wide or cross-prefix
|
||||
object access.
|
||||
- `s3:GetObjectAcl` on only
|
||||
`resources/environments/e-hehnrqjjrt/_runtime/*` in the same bucket. A
|
||||
successful break-glass deployment showed that EB copies each immutable
|
||||
application version, its embedded extensions, and its manifest under that
|
||||
exact environment runtime prefix. The failed OIDC path already allowed the
|
||||
source object, so the remaining ACL validation is limited to that proven
|
||||
runtime boundary. This grant exposes ACL metadata only; it does not grant
|
||||
runtime content reads or writes.
|
||||
|
||||
It grants **no** IAM mutation or `PassRole`, **no** RDS / Secrets Manager
|
||||
access, no EC2 mutation, and **no** administrator policy. There are no wildcard
|
||||
mutation surfaces.
|
||||
access, no EC2 mutation, and **no** administrator policy. The only non-EB/S3
|
||||
mutations are the three deployment-process Auto Scaling calls, restricted to
|
||||
this environment's ASG name pattern. There are no wildcard mutation surfaces.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
|
|
@ -139,10 +160,11 @@ All commands run from `infra/cdk/`.
|
|||
|
||||
- Trust policy `StringEquals` matches the exact audience and subject above.
|
||||
- The inline policy contains no `Resource: "*"` mutation action and no service
|
||||
outside `elasticbeanstalk` / `s3` / `cloudformation` / `ec2`. The
|
||||
`cloudformation` grants are the three observed read-only actions on the
|
||||
single EB-managed stack prefix; the only EC2 grant is the read-only
|
||||
`DescribeSubnets` action whose IAM resource model requires `Resource: "*"`.
|
||||
outside `elasticbeanstalk` / `s3` / `cloudformation` / `ec2` /
|
||||
`autoscaling`. CloudFormation discovery is limited to the single EB-managed
|
||||
stack prefix. EC2 and Auto Scaling discovery use `Resource: "*"` only where
|
||||
the IAM resource model requires it; Auto Scaling mutations are limited to
|
||||
this environment's ASG name pattern.
|
||||
|
||||
The workflow's `AWS_DEPLOY_ROLE_ARN` repository secret (environment `dev`) must
|
||||
hold the ARN output by this stack (`GithubDeployRoleArn`).
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ const ACCOUNT_ID = '396287094661';
|
|||
const REGION = 'us-east-1';
|
||||
const APPLICATION_NAME = 'shoc-backend';
|
||||
const ENVIRONMENT_NAME = 'shoc-backend-dev';
|
||||
const ENVIRONMENT_ID = 'e-hehnrqjjrt';
|
||||
const ENVIRONMENT_STACK_NAME = `awseb-${ENVIRONMENT_ID}-stack`;
|
||||
const REPO = 'Sea-Haven-Industries/shoc-backend';
|
||||
const BUCKET_NAME = `elasticbeanstalk-${REGION}-${ACCOUNT_ID}`;
|
||||
|
||||
|
|
@ -74,12 +76,15 @@ export class DeployDevStack extends cdk.Stack {
|
|||
new iam.PolicyStatement({
|
||||
effect: iam.Effect.ALLOW,
|
||||
actions: [
|
||||
'cloudformation:DescribeStackEvents',
|
||||
'cloudformation:DescribeStackResource',
|
||||
'cloudformation:GetTemplate',
|
||||
'cloudformation:DescribeStackResources',
|
||||
'cloudformation:DescribeStacks',
|
||||
'cloudformation:ListStackResources',
|
||||
],
|
||||
resources: [
|
||||
`arn:aws:cloudformation:${REGION}:${ACCOUNT_ID}:stack/awseb-e-hehnrqjjrt-stack/*`,
|
||||
`arn:aws:cloudformation:${REGION}:${ACCOUNT_ID}:stack/${ENVIRONMENT_STACK_NAME}/*`,
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
|
@ -87,11 +92,40 @@ export class DeployDevStack extends cdk.Stack {
|
|||
deployRole.addToPolicy(
|
||||
new iam.PolicyStatement({
|
||||
effect: iam.Effect.ALLOW,
|
||||
actions: ['ec2:DescribeSubnets'],
|
||||
actions: [
|
||||
'ec2:DescribeAvailabilityZones',
|
||||
'ec2:DescribeImages',
|
||||
'ec2:DescribeSubnets',
|
||||
],
|
||||
resources: ['*'],
|
||||
}),
|
||||
);
|
||||
|
||||
deployRole.addToPolicy(
|
||||
new iam.PolicyStatement({
|
||||
effect: iam.Effect.ALLOW,
|
||||
actions: [
|
||||
'autoscaling:DescribeAutoScalingGroups',
|
||||
'autoscaling:DescribeScalingActivities',
|
||||
],
|
||||
resources: ['*'],
|
||||
}),
|
||||
);
|
||||
|
||||
deployRole.addToPolicy(
|
||||
new iam.PolicyStatement({
|
||||
effect: iam.Effect.ALLOW,
|
||||
actions: [
|
||||
'autoscaling:PutNotificationConfiguration',
|
||||
'autoscaling:ResumeProcesses',
|
||||
'autoscaling:SuspendProcesses',
|
||||
],
|
||||
resources: [
|
||||
`arn:aws:autoscaling:${REGION}:${ACCOUNT_ID}:autoScalingGroup:*:autoScalingGroupName/${ENVIRONMENT_STACK_NAME}-*`,
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
deployRole.addToPolicy(
|
||||
new iam.PolicyStatement({
|
||||
effect: iam.Effect.ALLOW,
|
||||
|
|
@ -113,6 +147,14 @@ export class DeployDevStack extends cdk.Stack {
|
|||
}),
|
||||
);
|
||||
|
||||
deployRole.addToPolicy(
|
||||
new iam.PolicyStatement({
|
||||
effect: iam.Effect.ALLOW,
|
||||
actions: ['s3:GetObjectAcl'],
|
||||
resources: [`${bucketArn}/resources/environments/${ENVIRONMENT_ID}/_runtime/*`],
|
||||
}),
|
||||
);
|
||||
|
||||
new cdk.CfnOutput(this, 'GithubDeployRoleArn', {
|
||||
value: deployRole.roleArn,
|
||||
description: 'ARN of the GitHub OIDC deploy role for shoc-backend dev.',
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue