

# 使用 Amazon VPC 端点策略控制对 AWS STS 的访问
<a name="reference_sts_vpc_endpoint_policies"></a>

为 AWS Security Token Service (AWS STS) 创建接口 VPC 端点时，可以附加端点策略。该策略控制哪些主体可以使用端点以及他们可以执行哪些 AWS STS 操作。如果您未附加策略，端点将使用默认策略，允许所有主体对所有 AWS STS 操作进行无限制访问。

VPC 端点策略不会自行授予权限。它们充当与其他策略配合使用的额外边界。端点策略和调用方的适用策略都必须允许请求才能使请求成功。

有关 VPC 端点策略的更多信息，请参阅*《Amazon VPC 用户指南》*中的[使用端点策略控制对 VPC 端点的访问](https://docs.aws.amazon.com/vpc/latest/privatelink/vpc-endpoints-access.html)。

**Topics**
+ [默认的 VPC 端点策略](#reference_sts_vpc_endpoint_policies_default)
+ [AWS STS VPC 端点策略的重要注意事项](#reference_sts_vpc_endpoint_policies_considerations)
+ [可用于 AWS STS VPC 端点策略的条件键](#reference_sts_vpc_endpoint_policies_condition_keys)
+ [示例：允许组织执行所有 AWS STS 操作](#reference_sts_vpc_endpoint_policies_example_org)
+ [示例：允许特定账户执行所有 AWS STS 操作](#reference_sts_vpc_endpoint_policies_example_accounts)
+ [示例：限制为特定 AWS STS 操作](#reference_sts_vpc_endpoint_policies_example_actions)
+ [示例：在允许联合身份验证的同时拒绝非组织访问](#reference_sts_vpc_endpoint_policies_example_deny)

## 默认的 VPC 端点策略
<a name="reference_sts_vpc_endpoint_policies_default"></a>

如果在创建端点时未附加自定义策略，则 AWS 将附加以下默认策略。此策略允许对端点进行不受限制的访问。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "*",
            "Resource": "*"
        }
    ]
}
```

要限制对端点的访问，请附加自定义端点策略。

## AWS STS VPC 端点策略的重要注意事项
<a name="reference_sts_vpc_endpoint_policies_considerations"></a>

AWS STS 处理来自两种截然不同类型的调用方的请求。您的 VPC 端点策略必须考虑这两种类型，以免无意中阻止合法请求。

**经过身份验证的 AWS 主体**  
使用 AWS 签名版本 4 (SigV4) 对请求进行签名的 IAM 用户和 IAM 角色。这些调用方在请求上下文中具有标准条件键，例如 `aws:PrincipalOrgID`、`aws:PrincipalAccount` 和 `aws:PrincipalArn`。

**联合调用方**  
调用 `AssumeRoleWithSAML` 或 `AssumeRoleWithWebIdentity` 的 SAML 2.0 和 OpenID Connect (OIDC) 主体。这些调用方使用 SAML 断言或 JSON Web 令牌 (JWT) 进行身份验证，而不是 SigV4 签名。由于它们在请求时没有 AWS 身份，因此请求上下文不包括基于主体的条件键，例如 `aws:PrincipalOrgID`、`aws:PrincipalAccount` 和 `aws:PrincipalArn`。

**重要**  
如果您的 VPC 端点策略仅依赖于 `aws:PrincipalOrgID` 来允许访问，则联合 `AssumeRoleWithSAML` 和 `AssumeRoleWithWebIdentity` 调用将被隐式拒绝，因为非 AWS 主体不存在该条件键。

### AWS STS 如何评估联合调用方的 VPC 端点策略
<a name="reference_sts_vpc_endpoint_policies_federated_evaluation"></a>

当联合调用方通过 VPC 端点调用 `AssumeRoleWithSAML` 或 `AssumeRoleWithWebIdentity` 时，以下情况适用：
+ 调用方不是 AWS 主体。诸如 `aws:PrincipalOrgID`、`aws:PrincipalAccount` 和 `aws:PrincipalArn` 之类的条件键在请求上下文中不可用。
+ 联合调用方在请求上下文中没有条件键 `aws:PrincipalIsAWSService`。
+ 所代入的角色是一种 AWS 资源。基于资源的条件键（例如 `aws:ResourceOrgID` 和 `aws:ResourceAccount`）可用，它们指的是目标角色。
+ 该角色的信任策略仍然是联合访问的主要授权关卡。VPC 端点策略提供了额外的网络级边界。

我们建议在编写必须适用于联合调用方的 VPC 端点策略语句时使用 `aws:ResourceOrgID` 或 `aws:ResourceAccount`，因为这些调用方没有可用的基于主体的条件键。

## 可用于 AWS STS VPC 端点策略的条件键
<a name="reference_sts_vpc_endpoint_policies_condition_keys"></a>

下表显示了通过 AWS STS VPC 端点发出请求时，每种调用方类型的常用条件键及其在请求上下文中的可用性。除了此处列出的条件键之外，还有更多可用条件键。


**按调用方类型划分的条件键可用性**  

| 条件键 | 经过身份验证的 AWS 主体 | 联合调用方 | Description | 
| --- | --- | --- | --- | 
| `aws:PrincipalOrgID` | 是 | 否 | 调用主体的组织 ID | 
| `aws:PrincipalAccount` | 是 | 否 | 调用主体的账户 ID | 
| `aws:PrincipalArn` | 是 | 否 | 调用主体的 ARN | 
| `aws:PrincipalIsAWSService` | 是（评估结果为 false） | 否（键不存在） | 调用方是否为 AWS 服务主体 | 
| `aws:ResourceOrgID` | 支持 | 是 | 拥有所请求资源的账户的组织 ID | 
| `aws:ResourceAccount` | 支持 | 是 | 拥有所请求资源的账户 ID。 | 

**注意**  
对于经过身份验证的 AWS 主体（IAM 用户和角色），`aws:PrincipalIsAWSService` 存在于请求上下文中并评估为 false。对于联合调用方，此键完全不存在于请求上下文中。检查 `"Bool": {"aws:PrincipalIsAWSService": "false"}` 的条件与联合调用方不匹配，因为该键不存在。

## 示例：允许组织执行所有 AWS STS 操作
<a name="reference_sts_vpc_endpoint_policies_example_org"></a>

以下端点策略将您的 AWS STS VPC 端点限制在您的组织范围内，同时支持联合访问。它允许组织中经过身份验证的主体执行所有 AWS STS 操作，并单独允许联合调用方在组织中代入角色。联合调用方（`AssumeRoleWithSAML` 和 `AssumeRoleWithWebIdentity`）需要单独的语句，因为他们在请求上下文中没有 `aws:PrincipalOrgID`。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowOrganizationPrincipals",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "sts:*",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "o-exampleorgid"
                }
            }
        },
        {
            "Sid": "AllowFederatedAssumeRole",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "sts:AssumeRoleWithSAML",
                "sts:AssumeRoleWithWebIdentity"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceOrgID": "o-exampleorgid"
                }
            }
        }
    ]
}
```

第一个语句将 `"Principal": {"AWS": "*"}` 与 `aws:PrincipalOrgID` 结合使用，以允许来自贵组织中经过身份验证的 AWS 主体。第二个语句使用 `"Principal": "*"` 匹配联合调用方，并使用 `aws:ResourceOrgID` 将目标角色限制为贵组织。角色的信任策略仍然是控制哪些联合身份可以代入哪些角色的主要手段。

有关实施网络边界控制的更多信息，请参阅 GitHub 网站上的[在 AWS 上构建数据边界](https://docs.aws.amazon.com/whitepapers/latest/building-a-data-perimeter-on-aws/building-a-data-perimeter-on-aws.html)以及[数据边界策略示例](https://github.com/aws-samples/data-perimeter-policy-examples)。

## 示例：允许特定账户执行所有 AWS STS 操作
<a name="reference_sts_vpc_endpoint_policies_example_accounts"></a>

以下 VPC 端点策略允许特定账户中的主体执行所有 AWS STS 操作。如果您的账户不属于组织，请使用此策略。在单独的语句允许联合调用方，因为他们在请求上下文中没有 `aws:PrincipalAccount`。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowSpecificAccountPrincipals",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "sts:*",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalAccount": [
                        "111122223333",
                        "444455556666"
                    ]
                }
            }
        },
        {
            "Sid": "AllowFederatedAssumeRole",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "sts:AssumeRoleWithSAML",
                "sts:AssumeRoleWithWebIdentity"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceAccount": [
                        "111122223333",
                        "444455556666"
                    ]
                }
            }
        }
    ]
}
```

第一个语句将 `"Principal": {"AWS": "*"}` 与 `aws:PrincipalAccount` 结合使用，以允许来自指定账户的经过身份验证的 AWS 主体。第二个语句使用 `"Principal": "*"` 匹配联合调用方，并使用 `aws:ResourceAccount` 将目标角色限制为相同的账户。角色的信任策略仍然是控制哪些联合身份可以代入哪些角色的主要手段。

## 示例：限制为特定 AWS STS 操作
<a name="reference_sts_vpc_endpoint_policies_example_actions"></a>

以下端点策略仅允许经过身份验证的主体执行 `AssumeRole`，以及允许联合调用方执行 `AssumeRoleWithSAML`，两者的范围均限于组织中的角色。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAssumeRoleByOrgPrincipals",
            "Effect": "Allow",
            "Principal": {
                "AWS": "*"
            },
            "Action": "sts:AssumeRole",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "o-exampleorgid"
                }
            }
        },
        {
            "Sid": "AllowSAMLFederation",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "sts:AssumeRoleWithSAML",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceOrgID": "o-exampleorgid"
                }
            }
        }
    ]
}
```

此策略会阻止通过此端点执行的其他 AWS STS 操作，例如 `GetCallerIdentity`、`GetSessionToken` 和 `AssumeRoleWithWebIdentity`。调整 `Action` 元素以满足您的要求。

## 示例：在允许联合身份验证的同时拒绝非组织访问
<a name="reference_sts_vpc_endpoint_policies_example_deny"></a>

以下端点策略使用显式拒绝来阻止组织外部经过身份验证的主体，同时保留联合调用方的访问权限。这种方法从广泛允许开始，然后添加有针对性的拒绝语句。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAll",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "*",
            "Resource": "*"
        },
        {
            "Sid": "DenyNonOrgPrincipals",
            "Effect": "Deny",
            "Principal": {
                "AWS": "*"
            },
            "Action": "sts:*",
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:PrincipalOrgID": "o-exampleorgid"
                }
            }
        }
    ]
}
```

拒绝语句使用 `"Principal": {"AWS": "*"}`，其范围仅限于经过身份验证的 AWS 主体。联合调用方（SAML 和 OIDC）不是 AWS 主体，与此 `Principal` 元素不匹配，因此拒绝不适用于它们。这种方法避免了为联合调用方规定例外情况而需要使用复杂的 `Null` 或 `Bool` 条件。

**注意**  
第一个语句允许所有主体执行所有操作。第二个语句中的拒绝优先于组织外部经过身份验证的 AWS 主体。联合调用方在第一个语句中得到允许，并且不受拒绝影响，因为拒绝语句中的 `Principal` 元素与它们不匹配。