

# 在 Lambda 中查看基于资源的 IAM 策略
<a name="access-control-resource-based"></a>

Lambda 支持将基于资源的权限策略用于 Lambda 函数和层。您可以使用基于资源的策略向其他 [AWS 账户](permissions-function-cross-account.md)、[组织](permissions-function-organization.md)或[服务](permissions-function-services.md)授予访问权限。基于资源的策略应用于单个函数、版本、别名或层版本。

------
#### [ Console ]

**查看函数的基于资源的策略**

1. 打开 Lamba 控制台的[函数](https://console.aws.amazon.com/lambda/home#/functions)页面。

1. 选择函数。

1. 选择 **Configuration (配置)**，然后选择 **Permissions (权限)**。

1. 向下滚动到 ** Resource-based policy (基于资源的策略)**，然后选择 ** View policy document (查看策略文档)**。基于资源的策略显示了在其他账户或 AWS 服务尝试访问该函数时应用的权限。以下示例显示了一个语句，该语句允许 Amazon S3 调用为账户 `123456789012` 中名为 `amzn-s3-demo-bucket` 的存储桶调用名为 `my-function` 的函数。  
**Example 基于资源的策略**    
****  

   ```
   {
       "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:::amzn-s3-demo-bucket"
                 }
               }
           }
        ]
   }
   ```

------
#### [ AWS CLI ]

要查看函数的基于资源的策略，请使用 `get-policy` 命令。

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

您应看到以下输出：

****  

```
{"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*"}}}]}
```

对于版本和别名，请在函数名后面附加版本号或别名。

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

要从函数中删除权限，请使用 `remove-permission`。

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

使用 `get-layer-version-policy` 命令可查看层上的权限。

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

您应看到以下输出：

```
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"}}}"
```

使用 `remove-layer-version-permission` 可从策略中删除语句。

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

------

## 支持的 API 操作
<a name="permissions-resource-api"></a>

以下 Lambda API 操作支持基于资源的策略：
+ [CreateAlias](https://docs.aws.amazon.com/lambda/latest/api/API_CreateAlias.html)
+ [DeleteAlias](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteAlias.html)
+ [DeleteFunction](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteFunction.html)
+ [DeleteFunctionConcurrency](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteFunctionConcurrency.html)
+ [DeleteFunctionEventInvokeConfig](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteFunctionEventInvokeConfig.html)
+ [DeleteProvisionedConcurrencyConfig](https://docs.aws.amazon.com/lambda/latest/api/API_DeleteProvisionedConcurrencyConfig.html)
+ [GetAlias](https://docs.aws.amazon.com/lambda/latest/api/API_GetAlias.html)
+ [GetFunction](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunction.html)
+ [GetFunctionConcurrency](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConcurrency.html)
+ [GetFunctionConfiguration](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionConfiguration.html)
+ [GetFunctionEventInvokeConfig](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunctionEventInvokeConfig.html)
+ [GetPolicy](https://docs.aws.amazon.com/lambda/latest/api/API_GetPolicy.html)
+ [GetProvisionedConcurrencyConfig](https://docs.aws.amazon.com/lambda/latest/api/API_GetProvisionedConcurrencyConfig.html)
+ [Invoke](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html)
+ [InvokeFunctionUrl](urls-auth.md)（仅权限）
+ [ListAliases](https://docs.aws.amazon.com/lambda/latest/api/API_ListAliases.html)
+ [ListFunctionEventInvokeConfigs](https://docs.aws.amazon.com/lambda/latest/api/API_ListFunctionEventInvokeConfigs.html)
+ [ListProvisionedConcurrencyConfigs](https://docs.aws.amazon.com/lambda/latest/api/API_ListProvisionedConcurrencyConfigs.html)
+ [ListTags](https://docs.aws.amazon.com/lambda/latest/api/API_ListTags.html)
+ [ListVersionsByFunction](https://docs.aws.amazon.com/lambda/latest/api/API_ListVersionsByFunction.html)
+ [PublishVersion](https://docs.aws.amazon.com/lambda/latest/api/API_PublishVersion.html)
+ [PutFunctionConcurrency](https://docs.aws.amazon.com/lambda/latest/api/API_PutFunctionConcurrency.html)
+ [PutFunctionEventInvokeConfig](https://docs.aws.amazon.com/lambda/latest/api/API_PutFunctionEventInvokeConfig.html)
+ [PutProvisionedConcurrencyConfig](https://docs.aws.amazon.com/lambda/latest/api/API_PutProvisionedConcurrencyConfig.html)
+ [TagResource](https://docs.aws.amazon.com/lambda/latest/api/API_TagResource.html)
+ [UntagResource](https://docs.aws.amazon.com/lambda/latest/api/API_UntagResource.html)
+ [UpdateAlias](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateAlias.html)
+ [UpdateFunctionCode](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionCode.html)
+ [UpdateFunctionEventInvokeConfig](https://docs.aws.amazon.com/lambda/latest/api/API_UpdateFunctionEventInvokeConfig.html)

# 授予 Lambda 函数访问 AWS 服务 的权限
<a name="permissions-function-services"></a>

当您[使用 AWS 服务调用您的函数](lambda-services.md)时，可以用基于资源的策略语句授权。您可以将语句应用于整个函数，也可以将语句限制为单个版本或别名。

**注意**  
当您通过 Lambda 控制台向函数添加触发器时，该控制台会更新函数的基于资源的策略以允许服务调用它。要向 Lambda 控制台中不可用的其他账户或服务授予权限，可以使用 AWS CLI。

使用 [add-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-permission.html) 命令添加一条语句。最简单的基于资源的策略语句是允许一个服务调用某个函数。以下命令授予 Amazon Simple Notification Service 调用名为 `my-function` 的函数的权限。

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

您应看到以下输出：

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

这允许 Amazon SNS 在函数上调用 [Invoke](https://docs.aws.amazon.com/lambda/latest/api/API_Invoke.html) API 操作，但不会限制触发调用的 Amazon SNS 主题。为确保您的函数只被特定资源调用，请使用 `source-arn` 选项指定资源的 Amazon Resource Name (ARN)。以下命令只允许 Amazon SNS 调用名为 `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
```

有些服务可以调用其他账户中的函数。如果您指定的一个源 ARN 中包含您的账户 ID，这不是问题。但对于 Amazon S3 来说，源是其 ARN 中不包含账户 ID 的存储桶。有可能是您删除了该存储桶，而另一个账户用同样的名称创建了这样一个存储桶。使用 `source-account` 选项以及您的账户 ID 以确保只有您账户中的资源可以调用该函数。

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

# 向组织授予函数访问权限
<a name="permissions-function-organization"></a>

要向 [AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html) 中的组织授予权限，请将组织 ID 指定为 `principal-org-id`。以下 [add-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-permission.html) 命令向组织 `o-a1b2c3d4e5f` 中的所有用户授予调用访问权限。

```
aws lambda add-permission \
  --function-name example \
  --statement-id PrincipalOrgIDExample \
  --action lambda:InvokeFunction \
  --principal * \
  --principal-org-id o-a1b2c3d4e5f
```

**注意**  
在此命令中，`Principal` 为 `*`。这意味着组织 `o-a1b2c3d4e5f` 中的所有用户都获得了函数调用权限。如果您将某个 AWS 账户 或角色指定为 `Principal`，则只有该主体会获得函数调用权限，但前提是他们也是 `o-a1b2c3d4e5f` 组织的成员。

此命令会创建一个基于资源的策略，如下所示：

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "PrincipalOrgIDExample",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "lambda:InvokeFunction",
            "Resource": "arn:aws:lambda:us-east-2:123456789012:function:example",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "o-a1b2c3d4e5f"
                }
            }
        }
    ]
}
```

------

有关更多信息，请参阅《IAM 用户指南》**中的 [aws:PrincipalOrgID](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-principalorgid)。

# 向其他账户授予 Lambda 函数访问权限
<a name="permissions-function-cross-account"></a>

要与其他 AWS 账户 共享函数，请在该函数的[基于资源的策略](access-control-resource-based.md)中添加跨账户权限语句。执行 [add-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-permission.html) 命令，并将账户 ID 指定为 `principal`。以下示例向账户 `111122223333` 授权以 `my-function` 别名调用 `prod`。

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

您应看到以下输出：

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

基于资源的策略向另一个账户授予访问此函数的权限，但不允许该账户中的用户超出其权限。另一个账户中的用户必须具有相应的[用户权限](access-control-identity-based.md)才能使用 Lambda API。

要限制对另一个账户中用户或角色的访问，请将身份的完整 ARN 指定为主体。例如：`arn:aws:iam::123456789012:user/developer`。

[别名](configuration-aliases.md)限制了其他账户可以调用哪个版本。它要求另一个账户在函数 ARN 中包括该别名。

```
aws lambda invoke \
  --function-name arn:aws:lambda:us-east-2:123456789012:function:my-function:prod out
```

您应看到以下输出：

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

然后，函数所有者可以更新别名以指向新版本，而无需调用者更改他们调用函数的方式。这可以确保另一个账户不需要更改其代码即可使用新版本，并且它只具有调用与别名关联的函数版本的权限。

您可以授予对作用于现有函数的大多数 API 操作的跨账户访问权。例如，您可以授予 `lambda:ListAliases` 权限，以允许一个账户获得别名列表，或授予 `lambda:GetFunction` 权限，以让它们下载您的函数代码。分别添加每个权限，或使用 `lambda:*` 授予有关指定函数的所有操作的权限。

要授予其他账户对多个函数的权限，或不对某个函数执行的操作的权限，请使用 [IAM 角色](access-control-identity-based.md)。

# 向其他账户授予 Lambda 层访问权限
<a name="permissions-layer-cross-account"></a>

要与其他 AWS 账户 共享层，请在该层的[基于资源的策略](access-control-resource-based.md)中添加跨账户权限语句。执行 [add-layer-version-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-layer-version-permission.html) 命令，并将账户 ID 指定为 `principal`。在每个语句中，您可以向 [AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html) 中的单个账户、所有账户或组织授予权限。

以下示例向账户 111122223333 授予访问 `bash-runtime` 层版本 2 的权限。

```
aws lambda add-layer-version-permission \
  --layer-name bash-runtime \
  --version-number 2 \  
  --statement-id xaccount \
  --action lambda:GetLayerVersion \
  --principal 111122223333 \
  --output text
```

您应该可以看到类似于如下所示的输出内容：

```
{"Sid":"xaccount","Effect":"Allow","Principal":{"AWS":"arn:aws:iam::111122223333:root"},"Action":"lambda:GetLayerVersion","Resource":"arn:aws:lambda:us-east-1:123456789012:layer:bash-runtime:2"}
```

权限仅适用于单个层版本。每次创建新的层版本时都需重复此过程。

要向 [AWS Organizations](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_introduction.html) 组织中的所有账户授予权限，请使用 `organization-id` 选项。以下示例授予组织 `o-t194hfs8cz` 中的所有账户使用 `my-layer` 版本 3 的权限。

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

您应看到以下输出：

```
{"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"}}}"
```

要向多个账户或组织授予权限，您必须添加多个语句。