Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

document deploy permissions? #420

Closed
ianwremmel opened this issue May 18, 2018 · 18 comments
Closed

document deploy permissions? #420

ianwremmel opened this issue May 18, 2018 · 18 comments

Comments

@ianwremmel
Copy link

It would be really helpful if there were a documented set of permissions necessary for sam package and sam deploy to work. We're slowly adding permissions to our deploy role until we get a success.

@ehorodyski
Copy link

+1

Due to the complex security structure of AWS (which I personally am a fan of), this becomes a bottleneck when trying to adopt SAM in our development teams. Our development roles are defined by security, and it would be far easier to work with them with a preexisting list of permissions needed rather than having to go back-and-forth.

@gjoshevski
Copy link

Any news on this?

@scoates
Copy link

scoates commented Oct 26, 2018

FWIW, here's what I used (as part of a role definition in my SAM template) to get this working today (it was a pain to iterate to get to this, so hopefully it'll help someone here). See notes below.

    AdditionalPermissionPolicy:
        Type: "AWS::IAM::Policy"
        Properties:
            PolicyName: "root"
            PolicyDocument:
                Version: "2012-10-17"
                Statement:
                    -
                        Effect: "Allow"
                        Action:
                            - "s3:PutObject"
                            - "s3:GetObject"
                            - "s3:CreateMultipartUpload"
                        Resource:
                            - "arn:aws:s3:::{BUCKET_NAME}"
                            - "arn:aws:s3:::{BUCKET_NAME}/*"

                    -
                        Effect: "Allow"
                        Action:
                            - "cloudformation:DescribeStacks"
                            - "cloudformation:CreateChangeSet"
                            - "cloudformation:ExecuteChangeSet"
                            - "cloudformation:DescribeChangeSet"
                        Resource:
                            - !Sub "arn:aws:cloudformation:${AWS::Region}:${AWS::AccountId}:stack/{STACK_NAME}/*"
                            - "arn:aws:cloudformation:us-east-1:aws:transform/Serverless-2016-10-31"

                    -
                        Effect: "Allow"
                        Action:
                            - "cloudformation:GetTemplateSummary"
                        Resource: "*"

                    -
                        Effect: "Allow"
                        Action:
                            - "iam:GetRole"
                        Resource:
                            - !Sub "arn:aws:iam::${AWS::AccountId}:role/{STACK_NAME}-{FUNCTION_NAME}Role-*"

                    -
                        Effect: "Allow"
                        Action:
                            - "lambda:UpdateFunctionCode"
                            - "lambda:ListTags"
                            - "lambda:TagResource"
                            - "lambda:UntagResource"
                            - "lambda:GetFunctionConfiguration"
                        Resource:
                            - !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:{STACK_NAME}-{FUNCTION_NAME}-*"

Notes:

  • this is for (code) updates only; I can't imagine that it would work for deploying a new stack
  • replace the following:
    • {BUCKET_NAME} with the bucket name you're using for code upload
    • {STACK_NAME} with your stack name (see below)
    • {FUNCTION_NAME} with your function name; this is FirstFunction by default in the python cookiecutter template
  • I use this in a secondary stack that sets up a role for Codebuild, which is why I used {STACK_NAME} instead of ${AWS::StackName}, but you can probably use that

@annjawn
Copy link

annjawn commented Apr 22, 2019

+1 for this. Piecemealing through which roles to assign is becoming a grueling process and involves us going to the infosec team again and again for approvals. There's got to be a better way.

@jasonrberk
Copy link

how on Earth is this NOT documented anywhere?!?!?! I've spent the entire day trying to figure out what permissions need to be added to even run the samples provided in this repo:

First, I couldn't create the bucket from the CLI, so I had to login and make a bucket and get those permissions correct....then this:

~/repos/github/my-project [master ?]> sam deploy --template-file serverless-output.yml --stack-name my-stack --capabilities CAPABILITY_IAM

An error occurred (AccessDenied) when calling the DescribeStacks operation: User: <my-user> is not authorized to perform: cloudformation:DescribeStacks on resource: <my-stack>

How on earth is anyone supposed to figure this all out. PLEASE....at least provided the details needed to even run the examples....

@kiamatt
Copy link

kiamatt commented Jun 12, 2019

@scoates Awesome, awesome job. Thanks for tackling this before I spent my afternoon or longer on it.

@kiamatt
Copy link

kiamatt commented Jun 12, 2019

I ended up having to add lambda:ListVersionsByFunction, lambda:UpdateAlias and lambda:PublishVersion for arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:[function_name] as well, in case that helps anyone.

@sriram-mv sriram-mv added area/deploy sam deploy command area/package sam package command labels Aug 19, 2019
@kivagant-ba
Copy link

kivagant-ba commented Nov 19, 2019

Ohhh. This was annoying...

My set of permissions.

CIInstanceRole - a role that is attached to the EC2 instance where the CI is running. Must be assumed by the CI Job. Replace {ACCOUNT} with your number.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:DescribeStacks",
        "cloudformation:CreateChangeSet",
        "cloudformation:ExecuteChangeSet",
        "cloudformation:DescribeChangeSet"
      ],
      "Resource": [
        "arn:aws:cloudformation:us-east-1:aws:transform/Serverless-2016-10-31",
        "arn:aws:cloudformation:*:*:stack/*/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:GetTemplateSummary"
      ],
      "Resource": "*"
    },
    {
      "Sid": "PassRoleToSAM",
      "Effect": "Allow",
      "Action": [
        "iam:PassRole"

      ],
      "Resource": "arn:aws:iam::{ACCOUNT}:role/CICloudFormationSharedDeploymentRole"
    }
  ]
}

CICloudFormationSharedDeploymentRole - a CI role that must be passed with --role-arn arn:aws:iam::{ACCOUNT}:role/CICloudFormationSharedDeploymentRole. Pay attention that iam:PassRole is configured for this resource in the role above.

This does not include API Gateway and DynamoDB permissions, add them if you need.
Replace {SAM_S3_BUCKET}, SAM_STACK_NAME with your number.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::{SAM_S3_BUCKET}",
        "arn:aws:s3:::{SAM_S3_BUCKET}/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:DescribeStacks",
        "cloudformation:CreateChangeSet",
        "cloudformation:ExecuteChangeSet",
        "cloudformation:DescribeChangeSet"
      ],
      "Resource": [
        "arn:aws:cloudformation:us-east-1:aws:transform/Serverless-2016-10-31",
        "arn:aws:cloudformation:*:*:stack/{SAM_STACK_NAME}/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "cloudformation:GetTemplateSummary"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "iam:GetRole",
        "iam:CreateRole",
        "iam:PassRole",
        "iam:DeleteRole",
        "iam:GetRolePolicy",
        "iam:PutRolePolicy",
        "iam:AttachRolePolicy",
        "iam:DetachRolePolicy",
        "iam:DeleteRolePolicy",
        "iam:TagRole",
        "iam:UntagRole"
      ],
      "Resource": [
        "arn:aws:iam::*:role/{SAM_STACK_NAME}-*"

      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "events:*"
      ],
      "Resource": [
        "arn:aws:events:*:*:rule/{SAM_STACK_NAME}-*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "lambda:*"
      ],
      "Resource": [
        "arn:aws:lambda:*:*:function:{SAM_STACK_NAME}-*"
      ]
    }
  ]
}

Some permissions raise questions, i.e "iam:PassRole" for role/{SAM_STACK_NAME}-*, but id didn't work without it. Also I had to add deleting permissions in case of the stack failure.

The role must also have Trust relationship configured as in the example so CI can pass the CICloudFormationSharedDeploymentRole to SAM:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::{ACCOUNT}:role/CIInstanceRole"
      },
      "Action": "sts:AssumeRole"
    },
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudformation.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

And the SAM command example:

sam deploy \
--region us-east-1 \
--stack-name {SAM_STACK_NAME} \
--s3-bucket {SAM_S3_BUCKET} \
--s3-prefix {SAM_STACK_NAME} \
--tags Creator=sam sam=Owned \
--template-file packaged.yaml \
--capabilities CAPABILITY_IAM \
--role-arn arn:aws:iam::{ACCOUNT}:role/CICloudFormationSharedDeploymentRole \
--no-fail-on-empty-changeset

@freko247
Copy link

Hey, some additional permissions that I found missing:

API Gateway:

Action = [
  "apigateway:GET",
  "apigateway:PATCH",
  "apigateway:POST",
  "apigateway:PUT"
]

Lambda:

Action = [
  "lambda:CreateFunction",
  "lambda:AddPermission"
]

@oneEyedSunday
Copy link

Hello guys, I had to also add s3:ListBucket

@alex-nishikawa
Copy link

Another one to allow: cloudformation:DescribeStackEvents, not to be confused with DescribeStacks

@heffergm
Copy link

heffergm commented Aug 1, 2020

Does no one else have concerns over the need to pass this:

    {
      "Effect": "Allow",
      "Action": [
        "iam:GetRole",
        "iam:CreateRole",
        "iam:PassRole",
        "iam:DeleteRole",
        "iam:GetRolePolicy",
        "iam:PutRolePolicy",
        "iam:AttachRolePolicy",
        "iam:DetachRolePolicy",
        "iam:DeleteRolePolicy",
        "iam:TagRole",
        "iam:UntagRole"
      ],
      "Resource": [
        "arn:aws:iam::*:role/{SAM_STACK_NAME}-*"

      ]
    },

To automate this would mean granting permissions to an entity to create a new role with any set of permissions in it, which is a bit of a no-go for me.

I suspect there might be a way around this with permissions boundaries, but for the life of me I haven't been able to figure it out as yet.

I had managed to avoid the issue of PutRolePolicy and AttachRolePolicy (just for function code deployments) prior to adding a PreTrafficHook, but after doing so they appear to be required, so I'm a bit stuck.

@awood45
Copy link
Member

awood45 commented Aug 2, 2020

So for some context on those permissions, if you're creating IAM roles, you need to have the necessary permissions, and they are powerful permissions to have. If you want to get around this, there are two approaches:

  1. Create IAM roles elsewhere, and reference them by ARN in your SAM template. If you're doing this, you won't need permissions to create/delete roles (whatever account/user creates the roles needs those permissions, and this can happen outside of SAM template creation).
  2. For permissions boundaries, there are ways to ensure they are required to be present. For example, you could give a CloudFormation Deployment Role (or a user) those permissions, but only with a conditional:
          - Action:
              - iam:AttachRolePolicy
              - iam:CreateRole
              - iam:DeleteRolePolicy
              - iam:DetachRolePolicy
            Effect: Allow
            Resource: '*'
            Condition:
              StringEquals:
                iam:PermissionsBoundary: !Sub 'arn:${AWS::Partition}:iam::${AWS::AccountId}:policy/my-app-${AWS::Region}-PermissionsBoundary'

That way, an IAM role can only be created if the permissions boundary you specify is included with it, and SAM provides a field to easily include this.

In any case, either of those workarounds should help you reduce the necessary permissions scope as you develop your applications further.

@ojizero
Copy link

ojizero commented Aug 7, 2020

So far this policy is the smallest policy I managed to get sam deploy to release a new version of Lambda, YMMV! Not sure if it can be done with a smaller policy though ¯_(ツ)_/¯

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "IAM",
      "Effect": "Allow",
      "Action": [
        "iam:GetRole",
        "iam:PassRole"
      ],
      "Resource": [
        "arn:aws:iam::{ACCOUNT_ID}:role/{LAMBDA_ROLE}"
      ]
    },
    {
      "Sid": "S3",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject",
        "s3:GetObject"
      ],
      "Resource": [
        "arn:aws:s3:::{SAM_S3_BUCKET}/*"
      ]
    },
    {
      "Sid": "Lambda",
      "Effect": "Allow",
      "Action": [
        "lambda:UpdateFunctionCode",
        "lambda:UpdateFunctionConfiguration",
        "lambda:TagResource",
        "lambda:ListTags",
        "lambda:GetFunctionConfiguration",
        "lambda:UntagResource"
      ],
      "Resource": [
        "arn:aws:lambda:*:{ACCOUNT_ID}:function:{LAMBDA}"
      ]
    },
    {
      "Sid": "CloudFormation",
      "Effect": "Allow",
      "Action": "cloudformation:*",
      "Resource": [
        "arn:aws:cloudformation:*:{ACCOUNT_ID}:stack/{LAMBDA_STACK}/*",
        "arn:aws:cloudformation:*:{ACCOUNT_ID}:stack/{SAM_MANAGED_STACK}/*",
        "arn:aws:cloudformation:us-west-2:aws:transform/Serverless-2016-10-31"
      ]
    }
  ]
}

@Envek
Copy link

Envek commented Oct 28, 2020

If you use Lambda layers (to extract dependencies, etc):

          -
            Effect: "Allow"
            Action:
              - "lambda:PublishLayerVersion"
              - "lambda:GetLayerVersion"
              - "lambda:DeleteLayerVersion" # Required for Lambda upgrades
            Resource:
              - !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:${LayerName}"
              - !Sub "arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:${LayerName}:*"

If you use 3rd party layers (like for monitoring systems):

          -
            Effect: "Allow"
            Action:
              - "lambda:GetLayerVersion"
            Resource:
              - !Sub "arn:aws:lambda:${AWS::Region}:464622532012:layer:Datadog-*:*"

To bind Lambda to some source like SQS queue (but usually it is required for first deploy only):

          -
            Action:
              - "lambda:CreateEventSourceMapping"
              - "lambda:GetEventSourceMapping"
            Effect: Allow
            Resource: '*'

@Envek
Copy link

Envek commented Oct 28, 2020

That way, an IAM role can only be created if the permissions boundary you specify is included with it, and SAM provides a field to easily include this.

Damn, looks complicated! @awood45, can you please tell in more details how to do it? How permissions boundary should look like? I can't assemble this puzzle.

@Raaghu
Copy link

Raaghu commented Feb 2, 2021

+1

@sriram-mv
Copy link
Contributor

Closing this issue: https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-permissions.html

mndeveci added a commit to mndeveci/aws-sam-cli that referenced this issue Jan 24, 2023
* feat: Support Runtime management controls

- Modify ECR repo from `/sam/emulation-<runtime>` to `/lambda/<runtime>`.
- Keep RAPID image up-to-date with the remote environment.
- Remove SAM cli version from RAPID image tag locally.
  - These modifications change the rapid image tag
    from `python3.7-rapid-1.2.0-x86_64` to `3.7-rapid-x86_64`,
    since now the runtime name is part of the image *name* and not the tag.
- Support a `RuntimeManagementConfig` in SAM templates and show a message
  if a runtime version is pinned in the template when invoking.
- Rename some variables when building the rapid image, for more clarity.

* PR feedback. Add placeholder text

* Last updates for RuntimeManagementConfiguration

- Change from RuntimeVersion to RuntimeVersion Arn
- Update the message when user has a RuntimeVersion in their template
and wants to invoke locally.

* Update with latest tranform changes

* update tests with latest transform changes

* rollback dev version of SAMT

Co-authored-by: Mehmet Nuri Deveci <5735811+mndeveci@users.noreply.github.com>
mndeveci added a commit that referenced this issue Jan 24, 2023
* feat: Support Runtime management controls (#420)

* feat: Support Runtime management controls

- Modify ECR repo from `/sam/emulation-<runtime>` to `/lambda/<runtime>`.
- Keep RAPID image up-to-date with the remote environment.
- Remove SAM cli version from RAPID image tag locally.
  - These modifications change the rapid image tag
    from `python3.7-rapid-1.2.0-x86_64` to `3.7-rapid-x86_64`,
    since now the runtime name is part of the image *name* and not the tag.
- Support a `RuntimeManagementConfig` in SAM templates and show a message
  if a runtime version is pinned in the template when invoking.
- Rename some variables when building the rapid image, for more clarity.

* PR feedback. Add placeholder text

* Last updates for RuntimeManagementConfiguration

- Change from RuntimeVersion to RuntimeVersion Arn
- Update the message when user has a RuntimeVersion in their template
and wants to invoke locally.

* Update with latest tranform changes

* update tests with latest transform changes

* rollback dev version of SAMT

Co-authored-by: Mehmet Nuri Deveci <5735811+mndeveci@users.noreply.github.com>

* Update local_uri_plugin.py

* Update local_uri_plugin.py

Co-authored-by: Renato Valenzuela <37676028+valerena@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests