sst / sst

Build full-stack apps on your own infrastructure.
https://sst.dev
MIT License
21.72k stars 1.64k forks source link

Feature Request: Better Cross Account/Least Privilege Deployment Support #2240

Closed bestickley closed 1 week ago

bestickley commented 1 year ago

I'm building an SST app where we're using GitHub Actions for our pipeline. We have a devtools account and a target account. We want all deployments to go through (via assume-role) devtools account for security reasons. There will be multiple future target accounts. In order to get this working with SST I had to use some work arounds as documented below. The goal of this feature request is to make this easier on SST. What I think should change:

Current work around:

  1. Within target/deployment AWS account where cdk has not been bootstrapped, run sst cdk --app=.build/run.mjs bootstrap aws://<target-account-id>/us-east-1 --trust <assume-role-from-id> --cloudformation-execution-policies arn:aws:iam::aws:policy/AdministratorAccess
  2. Within target/deployment AWS account, run sst bootstrap
  3. Get credentials from assume-role-from account
  4. Assume lookup-role in target account. You can use below script
    ASSUMED_ROLE=$(aws sts assume-role --role-arn "arn:aws:iam::<target-account-id>:role/cdk-hnb659fds-lookup-role-<target-account-id>-us-east-1" --role-session-name "mysession" --output json)
    export AWS_ACCESS_KEY_ID=$(echo $ASSUMED_ROLE | jq -r .Credentials.AccessKeyId)
    export AWS_SECRET_ACCESS_KEY=$(echo $ASSUMED_ROLE | jq -r .Credentials.SecretAccessKey)
    export AWS_SESSION_TOKEN=$(echo $ASSUMED_ROLE | jq -r .Credentials.SessionToken)
  5. sst build
  6. Update deploy-role in target account with following statements:
    {
    "Action": [
    "ssm:GetParameter",
    "ssm:GetParameters"
    ],
    "Resource": [
    "arn:aws:ssm:us-east-1:<target-account-id>:parameter/sst/bootstrap/version",
    "arn:aws:ssm:us-east-1:<target-account-id>:parameter/sst/bootstrap/stack-name",
    "arn:aws:ssm:us-east-1:<target-account-id>:parameter/sst/bootstrap/bucket-name"
    ],
    "Effect": "Allow",
    "Sid": "ReadSSTVersion"
    },
    {
    "Action": [
    "sts:AssumeRole"
    ],
    "Resource": [
    "arn:aws:iam::<target-account-id>:role/cdk-hnb659fds-file-publishing-role-<target-account-id>-us-east-1",
    "arn:aws:iam::<target-account-id>:role/cdk-hnb659fds-image-publishing-role-<target-account-id>-us-east-1"
    ],
    "Effect": "Allow",
    "Sid": "AssumeCDKRoles"
    }
  7. Get credentials from assume-role-from account
  8. Assume deploy-role in target account
  9. sst deploy
nnyegaard commented 1 year ago

Would AWS Organisation and SSO not work here? What we do is have --profile xx behind all sst commands (and AWS cli commands) and each profile is given a role controlled from our AWS Organisation

bestickley commented 1 year ago

@nnyegaard, thanks for your idea! The role controlled by your AWS Organization, did you have to manually create it? This issue is to make creating that role easier. Also, are you doing that in CI? Do you have long-term credentials within your CI pipeline? I think security best practice is to assume roles and get short term credentials via STS which makes it a little more difficult to use the --profile strategy.

nnyegaard commented 1 year ago

No i setup the Organisation and roles with a normal CDK project, but you could do that in SST. I used this project, https://github.com/pepperize/cdk-organizations-example. You can control how long token lives for a given role on an account etc. So you should be able to implement anything you want

bestickley commented 1 year ago

@nnyegaard, is SST correctly assuming normal CDK roles created during cdk bootstrap? If so, it should fail because it won't have permissions to access SST specific resources, right? I think this issue isn't experience by most because the profile they give to SST has AdministratorAccess.

thdxr commented 1 week ago

We are transition this repo to https://github.com/sst/v2 and are closing this issue for now. If it is still relevant please reopen it there - sorry for the trouble