

# 在 Lambda 中使用基于属性的访问控制
<a name="attribute-based-access-control"></a>

借助[基于属性的访问权限控制（ABAC）](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction_attribute-based-access-control.html)，您可以使用标签来控制对 Lambda 资源的访问。您可以将标签附加到某些 Lambda 资源，附加到某些 API 请求，或附加到发出请求的 AWS Identity and Access Management（IAM）主体。有关 AWS 如何授予基于属性的访问权限的更多信息，请参阅《*IAM 用户指南*》中的[使用标签控制对 AWS 资源的访问](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_tags.html)。

您可以使用 ABAC [授予最低权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)，而无需在 IAM policy 中指定 Amazon 资源名称 (ARN) 或 ARN 模式。相反，您可以在 IAM policy 的[条件元素](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_condition.html)中指定一个标签来控制访问。使用 ABAC 可以更轻松地进行扩展，因为您无需在创建新资源时更新 IAM 策略。相反，将标签添加到新资源即可控制访问权限。

在 Lambda 中，标签可用于以下资源：
+ 函数 – 有关标记函数的更多信息，请参阅[在 Lambda 函数上使用标签](configuration-tags.md)。
+ 代码签名配置 – 有关标记代码签名配置的更多信息，请参阅[在代码签名配置上使用标签](tags-csc.md)。
+ 事件源映射 – 有关标记事件源映射的更多信息，请参阅[在事件源映射上使用标签](tags-esm.md)。

层不支持标签。

可以使用以下条件键根据标签编写 IAM 策略规则：
+ [aws:ResourceTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag)：根据附加到 Lambda 资源的标签控制访问权限。
+ [aws:RequestTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag)：要求请求中存在标签，例如在创建新函数时。
+ [aws:PrincipalTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-principaltag)：根据附加到其 IAM [用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags_users.html)或[角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_tags_roles.html)的标签，控制允许 IAM 主体（发出请求的人）执行的操作。
+  [aws:TagKeys](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys)：控制是否可以在请求中使用特定的标签键。

 只能为支持这些条件的操作指定条件。有关各 Lambda 操作支持的条件列表，请参阅《Service Authorization Reference》中的 [Actions, resources, and condition keys for AWS Lambda](https://docs.aws.amazon.com//service-authorization/latest/reference/list_awslambda.html)。有关 **aws:ResourceTag/tag-key** 支持，请参阅该文档中的“Resource types defined by AWS Lambda”。有关 **aws:RequestTag/tag-key** 和 **aws:TagKeys** 支持，同样请参阅该文档中的“Actions defined by AWS Lambda”。

**Topics**
+ [通过标签保护函数](attribute-based-access-control-example.md)

# 通过标签保护函数
<a name="attribute-based-access-control-example"></a>

以下步骤演示了一种使用 ABAC 设置函数权限的方法。在此示例方案中，您将创建四个 IAM 权限策略。然后，您会将这些策略附加到新的 IAM 角色。最后，您将创建一个 IAM 用户并授予该用户担任新角色的权限。

**Topics**
+ [先决条件](#abac-prerequisites)
+ [步骤 1：要求新函数具有标签](#require-tag-on-create)
+ [步骤 2：允许基于附加到 Lambda 函数和 IAM 主体的标签执行操作](#restrict-actions-function-tags)
+ [步骤 3：授予列表权限](#abac-list-permissions)
+ [步骤 4：授予 IAM 权限](#abac-iam-permissions)
+ [步骤 5：创建 IAM 角色](#abac-create-role)
+ [步骤 6：创建 IAM 用户](#abac-create-user)
+ [步骤 7：测试权限](#abac-test)
+ [步骤 8：清理资源](#abac-clean-up)

## 先决条件
<a name="abac-prerequisites"></a>

确保您具有 [Lambda 执行角色](lambda-intro-execution-role.md)。当您授予 IAM 权限和创建 Lambda 函数时，您将使用此角色。

## 步骤 1：要求新函数具有标签
<a name="require-tag-on-create"></a>

当将 ABAC 与 Lambda 配合使用时，最佳做法是要求所有函数都具有标签。这有助于确保您的 ABAC 权限策略按预期工作。

[创建类似于以下示例的 IAM policy](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html#access_policies_create-json-editor)。此策略使用 [aws:RequestTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-requesttag)、[aws:ResourceTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag) 和 [aws:TagKeys](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-tagkeys) 条件键来要求新函数和创建函数的 IAM 主体都具有 `project` 标签。`ForAllValues` 修饰符确保 `project` 是唯一允许的标签。如果您未包括 `ForAllValues` 修饰符，则用户可以将其他标签添加到函数中，只要它们也传递 `project`。

**Example – 要求新函数具有标签**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
      "Effect": "Allow",
      "Action": [
        "lambda:CreateFunction",
        "lambda:TagResource"
      ],
      "Resource": "arn:aws:lambda:*:*:function:*",
      "Condition": {
        "StringEquals": {
          "aws:RequestTag/project": "${aws:PrincipalTag/project}",
          "aws:ResourceTag/project": "${aws:PrincipalTag/project}"
        },
        "ForAllValues:StringEquals": {
          "aws:TagKeys": "project"
        }
      }
    }
  }
```

## 步骤 2：允许基于附加到 Lambda 函数和 IAM 主体的标签执行操作
<a name="restrict-actions-function-tags"></a>

使用 [aws:ResourceTag/tag-key](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-resourcetag) 条件键创建第二个 IAM policy，以要求主体的标签与附加到函数的标签匹配。以下示例策略允许具有 `project` 标签的委托人调用具有 `project` 标签的函数。如果函数具有任何其他标签，则该操作将被拒绝。

**Example – 要求函数和 IAM 主体的标签匹配**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Effect": "Allow",
        "Action": [
          "lambda:InvokeFunction",
          "lambda:GetFunction"
        ],
        "Resource": "arn:aws:lambda:*:*:function:*",
        "Condition": {
          "StringEquals": {
            "aws:ResourceTag/project": "${aws:PrincipalTag/project}"
          }
        }
      }
    ]
  }
```

## 步骤 3：授予列表权限
<a name="abac-list-permissions"></a>

创建允许主体列出 Lambda 函数和 IAM 角色的策略。这样，主体就可以在控制台上以及调用 API 操作时查看所有 Lambda 函数和 IAM 角色。

**Example – 授予 Lambda 和 IAM 列表权限**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Sid": "AllResourcesLambdaNoTags",
        "Effect": "Allow",
        "Action": [
          "lambda:GetAccountSettings",
          "lambda:ListFunctions",
          "iam:ListRoles"
        ],
        "Resource": "*"
      }
    ]
  }
```

## 步骤 4：授予 IAM 权限
<a name="abac-iam-permissions"></a>

创建允许 **iam:PassRole** 的策略。当您将执行角色分配给函数时，需要此权限。在以下示例策略中，将示例 ARN 替换为 Lambda 执行角色的 ARN。

**注意**  
不要在策略中将 `ResourceTag` 条件键与 `iam:PassRole` 操作一起使用。您无法在 IAM 角色上使用标签以控制可以传递该角色的用户的访问权限。有关将角色传递给服务所需权限的更多信息，请参阅[授予用户将角色传递给 AWS 服务的权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_passrole.html)。

**Example – 授予传递执行角色的权限**    
****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Sid": "VisualEditor0",
        "Effect": "Allow",
        "Action": [
          "iam:PassRole"
        ],
        "Resource": "arn:aws:iam::111122223333:role/lambda-ex"
      }
    ]
  }
```

## 步骤 5：创建 IAM 角色
<a name="abac-create-role"></a>

[使用角色委托权限](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#delegate-using-roles)是最佳实践。[创建名为 `abac-project-role` 的 IAM 角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html#roles-creatingrole-user-console)：
+ 在**步骤 1：选择可信实体**中：选择 **AWS 账户**，然后选择**此账户**。
+ 在**步骤 2：添加权限**上：附加您在前面的步骤中创建的四个 IAM policy。
+ 在**步骤 3：命名、查看和创建**上：选择 **Add tag**（添加标签）。对于**键**，输入 `project`。不要输入 **Value**（值）。

## 步骤 6：创建 IAM 用户
<a name="abac-create-user"></a>

[创建名为 `abac-test-user` 的 IAM 用户](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html#id_users_create_console)。在 **Set permissions**（设置权限）部分中，选择 **Attach existing policies directly**（直接附加现有策略），然后选择 **Create policy**（创建策略）。输入以下策略定义。将 *111122223333* 替换为您的 [AWS 账户 ID](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html#FindingYourAccountIdentifiers)。此策略允许 `abac-test-user` 担任 `abac-project-role`。

**Example – 允许 IAM 用户担任 ABAC 角色**  

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::111122223333:role/abac-project-role"
    }
  }
```

------

## 步骤 7：测试权限
<a name="abac-test"></a>

1. 以 `abac-test-user` 身份登录到 AWS 控制台。有关更多信息，请参阅[作为 IAM 用户登录](https://docs.aws.amazon.com/IAM/latest/UserGuide/console.html#user-sign-in-page)。

1. 切换到 `abac-project-role` 角色。有关更多信息，请参阅[切换到角色（控制台）](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_use_switch-role-console.html)。

1. [创建 Lambda 函数](configuration-tags.md#using-tags-with-the-console)：
   + 在 **Permissions**（权限）下，选择 **Change default execution role**（更改默认执行角色），然后对于 **Execution role**（执行角色），选择 **Use an existing role**（使用现有角色）。选择您在 [步骤 4：授予 IAM 权限](#abac-iam-permissions) 中使用的相同执行角色。
   + 在 **Advanced settings**（高级设置）下，选择 **Enable tags**（启用标签），然后选择 **Add new tag**（添加新标签）。对于**键**，输入 `project`。不要输入 **Value**（值）。

1. [测试函数](testing-functions.md)。

1. 创建第二个 Lambda 函数并添加其他标签，例如 `environment`。此操作应会失败，因为您在 [步骤 1：要求新函数具有标签](#require-tag-on-create) 中创建的 ABAC 策略仅允许主体创建具有 `project` 标签的函数。

1. 创建第三个没有标签的函数。此操作应会失败，因为您在 [步骤 1：要求新函数具有标签](#require-tag-on-create) 中创建的 ABAC 策略不允许主体创建没有标签的函数。

此授权策略允许您控制访问权限，而无需为每个新用户创建新的策略。要向新用户授予访问权限，只需授予他们担任与其所分配项目相对应的角色的权限。

## 步骤 8：清理资源
<a name="abac-clean-up"></a>

**要删除 IAM 角色**

1. 打开 IAM 控制台的[角色页面](https://console.aws.amazon.com/iam/home#/roles)。

1. 选择您在[步骤 5](#abac-create-role) 中创建的角色。

1. 选择**删除**。

1. 要确认删除，在文本输入字段中输入角色名称。

1. 选择**删除**。

**删除 IAM 用户**

1. 打开 IAM 控制台的[用户页面](https://console.aws.amazon.com/iam/home#/users)。

1. 选择您在[步骤 6](#abac-create-user) 中创建的 IAM 用户。

1. 选择**删除**。

1. 要确认删除，在文本输入字段中输入用户名。

1. 选择**删除用户**。

**删除 Lambda 函数**

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

1. 选择您创建的函数。

1. 依次选择**操作**和**删除**。

1. 在文本输入字段中键入 **confirm**，然后选择 **Delete**（删除）。