# 传递会话标签
会话标签（Session tags）根据您所调用的华为云安全令牌服务（STS）API的不同，其传递方式也有所不同：在调用AssumeAgency API时，会话标签通过切换IAM信任委托时tags参数进行传递；在调用AssumeAgencyWithSAML API时，会话标签通过SAML断言中指定的属性进行传递；在调用AssumeAgencyWithOIDC API时，会话标签通过OIDC令牌中的指定字段进行传递。具体传递方式参见后续段落。
当调用STS服务的上述API时，您会获得一个临时安全凭证（包括临时AK/SK和会话令牌security_token），该临时安全凭证对应本次委托会话（Assumed-agency），具有过期时间。当您使用该临时安全凭证发起后续请求时，请求上下文中会包含g:PrincipalTag条件键。您可以在策略的Condition元素中使用g:PrincipalTag条件键，来基于这些标签允许或拒绝访问。
#### 会话标签
目前您只能在STS的AssumeAgency API、AssumeAgencyWithSAML API和AssumeAgencyWithOIDC API传递会话标签，在IAM控制台切换信任委托时不支持传递会话标签。
您还可以通过设置transitive_tag_keys将会话标签设置为可传递（transitive）。同样，根据您所调用的华为云安全令牌服务（STS）API的不同，其传递方式也有所不同：在调用AssumeAgency API时，会话标签通过切换IAM信任委托时的transitive_tag_keys参数进行传递；在调用AssumeAgencyWithSAML API时，会话标签通过SAML断言中指定的属性进行传递；在调用AssumeAgencyWithOIDC API时，会话标签通过OIDC令牌中的指定字段进行传递。具体传递方式参见后续段落。
在transitive_tag_keys中指定的会话标签将在委托链中持续存在。详细信息可以参考[获取临时安全凭证](https://support.huaweicloud.com/usermanual-iam5/iam_01_1237.html)，如果满足以下条件，则传递会话标签的STS API调用会失败：
- 您传递的会话标签tags数量超过20个。
- 会话标签tags中键的纯文本超过128个字符。
- 会话标签tags中值的纯文本超过255个字符。
- 传递会话标签transitive_tag_keys数量超过20个。
 
#### 会话标签注意事项
在使用会话标签前，请了解以下关于会话标签的细节：
- 当使用会话标签时，准备切换信任委托的主体（IAM用户或信任委托）附加的身份策略和目标信任委托的信任策略必须都包含sts::tagSession授权项，否则AssumeAgency操作将失败。对于AssumeAgencyWithSAML API和AssumeAgencyWithOIDC API，只需要目标信任委托的信任策略中包含sts::tagSession授权项即可。
- 会话标签采用键值对形式。例如，若要在会话中添加联系信息，可以设置标签键为email，标签值为xxxxxx@example.com。
- 在使用委托链时（一个信任委托切换到另外一个信任委托）无法使用相同的会话标签键覆盖原有的会话标签的值。
- 您无法在IAM控制台切换信任委托时传递会话标签。
- 会话标签仅对当前会话有效。
- 会话标签支持委托链。默认情况下，STS不会将标签传递至后续信任委托会话，但您可以将会话标签设置为可传递，使标签在委托链中持续存在。
- 您可以使用g:PrincipalTag条件键来控制委托会话对华为云资源的访问。
 
#### 使用会话标签所需要的权限
要想设置会话标签，除了需要与STS API相匹配的API授权项外，您的策略中还必须具有以下授权项：
```
sts::tagSession
```
- 在IAM用户切换信任委托的场景中，要指定会话标签，IAM用户的身份策略和信任委托的信任策略都必须包含sts::tagSession权限。
- 在信任委托切换信任委托的场景中，要指定会话标签，发起切换的信任委托的身份策略和目标信任委托的信任策略都必须包含sts::tagSession权限。
- 在联邦主体切换信任委托的场景中，要指定会话标签，只需要信任委托的信任策略包含sts::tagSession权限。
 
作为账号管理员，假设您希望允许账号内的IAM用户A切换到同一账号中的TrustAgencyA信任委托，且在切换时允许传递会话标签。您可以将以下身份策略附加到该IAM用户：
```
{
"Version": "5.0",
"Statement": [{
"Effect": "Allow",
"Action": [
"sts:agencies:assume",
"sts::tagSession"
]
}]
}
```
要想主体切换信任委托时可以传递会话标签，您可以在创建信任委托A时配置如下的信任策略：
```
{
"Version": "5.0",
"Statement": [{
"Action": [
"sts:agencies:assume",
"sts::tagSession"
],
"Effect": "Allow",
"Principal": {
"IAM": [
"{account_id}"
]
}
}]
}
```
#### 使用AssumeAgency API传递会话标签
AssumeAgency API会返回一组临时安全凭证，您可以使用这些凭证来访问华为云资源。你可以使用IAM用户或委托凭证来调用 AssumeAgencyAPI。若要在切换委托时传递会话标签，请指定AssumeAgencyAPI 请求体中的tags参数。若要将标签设置为**可传递（transitive）**，请指定AssumeAgencyAPI 请求体中的transitive_tag_keys参数，可传递标签会在委托链中持续保留。
#### 使用AssumeAgencyWithSAML API传递会话标签
AssumeAgencyWithSAML API通过SAML协议进行身份验证，该操作会返回一组临时凭证，可用于访问华为云资源。华为云的SAML断言认证支持传递会话标签属性和可传递标签属性。
- **传递会话标签**
  若要将SAML属性作为会话标签传递，请在SAML断言中包含Attribute元素，并将Name属性设置为： https://www.huaweicloud.com/SAML/Attributes/PrincipalTag:{TagKey}；
  使用AttributeValue元素指定标签的值。每个会话标签需包含一个独立的Attribute元素。
  **示例：** 传递Project:Automation、CostCenter:12345和Department:Engineering。
  ```
  <Attribute Name="https://www.huaweicloud.com/SAML/Attributes/PrincipalTag:Project">
    <AttributeValue>Automation</AttributeValue>
  </Attribute>
  <Attribute Name="https://www.huaweicloud.com/SAML/Attributes/PrincipalTag:CostCenter">
    <AttributeValue>12345</AttributeValue>
  </Attribute>
  <Attribute Name="https://www.huaweicloud.com/SAML/Attributes/PrincipalTag:Department">
    <AttributeValue>Engineering</AttributeValue>
  </Attribute>
  ```
  
- **设置可传递标签**
  若要将上述标签设置为**可传递**（在委托链中持续保留），请另加一个Attribute元素，其Name属性设置为： https://www.huaweicloud.com/SAML/Attributes/TransitiveTagKeys
  **示例：** 将 Project 和 Department 设置为可传递。
  ```
  <Attribute Name="https://www.huaweicloud.com/SAML/Attributes/TransitiveTagKeys">
    <AttributeValue>Project</AttributeValue>
    <AttributeValue>Department</AttributeValue>
  </Attribute>
  ```
  
 
#### 使用AssumeAgencyWithOIDC API传递会话标签
AssumeAgencyWithOIDC API通过OIDC协议进行身份验证，该操作会返回一组临时凭证，可用于访问华为云资源。若要从OIDC传递会话标签，您必须在提交请求时，将标签包含在OIDC令牌中。华为云在OIDC令牌的认证中支持两种会话标签的声明格式：**嵌套式声明格式** 和**扁平化声明格式** 。扁平化声明格式虽然在结构上与嵌套声明格式不同，但其实现的功能完全一致。它的存在主要是为了兼容那些不支持在OIDC令牌声明中嵌套JSON对象的身份提供商，例如Microsoft Entra ID。扁平化声明格式与嵌套声明格式不可同时使用**。**
- **嵌套声明格式 (Nested Claim Format)**
  这种格式在OIDC令牌中使用 https://www.huaweicloud.com/tags 声明下的结构化对象组成。
  - **主体标签**：使用principal_tags键下的嵌套对象表示。
  
  - **可传递的标签键列表**：使用transitive_tag_keys键下的数组表示。
  
  - 两者都嵌套在华为云命名空间下。
   
  ```
  {
      "sub": "johndoe",
      "iss": "https://xyz.com",
      "https://www.huaweicloud.com/tags": {
          "principal_tags": {
              "Project": "Automation",
              "CostCenter": "987654",
              "Department": "Engineering"
          },
          "transitive_tag_keys": [
              "Project",
              "CostCenter"
          ]
      }
  }
  ```
  

- **扁平化声明格式**
  此格式适用于不支持在OIDC令牌声明中使用嵌套对象的身份提供商（例如 **Microsoft Entra ID** ）。
  - **主体标签**：使用带有前缀 https://www.huaweicloud.com/tags/principal_tags/ 的独立声明表示。
  
  - **可传递的标签键列表**：使用带有前缀 https://www.huaweicloud.com/tags/transitive_tag_keys 的单个声明表示，其值为字符串数组。
   
  ```
  {
      "sub": "johndoe",
      "iss": "https://xyz.com",
      "https://www.huaweicloud.com/tags/principal_tags/Project": "Automation",
      "https://www.huaweicloud.com/tags/principal_tags/CostCenter": "987654",
      "https://www.huaweicloud.com/tags/principal_tags/Department": "Engineering",
      "https://www.huaweicloud.com/tags/transitive_tag_keys": [
          "Project",
          "CostCenter"
      ]
  }
  ```
  
#### 委托链中的会话标签
您可以先切换到一个信任委托，然后使用获取的临时凭证切换到另外一个信任委托，这一过程称为委托链（Agency Chaining）。在您设置会话标签时，您可以将标签键设置为可传递，以确保这些会话标签能传递至委托链中的后续会话。请注意：信任委托身上的标签无法设为可传递，若要将这些标签传递至后续会话，必须将其明确指定为会话标签。
以下示例演示了STS如何在委托链中将会话标签、委托标签传递至后续会话。在此委托链场景中，您通过AssumeAgency API使用IAM用户访问密钥切换到TrustAgency1的信任委托，随后利用生成的会话临时安全凭证切换到第二个信任委托TrustAgency2，最后使用第二次会话的临时安全凭证切换到第三个信任委托TrustAgency3。这些请求作为三个独立操作执行，且每个信任委托已预先在IAM中打上了标签，每次请求时您可以使用AssumeAgency API中的tags和transitive_tag_keys参数确保会话标签从早期会话传递到后续会话。
![](https://support.huaweicloud.com/usermanual-iam5/zh-cn_image_0000002394839117.png "点击放大")
假设切换**TrustAgency1** 时在AssumeAgency API中设置了会话标签Team=1，且将Team设置为了可传递。此时，在TrustAgency1身上打了标签EmployeeID=1，如果您想要将委托标签EmployeeID=1也传递至后续会话，那么您必须**手动在AssumeAgency API中也将其作为会话标签并设置为可传递** 。最后，生成的**会话主体（Session Principal）**中将同时包含Team=1和EmployeeID=1这两个标签，这样您便可以使用g:PrincipalTag/Team、g:PrincipalTag/EmployeeID条件键进行访问控制。
![](https://support.huaweicloud.com/usermanual-iam5/zh-cn_image_0000002394719529.png "点击放大")
现在您使用会话1的临时安全凭证去切换**TrustAgency2**，Team=1和EmployeeID=1将从会话1继承到会话2。此时，在TrustAgency2身上打了标签JobRole=2，但是您没有将其作为会话标签并设置为可传递。最后，虽然生成的会话主体中将同时包含Team=1、EmployeeID=1和JobRole=2这三个标签，但是JobRole=2将不会往后续的会话中进行传递，只在本次会话2中有效。
![](https://support.huaweicloud.com/usermanual-iam5/zh-cn_image_0000002361120076.png "点击放大")
最后您使用会话2的临时安全凭证去切换**TrustAgency3** ，Team=1和EmployeeID=1将从会话2继续继承到会话3。实际上，会话3的**主体标签（Principal Tag）** 将由新增的会话标签、新增的可传递标签、信任委托本身的委托标签构成。此时，在TrustAgency3身上打了标签Team=3，继承的标签Team=1和信任委托本身的标签Team=3在标签键上是相同的，由于继承的标签优先级要高于信任委托本身的标签，因此Team=1将覆盖Team=3。最后，生成的**会话主体**中将同时包含Team=1、EmployeeID=1这两个标签。
![](https://support.huaweicloud.com/usermanual-iam5/zh-cn_image_0000002394720461.png "点击放大")
#### 将会话标签用于访问控制
可以在信任委托身上附加身份策略要求满足g:PrincipalTag/Team=1时才拥有IAM访问权限，策略示例如下：
```
{
"Version": "5.0",
"Statement": [{
"Effect": "Allow",
"Action": [
"iam:*:*"
],
"Condition": {
"StringEquals": {
"g:PrincipalTag/Team": [
"1"
]
}
}
}]
}
```
如果信任委托本身没有Team=1的委托标签，那么在调用AssumeAgency API切换信任委托时，只有在tags参数中填写key=Team，value=1时获取的临时安全凭证会话才拥有访问IAM的权限，AssumeAgency API请求体示例如下：
```
{
"agency_urn": "iam::account_id:agency:agency_name",
"agency_session_name": "session_name",
"tags": [{
"key": "Team",
"value": "1"
}]
}
```
