Skip to content

Latest commit

 

History

History
228 lines (163 loc) · 12.8 KB

access-control-resource-based.md

File metadata and controls

228 lines (163 loc) · 12.8 KB

Using resource-based policies for AWS Lambda

AWS Lambda supports resource-based permissions policies for Lambda functions and layers. Resource-based policies let you grant usage permission to other AWS accounts on a per-resource basis. You also use a resource-based policy to allow an AWS service to invoke your function on your behalf.

For Lambda functions, you can grant an account permission to invoke or manage a function. You can add multiple statements to grant access to several accounts, or let any account invoke your function. You can also use the policy to grant invoke permission to an AWS service that invokes a function in response to activity in your account.

To view a function's resource-based policy

  1. Open the Functions page on the Lambda console.

  2. Choose a function.

  3. Choose Configuration and then choose Permissions.

  4. Scroll down to Resource-based policy and then choose View policy document. The resource-based policy shows the permissions that are applied when another account or AWS service attempts to access the function. The following example shows a statement that allows Amazon S3 to invoke a function named my-function for a bucket named my-bucket in account 123456789012.
    Example Resource-based policy

    {
        "Version": "2012-10-17",
        "Id": "default",
        "Statement": [
            {
                "Sid": "lambda-allow-s3-my-function",
                "Effect": "Allow",
                "Principal": {
                  "Service": "s3.amazonaws.com"
                },
                "Action": "lambda:InvokeFunction",
                "Resource":  "arn:aws:lambda:us-east-2:123456789012:function:my-function:*",
                "Condition": {
                  "StringEquals": {
                    "AWS:SourceAccount": "123456789012"
                  },
                  "ArnLike": {
                    "AWS:SourceArn": "arn:aws:s3:::my-bucket"
                  }
                }
            }
         ]
    }
    

For Lambda layers, you can only use a resource-based policy on a specific layer version, instead of the entire layer. In addition to policies that grant permission to a single account or multiple accounts, for layers, you can also grant permission to all accounts in an organization.

Note
You can only update resource-based policies for Lambda resources within the scope of the AddPermission and AddLayerVersionPermission API actions. Currently, you can't author policies for your Lambda resources in JSON, or use conditions that don't map to parameters for those actions.

Resource-based policies apply to a single function, version, alias, or layer version. They grant permission to one or more services and accounts. For trusted accounts that you want to have access to multiple resources, or to use API actions that resource-based policies don't support, you can use cross-account roles.

Topics

Granting function access to AWS services

When you use an AWS service to invoke your function, you grant permission in a statement on a resource-based policy. You can apply the statement to the entire function to be invoked or managed, or limit the statement to a single version or alias.

Note
When you add a trigger to your function with the Lambda console, the console updates the function's resource-based policy to allow the service to invoke it. To grant permissions to other accounts or services that aren't available in the Lambda console, you can use the AWS CLI.

Add a statement with the add-permission command. The simplest resource-based policy statement allows a service to invoke a function. The following command grants Amazon SNS permission to invoke a function named my-function.

aws lambda add-permission --function-name my-function --action lambda:InvokeFunction --statement-id sns \
--principal sns.amazonaws.com --output text

You should see the following output:

{"Sid":"sns","Effect":"Allow","Principal":{"Service":"sns.amazonaws.com"},"Action":"lambda:InvokeFunction","Resource":"arn:aws:lambda:us-east-2:123456789012:function:my-function"}

This lets Amazon SNS call the lambda:Invoke API for the function, but it doesn't restrict the Amazon SNS topic that triggers the invocation. To ensure that your function is only invoked by a specific resource, specify the Amazon Resource Name (ARN) of the resource with the source-arn option. The following command only allows Amazon SNS to invoke the function for subscriptions to a topic named my-topic.

aws lambda add-permission --function-name my-function --action lambda:InvokeFunction --statement-id sns-my-topic \
--principal sns.amazonaws.com --source-arn arn:aws:sns:us-east-2:123456789012:my-topic

Some services can invoke functions in other accounts. If you specify a source ARN that has your account ID in it, that isn't an issue. For Amazon S3, however, the source is a bucket whose ARN doesn't have an account ID in it. It's possible that you could delete the bucket and another account could create a bucket with the same name. Use the source-account option with your account ID to ensure that only resources in your account can invoke the function.

aws lambda add-permission --function-name my-function --action lambda:InvokeFunction --statement-id s3-account \
--principal s3.amazonaws.com --source-arn arn:aws:s3:::my-bucket-123456 --source-account 123456789012

Granting function access to other accounts

To grant permissions to another AWS account, specify the account ID as the principal. The following example grants account 210987654321 permission to invoke my-function with the prod alias.

aws lambda add-permission --function-name my-function:prod --statement-id xaccount --action lambda:InvokeFunction \
--principal 210987654321 --output text

You should see the following output:

{"Sid":"xaccount","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::210987654321:root"},"Action":"lambda:InvokeFunction","Resource":"arn:aws:lambda:us-east-2:123456789012:function:my-function"}

The resource-based policy grants permission for the other account to access the function, but doesn't allow users in that account to exceed their permissions. Users in the other account must have the corresponding user permissions to use the Lambda API.

To limit access to a user or role in another account, specify the full ARN of the identity as the principal. For example, arn:aws:iam::123456789012:user/developer.

The alias limits which version the other account can invoke. It requires the other account to include the alias in the function ARN.

aws lambda invoke --function-name arn:aws:lambda:us-west-2:123456789012:function:my-function:prod out

You should see the following output:

{
    "StatusCode": 200,
    "ExecutedVersion": "1"
}

The function owner can then update the alias to point to a new version without the caller needing to change the way they invoke your function. This ensures that the other account doesn't need to change its code to use the new version, and it only has permission to invoke the version of the function associated with the alias.

You can grant cross-account access for most API actions that operate on an existing function. For example, you could grant access to lambda:ListAliases to let an account get a list of aliases, or lambda:GetFunction to let them download your function code. Add each permission separately, or use lambda:* to grant access to all actions for the specified function.

Cross-account APIs

Currently, Lambda doesn’t currently support cross-account actions for all of its APIs via resource-based policies. The following APIs are supported:

To grant other accounts permission for multiple functions, or for actions that don't operate on a function, we recommend that you use IAM roles.

Granting layer access to other accounts

To grant layer-usage permission to another account, add a statement to the layer version's permissions policy using the add-layer-version-permission command. In each statement, you can grant permission to a single account, all accounts, or an organization.

aws lambda add-layer-version-permission --layer-name xray-sdk-nodejs --statement-id xaccount \
--action lambda:GetLayerVersion  --principal 210987654321 --version-number 1 --output text

You should see output similar to the following:

e210ffdc-e901-43b0-824b-5fcd0dd26d16    {"Sid":"xaccount","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::210987654321:root"},"Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-east-2:123456789012:layer:xray-sdk-nodejs:1"}

Permissions apply only to a single layer version. Repeat the process each time that you create a new layer version.

To grant permission to all accounts in an organization, use the organization-id option. The following example grants all accounts in an organization permission to use version 3 of a layer.

aws lambda add-layer-version-permission --layer-name my-layer \
--statement-id engineering-org --version-number 3 --principal '*' \
--action lambda:GetLayerVersion --organization-id o-t194hfs8cz --output text

You should see the following output:

b0cd9796-d4eb-4564-939f-de7fe0b42236    {"Sid":"engineering-org","Effect":"Allow","Principal":"*","Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-east-2:123456789012:layer:my-layer:3","Condition":{"StringEquals":{"aws:PrincipalOrgID":"o-t194hfs8cz"}}}"

To grant permission to all AWS accounts, use * for the principal, and omit the organization ID. For multiple accounts or organizations, you need to add multiple statements.

Cleaning up resource-based policies

To view a function's resource-based policy, use the get-policy command.

aws lambda get-policy --function-name my-function --output text

You should see the following output:

{"Version":"2012-10-17","Id":"default","Statement":[{"Sid":"sns","Effect":"Allow","Principal":{"Service":"s3.amazonaws.com"},"Action":"lambda:InvokeFunction","Resource":"arn:aws:lambda:us-east-2:123456789012:function:my-function","Condition":{"ArnLike":{"AWS:SourceArn":"arn:aws:sns:us-east-2:123456789012:lambda*"}}}]}      7c681fc9-b791-4e91-acdf-eb847fdaa0f0

For versions and aliases, append the version number or alias to the function name.

aws lambda get-policy --function-name my-function:PROD

To remove permissions from your function, use remove-permission.

aws lambda remove-permission --function-name example --statement-id sns

Use the get-layer-version-policy command to view the permissions on a layer.

aws lambda get-layer-version-policy --layer-name my-layer --version-number 3 --output text

You should see the following output:

b0cd9796-d4eb-4564-939f-de7fe0b42236    {"Sid":"engineering-org","Effect":"Allow","Principal":"*","Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-west-2:123456789012:layer:my-layer:3","Condition":{"StringEquals":{"aws:PrincipalOrgID":"o-t194hfs8cz"}}}"

Use remove-layer-version-permission to remove statements from the policy.

aws lambda remove-layer-version-permission --layer-name my-layer --version-number 3 --statement-id engineering-org