aws / copilot-cli

The AWS Copilot CLI is a tool for developers to build, release and operate production ready containerized applications on AWS App Runner or Amazon ECS on AWS Fargate.
https://aws.github.io/copilot-cli/
Apache License 2.0
3.47k stars 399 forks source link

Too-Wide Permissions for EnvManager Role - best way to scope-down? #5036

Open adrianosela opened 1 year ago

adrianosela commented 1 year ago

Background

The copilot env deploy and copilot svc deploy commands under the hood assume a copilot-managed AWS IAM Role (per environment) of the form ${COPILOT_APP_NAME}-${COPILOT_ENV_NAME}-EnvManagerRole

This means I need to give my CI/CD system access to sts:AssumeRole that role if I want to deploy my app with a CI system -- that's all good so far.

The problem is that the ...-EnvManagerRole by default is absurdly permissive and most of the permissions it has are not required to deploy my app...

For example, and of particular concern, the role has:

Click to see (A) portion of policy ``` { "Action": [ "ecs:ListAttributes", "ecs:ListTasks", "ecs:DescribeServices", "ecs:DescribeTaskSets", "ecs:ListContainerInstances", "ecs:DescribeContainerInstances", "ecs:DescribeTasks", "ecs:DescribeClusters", "ecs:UpdateService", "ecs:PutAttributes", "ecs:StartTelemetrySession", "ecs:StartTask", "ecs:StopTask", "ecs:ListServices", "ecs:ListTaskDefinitionFamilies", "ecs:DescribeTaskDefinition", "ecs:ListTaskDefinitions", "ecs:ListClusters", "ecs:RunTask" ], "Resource": "*", "Effect": "Allow", "Sid": "ECS" }, ```
Click to see (B) portion of policy ``` { "Action": [ "cloudformation:CancelUpdateStack", "cloudformation:CreateChangeSet", "cloudformation:CreateStack", "cloudformation:DeleteChangeSet", "cloudformation:DeleteStack", "cloudformation:Describe*", "cloudformation:DetectStackDrift", "cloudformation:DetectStackResourceDrift", "cloudformation:ExecuteChangeSet", "cloudformation:GetTemplate", "cloudformation:GetTemplateSummary", "cloudformation:UpdateStack", "cloudformation:UpdateTerminationProtection" ], "Resource": "*", "Effect": "Allow", "Sid": "CloudFormation" }, ```
Click to see (C) portion of policy ``` { "Action": [ "ssm:DeleteParameter", "ssm:DeleteParameters", "ssm:GetParameter", "ssm:GetParameters", "ssm:GetParametersByPath" ], "Resource": "*", "Effect": "Allow", "Sid": "SSM" }, ```

Question

I believe an IAM permissions boundary (policy) for all copilot-managed roles can be provided during copilot app init with the --permissions-boundary flag; but I already have a copilot app and I am hoping not to need to tear it down to recreate it with the more finer grained IAM perms.

I am wondering what the best way is to scope down this role WITH INFRA AS CODE e.g. cloudformation such that I can make the changes to the EXISTING COPILOT APP and if I ever accidentally destroy the app, I can recreate it with the same IAM policy / settings. i.e. I don't want to make the changes manually in the AWS console nor the CLI.

I am thinking of setting the permissions boundary to the roles by explicit role ARN in CFN -- is there a better way? Something perhaps I can add in my copilot manifests (after the app is already created)?

Any help is appreciated <3

huanjani commented 1 year ago

Hello, @adrianosela.

This is a great question! Copilot now has a powerful Overrides feature with which you can run copilot env override and use either yaml patches or the CDK to override those permissions.

With a yaml patch, you could add your permissions boundary to the Env Manager (and other) role(s), OR you could remove certain permissions or replace parts of the Env Manager policy. You can leverage copilot env package --diff along the way, and regular copilot env package to write your new CFN template to a file.

Let us know if you need more guidance with any of those options!

(We generally try not to add more permissions than those that are necessary, so we can't guarantee that Copilot will work as designed after you change the permissions. But thanks for the nudge to reexamine some of our more permissive policies!)

adrianosela commented 1 year ago

Thanks for the quick reply @huanjani! I'll give that a try :)

adrianosela commented 1 year ago

Thank you @huanjani -- Using overrides with yaml patches indeed works great to scope down the EnvManager role.

The only downside is, and correct me if I'm wrong, if copilot modifies a role policy (to accommodate a new feature for example) which I am replacing via yaml patches. I imagine copilot will break if the new feature requires permissions that my override does not have.

Again, of particular concern is the env manager role.

Any chance in the future the env manager role could be defined in accordance to the manifest? For example, if my app uses no ssm parameters -- don't give the envmanager role any ssm permissions. Or if my app needs ssm parameter /x/y/z, give the envmanager role only access to x/y/z and so on... same for ECS permissions, etc.

More generally, maybe copilot could define the EnvManager role in accordance with the stuff defined in the manifest.

github-actions[bot] commented 12 months ago

This issue is stale because it has been open 60 days with no response activity. Remove the stale label, add a comment, or this will be closed in 14 days.