管理基於上下文的限制

您可以隨時更新描述(有助於識別規則的目的)或選擇新的資源和網路環境清單,從而管理上下文規則。 您也可以移除基於上下文的限制,以刪除規則中由上下文定義的限制。

基於情境的限制可定義並強制執行其本身 IBM Cloud® 資源的存取限制。 您可以根據情境 (例如網路區域和端點類型) 定義這些限制。 如需詳細資訊,請參閱 什麼是基於上下文的限制

基於上下文的限制服務會管理規則和網路區域,因此如果您無法滿足基於上下文的限制服務上的規則,就有可能完全失去管理這些資源的能力。 只有當請求的上下文符合新的或修改過的規則時,才允許嘗試建立或更新此類規則。

如果您無法再滿足以基於情境的限制服務為目標的規則,請 開啟支援個案,並提供您可以滿足的情境,以恢復您的存取權限。

開始之前

若要管理基於上下文的限制,您必須在帳戶管理服務上指定管理員角色。

使用主控台更新規則

若要編輯雲端資源上基於上下文的限制,請完成下列步驟:

  1. 在 IBM Cloud 主控台中,按一下管理 > 基於上下文的限制,然後選擇規則
  2. 在要更新的規則上選取 行動 圖示 動作圖示,然後選取 編輯
  3. 若要更新操作受規則限制的 API 範圍,請選擇「所有 API」或「特定 API」。 然後按一下套用繼續
  4. 若要更新限制的資源範圍,您可以根據可用的屬性 (例如資源群組或位置) 選擇「所有資源」或「特定資源」。 然後按一下套用繼續
  5. 按一下摘要面板中的 Edit 圖示 Edit 圖示 輯),以更新現有的上下文。
    1. 更新允許的端點類型。
      • 請將切換設定為否以允許所有服務支援的端點類型。
      • 將切換設為是,以僅允許特定端點類型。
    2. 更新工作區。 您可以選取新的網路區域,或取消選取網路區域以將其移除。
  6. 然後按一下套用
  7. 按一下摘要面板中的移除圖示移除圖示,以移除上下文。
  8. 透過選擇所有端點或特定端點,以及選擇您的網路區域,設定新的上下文。 然後,按一下新增
  9. 按一下「套用」或「繼續」。
  10. 為您的規則提供新的說明。 按一下套用以更新說明,或按一下繼續
  11. 若要更新規則的執行,請按一下 Edit 圖示 Edit 圖示。 您可以啟用停用或將規則設定為僅報告
  12. 按一下套用完成。

使用 CLI 更新規則

若要更新雲端資源上基於上下文的限制,請使用 ibmcloud cbr rule-update 指令。 以下範例會更新 ID 為 30fd58c9b75f40e854b89c432318b4a2 的規則的說明、允許的端點類型和網路區域。

ibmcloud cbr rule-update 30fd58c9b75f40e854b89c432318b4a2 --description 'Example rule description' --service-name kms --context-attributes endpointType=private --zone-id 93de8d3f588ab2c457ff576c364d1145

使用 API 更新規則

若要透過建立規則來更新雲端資源的限制,請呼叫 Context-based restrictions API

  1. 取得規則 您想要替換的 在回應正文中,複製規則 ID,並在回應標頭中複製 ETag 標頭。

    curl -X GET --location --header "Authorization: Bearer {iam_token}" --header "Accept: application/json" "https://cbr.cloud.ibm.com/v1/rules/{rule_id}"
    
    GetRuleOptions getRuleOptions = new GetRuleOptions.Builder()
    .ruleId(ruleID)
    .build();
    Response<Rule> response = contextBasedRestrictionsService.getRule(getRuleOptions).execute();
    Rule rule = response.getResult();
    System.out.println(rule);
    
    const params = {
      ruleId,
    };
    try {
      const res = await contextBasedRestrictionsService.getRule(params);
      console.log(JSON.stringify(res.result, null, 2));
    } catch (err) {
      console.warn(err);
    }
    
    rule = context_based_restrictions_service.get_rule(
      rule_id=rule_id
    )
    rule = rule.get_result()
    print(json.dumps(rule, indent=2))
    
    getRuleOptions := contextBasedRestrictionsService.NewGetRuleOptions(
      ruleID,
    )
    rule, response, err := contextBasedRestrictionsService.GetRule(getRuleOptions)
    if err != nil {
      panic(err)
    }
    b, _ := json.MarshalIndent(rule, "", "  ")
    fmt.Println(string(b))
    
  2. 以下範例以更新版本取代規則。 取代請求的 If-Match 標頭中需要 ETag 值。

    curl -X PUT --location --header "Authorization: Bearer {iam_token}" --header "Accept: application/json" --header "If-Match: {if_match}" --header "Content-Type: application/json" --data '{ "description": "this is an example of rule", "resources": [ { "attributes": [ { "name": "accountId", "value": "12ab34cd56ef78ab90cd12ef34ab56cd" }, { "name": "serviceName", "value": "kms" } ] } ], "contexts": [ { "attributes": [ { "name": "networkZoneId", "value": "76921bd873115033bd2a0909fe081b45" } ] } ], "enforcement_mode": "disabled" }' "{base_url}/v1/rules/{rule_id}"
    
    RuleContextAttribute ruleContextAttributeModel = new RuleContextAttribute.Builder()
      .name("networkZoneId")
      .value("76921bd873115033bd2a0909fe081b45")
      .build();
    RuleContext ruleContextModel = new RuleContext.Builder()
      .attributes(new java.util.ArrayList<RuleContextAttribute>(java.util.Arrays.asList(ruleContextAttributeModel)))
      .build();
    ResourceAttribute resourceAttributeModel = new ResourceAttribute.Builder()
      .name("accountId")
      .value("12ab34cd56ef78ab90cd12ef34ab56cd")
      .build();
    Resource resourceModel = new Resource.Builder()
      .attributes(new java.util.ArrayList<ResourceAttribute>(java.util.Arrays.asList(resourceAttributeModel)))
      .build();
    ReplaceRuleOptions replaceRuleOptions = new ReplaceRuleOptions.Builder()
      .ruleId("testString")
      .ifMatch("testString")
      .description("this is an example of rule")
      .enforcementMode("disabled")
      .contexts(new java.util.ArrayList<RuleContext>(java.util.Arrays.asList(ruleContextModel)))
      .resources(new java.util.ArrayList<Resource>(java.util.Arrays.asList(resourceModel)))
      .build();
    Response<OutRule> response = contextBasedRestrictionsService.replaceRule(replaceRuleOptions).execute();
    OutRule outRule = response.getResult();
    System.out.println(outRule);
    
    // Request models needed by this operation.
    // RuleContextAttribute
    const ruleContextAttributeModel = {
      name: 'networkZoneId',
      value: '76921bd873115033bd2a0909fe081b45',
    };
    // RuleContext
    const ruleContextModel = {
      attributes: [ruleContextAttributeModel],
    };
    // ResourceAttribute
    const resourceAttributeModel = {
      name: 'accountId',
      value: '12ab34cd56ef78ab90cd12ef34ab56cd',
    };
    // Resource
    const resourceModel = {
      attributes: [resourceAttributeModel],
    };
    const params = {
      ruleId: 'testString',
      ifMatch: 'testString',
      contexts: [ruleContextModel],
      resources: [resourceModel],
      description: 'this is an example of rule',
      enforcementMode: 'disabled',
    };
    contextBasedRestrictionsService.replaceRule(params)
      .then(res => {
        console.log(JSON.stringify(res.result, null, 2));
      })
      .catch(err => {
        console.warn(err)
      });
    
    rule_context_attribute_model = {
      'name': 'networkZoneId',
      'value': '76921bd873115033bd2a0909fe081b45',
    }
    rule_context_model = {
      'attributes': [rule_context_attribute_model],
    }
    resource_attribute_model = {
      'name': 'accountId',
      'value': '12ab34cd56ef78ab90cd12ef34ab56cd',
    }
    resource_model = {
      'attributes': [resource_attribute_model],
    }
    out_rule = context_based_restrictions_service.replace_rule(
      rule_id='testString',
      if_match='testString',
      contexts=[rule_context_model],
      resources=[resource_model],
      description='this is an example of rule',
      enforcement_mode='disabled'
    ).get_result()
    print(json.dumps(out_rule, indent=2))
    
    ruleContextAttributeModel := &contextbasedrestrictionsv1.RuleContextAttribute{
      Name: core.StringPtr("networkZoneId"),
      Value: core.StringPtr("76921bd873115033bd2a0909fe081b45"),
    }
    ruleContextModel := &contextbasedrestrictionsv1.RuleContext{
      Attributes: []contextbasedrestrictionsv1.RuleContextAttribute{*ruleContextAttributeModel},
    }
    resourceAttributeModel := &contextbasedrestrictionsv1.ResourceAttribute{
      Name: core.StringPtr("accountId"),
      Value: core.StringPtr("12ab34cd56ef78ab90cd12ef34ab56cd"),
    }
    resourceModel := &contextbasedrestrictionsv1.Resource{
      Attributes: []contextbasedrestrictionsv1.ResourceAttribute{*resourceAttributeModel},
    }
    replaceRuleOptions := contextBasedRestrictionsService.NewReplaceRuleOptions(
      "testString",
      "testString",
    )
    replaceRuleOptions.SetDescription("this is an example of rule")
    replaceRuleOptions.SetContexts([]contextbasedrestrictionsv1.RuleContext{*ruleContextModel})
    replaceRuleOptions.SetResources([]contextbasedrestrictionsv1.Resource{*resourceModel})
    replaceRuleOptions.SetEnforcementMode(contextbasedrestrictionsv1.ReplaceRuleOptionsEnforcementModeDisabledConst)
    outRule, response, err := contextBasedRestrictionsService.ReplaceRule(replaceRuleOptions)
    if err != nil {
      panic(err)
    }
    b, _ := json.MarshalIndent(outRule, "", "  ")
    fmt.Println(string(b))
    

使用主控台更新網路區域

您可以修改允許存取請求來源的位置清單。 一組一個或多個網路位置可以由 IP 位址 (個別位址、範圍或子網路)、VPC 或服務參考指定。 您可以更新規則中使用的網路區域,或稍後將新更新的網路區域整合到規則中。

  1. 在 IBM Cloud 主控台中,按一下管理 > 基於上下文的限制,然後選擇網路區域
  2. 在要更新的網路區域上選取 行動 圖示 動作圖示,然後選取 編輯
  3. 您可以更新您的區域名稱和描述。
  4. 您可以編輯允許存取請求來源的 IP 位址清單。 必要時,在拒絕清單中包含例外情況。
  5. 您可以新增或移除允許的 VPC。
  6. 您可以新增或移除服務參考。 選取一個服務,使其 IP 位址與您的網路區域關聯。
  7. 一下下一步,檢視您的新組態。
  8. 若要套用變更,請按一下更新

使用 CLI 更新網路區域

若要更新網路區域,請完成下列步驟。

  1. 使用 ibmcloud cbr zones 指令列出帳戶中的所有區域,擷取要更新的網路區域的區域 ID。
    ibmcloud cbr zones
    
  2. 使用 ibmcloud cbr zone-update 指令更新網路區域。 以下範例更新 ID 為 65810ac762004f22ac19f8f8edf70a34 的網路區域的區域名稱、允許的位址和排除的位址。
    ibmcloud cbr zone-update 65810ac762004f22ac19f8f8edf70a34 --name 'Example Zone Name' --addresses 166.22.23.0-166.22.23.108 --excluded 166.22.23.100
    

使用 API 更新網路區域

若要更新網路區域,請完成下列步驟。

  1. 取得區域 您想要替換的 在回應正文中,複製區域 ID,並在回應標頭中複製 ETag 標頭。

    curl -X GET --location --header "Authorization: Bearer {iam_token}" --header "Accept: application/json" "https://cbr.cloud.ibm.com/v1/zones/{zone_id}"
    
    GetZoneOptions getZoneOptions = new GetZoneOptions.Builder()
     .zoneId(zoneID)
     .build();
    Response<Zone> response = contextBasedRestrictionsService.getZone(getZoneOptions).execute();
    Zone zone = response.getResult();
    System.out.println(zone);
    
    const params = {
     zoneId,
    };
    try {
     const res = await contextBasedRestrictionsService.getZone(params);
     console.log(JSON.stringify(res.result, null, 2));
    } catch (err) {
     console.warn(err);
    }
    
    get_zone_response = context_based_restrictions_service.get_zone(
     zone_id=zone_id
    )
    zone = get_zone_response.get_result()
    print(json.dumps(zone, indent=2))
    
    getZoneOptions := contextBasedRestrictionsService.NewGetZoneOptions(
      zoneID,
    )
     zone, response, err := contextBasedRestrictionsService.GetZone(getZoneOptions)
    if err != nil {
      panic(err)
    }
    b, _ := json.MarshalIndent(zone, "", "  ")
    fmt.Println(string(b))
    
  2. 使用 Replace zone(取代區域 )方法更新網路區域。 取代請求的 If-Match 標頭中需要 ETag 值。

    curl -X PUT --location --header "Authorization: Bearer {iam_token}" --header "Accept: application/json" --header "If-Match: {if_match}" --header "Content-Type: application/json" --data '{ "name": "new zone name", "description": "new zone description", "account_id": "12ab34cd56ef78ab90cd12ef34ab56cd", "addresses": [ { "type": "ipAddress", "value": "169.23.56.234" }, { "type": "ipRange", "value": "169.23.22.0-169.23.22.255" }, { "type": "vpc", "value": "crn:v1:bluemix:public:is:us-south:a/12ab34cd56ef78ab90cd12ef34ab56cd::vpc:r134-d98a1702-b39a-449a-86d4-ef8dbacf281e" } ] }' "{base_url}/v1/zones/{zone_id}"
    
    AddressIPAddress addressModel = new AddressIPAddress.Builder()
      .type("ipAddress")
      .value("169.23.56.234")
      .build();
    ReplaceZoneOptions replaceZoneOptions = new ReplaceZoneOptions.Builder()
      .zoneId("testString")
      .ifMatch("testString")
      .name("an example of zone")
      .accountId("12ab34cd56ef78ab90cd12ef34ab56cd")
      .description("this is an example of zone")
      .addresses(new java.util.ArrayList<Address>(java.util.Arrays.asList(addressModel)))
      .build();
    Response<OutZone> response = contextBasedRestrictionsService.replaceZone(replaceZoneOptions).execute();
    OutZone outZone = response.getResult();
    System.out.println(outZone);
    
    // Request models needed by this operation.
    // AddressIPAddress
    const addressModel = {
      type: 'ipAddress',
      value: '169.23.56.234',
    };
    const params = {
      zoneId: 'testString',
      ifMatch: 'testString',
      name: 'an example of zone',
      accountId: '12ab34cd56ef78ab90cd12ef34ab56cd',
      addresses: [addressModel],
      description: 'this is an example of zone',
    };
    contextBasedRestrictionsService.replaceZone(params)
      .then(res => {
        console.log(JSON.stringify(res.result, null, 2));
      })
      .catch(err => {
        console.warn(err)
      });
    
    address_model = {
      'type': 'ipAddress',
      'value': '169.23.56.234',
    }
    out_zone = context_based_restrictions_service.replace_zone(
      zone_id='testString',
      if_match='testString',
      name='an example of zone',
      account_id='12ab34cd56ef78ab90cd12ef34ab56cd',
      addresses=[address_model],
      description='this is an example of zone'
    ).get_result()
    print(json.dumps(out_zone, indent=2))
    
    addressModel := &contextbasedrestrictionsv1.AddressIPAddress{
      Type: core.StringPtr("ipAddress"),
      Value: core.StringPtr("169.23.56.234"),
    }
    replaceZoneOptions := contextBasedRestrictionsService.NewReplaceZoneOptions(
      "testString",
      "testString",
    )
    replaceZoneOptions.SetName("an example of zone")
    replaceZoneOptions.SetAccountID("12ab34cd56ef78ab90cd12ef34ab56cd")
    replaceZoneOptions.SetDescription("this is an example of updated zone")
    replaceZoneOptions.SetAddresses([]contextbasedrestrictionsv1.AddressIntf{addressModel})
    outZone, response, err := contextBasedRestrictionsService.ReplaceZone(replaceZoneOptions)
    if err != nil {
      panic(err)
    }
    b, _ := json.MarshalIndent(outZone, "", "  ")
    fmt.Println(string(b))
    

使用主控台移除規則

刪除規則會移除給定資源中基於上下文的限制,如果使用者擁有正確的權限,則允許任何上下文的請求。 完成下列步驟即可移除雲端資源上的規則:

  1. 在 IBM Cloud 主控台中,移至管理 > 基於上下文的限制,然後選取規則
  2. 按一下包含該規則的行中的 Actions 圖示 Actions 圖示,然後按一下 Remove

使用 CLI 移除規則

完成下列步驟即可移除雲端資源上的規則:

  1. 使用 基於上下文的限制規則 命令,擷取要刪除的規則 ID。 您可以透過指定屬性作為指令選項來縮小清單結果的範圍。
    ibmcloud cbr rules --serviceName "iam-identity"
    
  2. 使用 cbr rule-delete 指令刪除指定規則 ID 的規則。
    ibmcloud cbr rule-delete 30fd58c9b75f40e854b89c432318b4a2
    

使用 API 移除規則

完成下列步驟即可移除雲端資源上的規則:

  1. 使用 context-based-restrictions list rules 方法擷取要刪除的規則 ID。
    curl -X GET --location --header "Authorization: Bearer {iam_token}" --header "Accept: application/json" "{base_url}/v1/rules?account_id={account_id}"
    
    ListRulesOptions listRulesOptions = new ListRulesOptions.Builder()
    .accountId("testString")
    .build();
    
    Response<OutRulePage> response = contextBasedRestrictionsService.listRules(listRulesOptions).execute();
    OutRulePage outRulePage = response.getResult();
    
    System.out.println(outRulePage);
    
     const params = {
       accountId: 'testString',
     };
    
     contextBasedRestrictionsService.listRules(params)
       .then(res => {
         console.log(JSON.stringify(res.result, null, 2));
       })
       .catch(err => {
         console.warn(err)
       });
    
    out_rule_page = context_based_restrictions_service.list_rules(
       account_id='testString'
     ).get_result()
    
     print(json.dumps(out_rule_page, indent=2))
    
     listRulesOptions := contextBasedRestrictionsService.NewListRulesOptions(
       "testString",
     )
    
     ruleList, response, err := contextBasedRestrictionsService.ListRules(listRulesOptions)
     if err != nil {
       panic(err)
     }
     b, _ := json.MarshalIndent(ruleList, "", "  ")
     fmt.Println(string(b))
    
  2. 刪除指定規則 ID 的規則。
    curl -X DELETE --location --header "Authorization: Bearer {iam_token}" "{base_url}/v1/rules/{rule_id}"
    
    DeleteRuleOptions deleteRuleOptions = new DeleteRuleOptions.Builder()
      .ruleId("testString")
      .build();
    
    Response<Void> response = contextBasedRestrictionsService.deleteRule(deleteRuleOptions).execute();
    
     const params = {
       ruleId: 'testString',
     };
    
     contextBasedRestrictionsService.deleteRule(params)
       .then(res => {
         done();
       })
       .catch(err => {
         console.warn(err)
       });
    
     response = context_based_restrictions_service.delete_rule(
       rule_id='testString'
     )
    
     deleteRuleOptions := contextBasedRestrictionsService.NewDeleteRuleOptions(
       "testString",
     )
    
     response, err := contextBasedRestrictionsService.DeleteRule(deleteRuleOptions)
     if err != nil {
       panic(err)
     }
     if response.StatusCode != 204 {
       fmt.Printf("\nUnexpected response status code received from DeleteRule(): %d\n", response.StatusCode)
     }
    

使用主控台移除網路區域

移除網路區域會移除允許的網路位置集,從中建立存取請求。 如果將網路區域新增到規則中,您必須先從規則中移除區域。 完成下列步驟以移除網路區域:

  1. 在 IBM Cloud 主控台中,移至管理 > 基於上下文的限制,然後選擇網路區域
  2. 按一下包含網路區域的行中的 Actions 圖示 Actions 圖示,然後按一下 Remove

使用 CLI 移除網路區域

移除網路區域會移除允許的網路位置集,從中建立存取請求。 如果將網路區域新增到規則中,您必須先從規則中移除區域。 如需從規則中移除區域的詳細資訊,請參閱 更新基於上下文的限制。 然後,請完成下列步驟:

  1. 使用 contxt-based restrictions zones 指令擷取要刪除的網路區域的區域 ID。 您可以透過指定區域的名稱來縮小清單結果的範圍。
    ibmcloud cbr zones --name "Example zone"
    
  2. 使用 cbr zone-delete 指令刪除指定區域 ID 的網路區域。
    ibmcloud cbr zone-delete 65810ac762004f22ac19f8f8edf70a34
    

使用 API 移除網路區域

移除網路區域會移除允許的網路位置集,從中建立存取請求。 如果將網路區域新增到規則中,您必須先從規則中移除區域。 有關從規則中移除區域的詳細資訊,請參閱 更新基於上下文的限制。 然後,請完成下列步驟:

  1. 使用 Context-based restrictions list zones 方法擷取要刪除的規則 ID。
    curl -X GET --location --header "Authorization: Bearer {iam_token}" --header "Accept: application/json" "{base_url}/v1/zones?account_id={account_id}"
    
    ListZonesOptions listZonesOptions = new ListZonesOptions.Builder()
    .accountId("testString")
    .build();
    
    Response<OutZonePage> response = contextBasedRestrictionsService.listZones(listZonesOptions).execute();
    OutZonePage outZonePage = response.getResult();
    
    System.out.println(outZonePage);
    
     const params = {
       accountId: 'testString',
     };
    
     contextBasedRestrictionsService.listZones(params)
       .then(res => {
         console.log(JSON.stringify(res.result, null, 2));
       })
       .catch(err => {
         console.warn(err)
       });
    
     out_zone_page = context_based_restrictions_service.list_zones(
       account_id='testString'
     ).get_result()
    
     print(json.dumps(out_zone_page, indent=2))
    
     listZonesOptions := contextBasedRestrictionsService.NewListZonesOptions(
       "testString",
     )
    
     outZonePage, response, err := contextBasedRestrictionsService.ListZones(listZonesOptions)
     if err != nil {
       panic(err)
     }
     b, _ := json.MarshalIndent(outZonePage, "", "  ")
     fmt.Println(string(b))
    
  2. 刪除指定區域 ID 的網路區域。
    curl -X DELETE --location --header "Authorization: Bearer {iam_token}" "{base_url}/v1/zones/{zone_id}"
    
     DeleteZoneOptions deleteZoneOptions = new DeleteZoneOptions.Builder()
       .zoneId("testString")
       .build();
    
     Response<Void> response = contextBasedRestrictionsService.deleteZone(deleteZoneOptions).execute();
    
     const params = {
       zoneId: 'testString',
     };
    
     contextBasedRestrictionsService.deleteZone(params)
       .then(res => {
         done();
       })
       .catch(err => {
         console.warn(err)
       });
    
     response = context_based_restrictions_service.delete_zone(
       zone_id='testString'
     )
    
     deleteZoneOptions := contextBasedRestrictionsService.NewDeleteZoneOptions(
       "testString",
     )
    
     response, err := contextBasedRestrictionsService.DeleteZone(deleteZoneOptions)
     if err != nil {
       panic(err)
     }
     if response.StatusCode != 204 {
       fmt.Printf("\nUnexpected response status code received from DeleteZone(): %d\n", response.StatusCode)
     }
    

限制使用主控台管理規則和網路區域的能力

若要設定此規則,請以 基於情境的限制 服務為目標。 有關設定規則步驟的詳細資訊,請參閱建立 規則。 範圍涵蓋 所有資源的規則適用於服務管理的所有目前和未來資源。 如果要限制特定資源的操作,請將規則範圍設定為特定資源 > 資源類型。 若要完成任何規則或網路區域管理作業,使用者必須以 IAM 存取政策指派正確的角色,而且他們必須符合基於情境的限制規則。

限制使用 API 管理規則和網路區域的能力

以下範例以 JSON 格式顯示保護規則和網路區域管理作業的規則:

{
  "resources": [
    {
      "attributes": [
        {
          "name": "accountId",
          "value": "my-AccountID"
        },
        {
          "name": "serviceName",
          "value": "context-based-restrictions"
        }
      ]
    }
  ],
  "description": "",
  "contexts": [
    {
      "attributes": [
        {
          "name": "networkZoneId",
          "value": "my-zoneID"
        }
      ]
    }
  ],
  "enforcement_mode": "report"
}

僅指定 accountIdserviceName 資源屬性的規則適用於服務管理的所有目前和未來資源。 如果要限制特定資源的操作,請包含相應的 resourceType 資源屬性。 基於上下文限制服務的 resourceType 有效值為 rulezone

若要完成任何規則或網路區域管理作業,使用者必須以 IAM 存取政策指派正確的角色,而且他們必須符合基於情境的限制規則。