在 Cloud Healthcare API 中控制对 FHIR 资源的访问权限

本页面介绍了如何使用 FHIR 同意资源确定 Cloud Healthcare API 中 FHIR 存储区的数据访问权限。

如需配置强制执行意见征求的 FHIR 存储区,请完成以下步骤:

  1. 如果您还没有 FHIR 存储区,请创建一个。

  2. 设置以下 FHIR 存储区的 ConsentConfig 参数,以启用意见征求强制执行:

    • version:指定正在用于 FHIR 存储区的意见征求强制执行版本。此值只能由 CreateFhirStoreUpdateFhirStore 设置一次。设置后,您必须调用 ApplyConsentsApplyAdminConsents 来更改版本。

    • access_enforced:如果设置为 true,则在访问 FHIR 资源时,将根据使用方提供的意见征求指令来验证提供的意见征求标头。

    • consent_header_handling:如果设置为 PERMIT_EMPTY_SCOPE(默认值),则服务器允许不带(或为空)X-Consent-Scope 标头的请求。如果设置为 REQUIRED_ON_READaccess_enforced = true,则服务器会拒绝所有不含(或为空)X-Consent-Scope 标头的请求。

使用 ConsentConfig 设置新的 FHIR 存储区

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    --data "{
      'version': 'R4',
      'enableUpdateCreate': true,
      'consentConfig': {
        'version': 'V1',
        'accessEnforced': false
      }
    }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores?fhirStoreId=FHIR_STORE_ID"

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID",
  "version": "R4",
  "enableUpdateCreate": true,
  "consentConfig": {
    "version": "V1"
  }
}

如果您已有商店,请使用 UpdateFhirStore 将具有意见征求强制执行 versionConsentConfig 设置为 V1,并将 accessEnforced 设置为 false

curl -X PATCH \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    --data "{
      'consentConfig': {
        'version': 'V1',
        'accessEnforced': false
      }
    }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"

政策通过意见征求资源表示。如需了解资源字段的用途和用途,请参阅数据模型文档

以下是可为此特定示例创建的所有资源的示例。

以下示例展示了如何执行 [FHIR 软件包](/healthcare-api/docs/how-tos/fhir-bundles) 以填充以下资源:

  • 名为 Jeffrey Brown 的从业者资源
  • 名为 Darcy Smith 的患者资源
  • 显示 Darcy (LOINC718-7) 的血红蛋白测量结果的观察资源,这些数据是由 Happy Hospital 收集的
  • 显示 Darcy 的血糖测量结果的观察资源 (LOINC15074-8)。
  • Darcy 同意 Jeffrey Brown 使用 App/123 应用访问她由 Happy Hospital 收集的数据
  • Darcy 的同意书,允许 Jeffrey Brown 访问她的任何数据进行紧急治疗 (ETREAT)
  • 来自 Happy Hospital 的同意书,允许 Jeffrey Brown 在进行生物医学研究时访问所有数据 (BIORCH),只需申请 App/golden

cat > bundle.json << 'EOF'
{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [
    {
      "request": {"method": "PUT", "url": "Practitioner/12942879-f89f-41ae-aa80-0b911b649833"},
      "resource": {
        "active": true,
        "birthDate": "1970-05-23",
        "gender": "male",
        "id": "12942879-f89f-41ae-aa80-0b911b649833",
        "name": [{
            "family": "Brown",
            "given": ["Jeffrey"],
            "use": "official"
        }],
        "resourceType": "Practitioner"
      }
    },
    {
      "request": {"method": "PUT", "url": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
      "resource": {
        "active": true,
        "birthDate": "1990-01-01",
        "gender": "female",
        "id": "3c6aa096-c054-4c22-b2b4-1e4a4d203de2",
        "name": [{
            "family": "Smith",
            "given": ["Darcy"],
            "use": "official"
        }],
        "resourceType": "Patient"
      }
    },
    {
      "request": {"method": "PUT", "url": "Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"},
      "resource": {
        "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
        "meta": {"source": "http://example.com/HappyHospital"},
        "code": {
          "coding": [{
            "code": "718-7",
            "system": "http://loinc.org",
            "display": "Hemoglobin [Mass/volume] in Blood"
          }]
        },
        "effectivePeriod": {"start": "2021-12-10T05:30:10+01:00"},
        "issued": "2021-12-10T13:30:10+01:00",
        "resourceType": "Observation",
        "status": "final",
        "subject": {"reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
        "valueQuantity": {
          "code": "g/dL",
          "system": "http://unitsofmeasure.org",
          "unit": "g/dl",
          "value": 7.2
        }
      }
    },
    {
      "request": {"method": "PUT", "url": "Observation/68583624-9921-4158-8754-2a306c689abd"},
      "resource": {
        "id": "68583624-9921-4158-8754-2a306c689abd",
        "code": {
          "coding": [{
            "code": "15074-8",
            "system": "http://loinc.org",
            "display": "Glucose [Moles/volume] in Blood"
          }]
        },
        "effectivePeriod": {"start": "2021-12-01T05:30:10+01:00"},
        "issued": "2021-12-01T13:30:10+01:00",
        "resourceType": "Observation",
        "status": "final",
        "subject": {"reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
        "valueQuantity": {
          "code": "mmol/L",
          "system": "http://unitsofmeasure.org",
          "unit": "mmol/l",
          "value": 6.3
        }
      }
    },
    {
      "request": {"method": "PUT", "url": "Consent/10998b60-a252-405f-aa47-0702554ddc8e"},
      "resource": {
        "category": [{
          "coding": [{
            "code": "59284-0",
            "system": "http://terminology.hl7.org/CodeSystem/consentcategorycodes"
          }]
        }],
        "id": "10998b60-a252-405f-aa47-0702554ddc8e",
        "patient": {"reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
        "policyRule": {
          "coding": [{
            "code": "OPTIN",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
          }]
        },
        "provision": {
          "actor": [
            {
              "reference": {"reference": "Practitioner/12942879-f89f-41ae-aa80-0b911b649833"},
              "role": {
                "coding": [{
                  "code": "GRANTEE",
                  "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode"
                }]
              }
            }
          ],
          "extension": [
            {
              "url": "https://g.co/fhir/medicalrecords/Environment",
              "valueCodeableConcept": {
                "coding": [{
                  "code": "123",
                  "system": "App"
                }]
              }
            },
            {
              "url": "https://g.co/fhir/medicalrecords/DataSource",
              "valueUri": "http://example.com/HappyHospital"
            }
          ],
          "type": "permit"
        },
        "resourceType": "Consent",
        "scope": {
          "coding": [{
            "code": "patient-privacy",
            "system": "http://terminology.hl7.org/CodeSystem/consentscope"
          }]
        },
        "status": "active"
      }
    },
    {
      "request": {"method": "PUT", "url": "Consent/73c54e8d-2789-403b-9dee-13085c5d5e34"},
      "resource": {
        "category": [{
          "coding": [{
            "code": "59284-0",
            "system": "http://terminology.hl7.org/CodeSystem/consentcategorycodes"
          }]
        }],
        "id": "73c54e8d-2789-403b-9dee-13085c5d5e34",
        "patient": {"reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"},
        "policyRule": {
          "coding": [{
            "code": "OPTIN",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
          }]
        },
        "provision": {
          "actor": [
            {
              "reference": {"reference": "Practitioner/12942879-f89f-41ae-aa80-0b911b649833"},
              "role": {
                "coding": [{
                  "code": "GRANTEE",
                  "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode"
                }]
              }
            }
          ],
          "purpose": [{
            "code": "ETREAT",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason"
          }],
          "type": "permit"
        },
        "resourceType": "Consent",
        "scope": {
          "coding": [{
            "code": "patient-privacy",
            "system": "http://terminology.hl7.org/CodeSystem/consentscope"
          }]
        },
        "status": "active"
      }
    },
    {
      "request": {"method": "PUT", "url": "Consent/5c8e3f8a-9fd5-480d-a08e-f29b89feccde"},
      "resource": {
        "category": [{
          "coding": [{
            "code": "57017-6",
            "system": "http://loinc.org"
          }]
        }],
        "id": "5c8e3f8a-9fd5-480d-a08e-f29b89feccde",
        "patient": {},
        "extension": [{
          "url": "https://g.co/fhir/medicalrecords/ConsentAdminPolicy"
        }],
        "policyRule": {
          "coding": [{
            "code": "OPTIN",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode"
          }]
        },
        "provision": {
          "actor": [
            {
              "reference": {"reference": "Practitioner/12942879-f89f-41ae-aa80-0b911b649833"},
              "role": {
                "coding": [{
                  "code": "GRANTEE",
                  "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode"
                }]
              }
            }
          ],
          "purpose": [{
            "code": "BIORCH",
            "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason"
          }],
          "extension": [
            {
              "url": "https://g.co/fhir/medicalrecords/Environment",
              "valueCodeableConcept": {
                "coding": [{
                  "code": "golden",
                  "system": "App"
                }]
              }
            }
          ],
          "type": "permit"
        },
        "resourceType": "Consent",
        "scope": {},
        "status": "active"
      }
    }
  ]
}
EOF
curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/fhir+json; charset=utf-8" \
    --data @bundle.json \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir"

您应该收到类似以下内容的 JSON 响应:

{
  "entry": [
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/12942879-f89f-41ae-aa80-0b911b649833/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/68583624-9921-4158-8754-2a306c689abd/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/10998b60-a252-405f-aa47-0702554ddc8e/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/73c54e8d-2789-403b-9dee-13085c5d5e34/_history/VERSION_ID",
        "status": "201 Created"
      }
    },
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/5c8e3f8a-9fd5-480d-a08e-f29b89feccde/_history/VERSION_ID",
        "status": "201 Created"
      }
    }
  ],
  "resourceType": "Bundle",
  "type": "transaction-response"
}

以下是 R4 意见征求资源的更多示例,演示了如何表示复杂的政策。

{
  "resourceType": "Consent",
  "id": "patient-consent-example",
  "patient": {
    "reference": "Patient/f001"
  },
  "category": [
    {
      "coding": [
        {
          "system": "http://loinc.org",
          "code": "59284-0"
        }
      ]
    }
  ],
  "scope": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/consentscope",
        "code": "patient-privacy"
      }
    ]
  },
  "policyRule": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "OPTIN"
      }
    ]
  },
  "status": "active",
  "provision": {
    "type": "permit",
    "actor": [
      {
        "reference": {
          "reference": "Practitioner/f002"
        },
        "role": {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
              "code": "GRANTEE"
            }
          ]
        }
      }
    ],
    "purpose": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
        "code": "TREAT"
      }
    ],
    "class": [
      {
        "system": "http://hl7.org/fhir/resource-types",
        "code": "Encounter"
      }
    ],
    "data": [
      {
        "meaning": "instance",
        "reference": {
          "reference": "Encounter/e001"
        }
      }
    ],
    "extension": [
      {
        "url": "https://g.co/fhir/medicalrecords/Environment",
        "valueCodeableConcept": {
          "coding": [
            {
              "system": "iso3166-1",
              "code": "CA"
            }
          ]
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "valueCoding": {
          "system": "http://terminology.hl7.org/CodeSystem/common-tags",
          "code": "actionable"
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "extension": [
          {
            "url": "https://g.co/fhir/medicalrecords/DataTag",
            "valueCoding": {
              "system": "http://example.com/custom-tags",
              "code": "archived"
            }
          },
          {
            "url": "https://g.co/fhir/medicalrecords/DataTag",
            "valueCoding": {
              "system": "http://example.com/custom-tags",
              "code": "insensitive"
            }
          }
        ]
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataSource",
        "valueUri": "http://somesystem.example.org/foo"
      }
    ],
    "systemLabel": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
        "code": "R"
      },
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "PSY"
      }
    ]
  }
}

上述示例代表了患者意见征求资源,其中患者 f001 向从业者 f002 授予了权限,以提供 TREAT 表示的常规治疗。从业者来自地理位置iso3166-1/CA。如果数据满足以下所有条件,则此 Consent 资源允许从业者访问患者数据:

  • 它是一种 Encounter 类型,ID 为 Encounter/e001
  • 它来自 http://somesystem.example.org/foo 源代码。
  • 该代码至少满足以下其中一个条件:
    • 具有标记(system = http://terminology.hl7.org/CodeSystem/common-tagscode = actionable
    • 同时包含这两个标记(system = http://example.com/custom-tagscode = archived)且system = http://example.com/custom-tagscode = insensitive
  • 它至少具有以下某一安全标签
    • system = http://terminology.hl7.org/CodeSystem/v3-ConfidentialitycodeRNMLU 中的一个。
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCodecode = PSY

{
  "resourceType": "Consent",
  "id": "admin-policy-example",
  "patient": {},
  "extension": [{
    "url": "https://g.co/fhir/medicalrecords/ConsentAdminPolicy"
  }],
  "category": [
    {
      "coding": [
        {
          "system": "http://loinc.org",
          "code": "57017-6"
        }
      ]
    }
  ],
  "scope": {},
  "policyRule": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "OPTIN"
      }
    ]
  },
  "status": "active",
  "provision": {
    "type": "permit",
    "actor": [
      {
        "reference": {
          "reference": "Practitioner/f002"
        },
        "role": {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
              "code": "GRANTEE"
            }
          ]
        }
      }
    ],
    "purpose": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
        "code": "TREAT"
      }
    ],
    "class": [
      {
        "system": "http://hl7.org/fhir/resource-types",
        "code": "Encounter"
      }
    ],
    "data": [
      {
        "meaning": "instance",
        "reference": {
          "reference": "Encounter/e001"
        }
      }
    ],
    "extension": [
      {
        "url": "https://g.co/fhir/medicalrecords/Environment",
        "valueCodeableConcept": {
          "coding": [
            {
              "system": "iso3166-1",
              "code": "CA"
            }
          ]
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "valueCoding": {
          "system": "http://terminology.hl7.org/CodeSystem/common-tags",
          "code": "actionable"
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "extension": [
          {
            "url": "https://g.co/fhir/medicalrecords/DataTag",
            "valueCoding": {
              "system": "http://example.com/custom-tags",
              "code": "archived"
            }
          },
          {
            "url": "https://g.co/fhir/medicalrecords/DataTag",
            "valueCoding": {
              "system": "http://example.com/custom-tags",
              "code": "insensitive"
            }
          }
        ]
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataSource",
        "valueUri": "http://somesystem.example.org/foo"
      }
    ],
    "systemLabel": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
        "code": "R"
      },
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "PSY"
      }
    ]
  }
}

上面的示例表示管理员政策 Consent 资源向从业者 f002 授予权限,用于提供常规服务(以 TREAT 表示)。从业者来自地理定位 iso3166-1/CA。如果数据满足以下所有条件,则此 Consent 资源允许从业者访问患者数据:

  • 它是一种 Encounter 类型,ID 为 Encounter/e001
  • 它来自 http://somesystem.example.org/foo 源代码。
  • 该代码至少满足以下其中一个条件:
    • 具有标记(system = http://terminology.hl7.org/CodeSystem/common-tagscode = actionable
    • 同时包含这两个标记(system = http://example.com/custom-tagscode = archived)且system = http://example.com/custom-tagscode = insensitive
  • 它至少具有以下某一安全标签
    • system = http://terminology.hl7.org/CodeSystem/v3-ConfidentialitycodeRNMLU 中的一个。
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCodecode = PSY

{
  "resourceType": "Consent",
  "id": "admin-cascading-policy-example",
  "patient": {},
  "extension": [
    { "url": "https://g.co/fhir/medicalrecords/ConsentAdminPolicy" },
    { "url": "https://g.co/fhir/medicalrecords/CascadingPolicy" }
  ],
  "category": [
    {
      "coding": [
        {
          "system": "http://loinc.org",
          "code": "57017-6"
        }
      ]
    }
  ],
  "scope": {},
  "policyRule": {
    "coding": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "OPTIN"
      }
    ]
  },
  "status": "active",
  "provision": {
    "type": "permit",
    "actor": [
      {
        "reference": {
          "reference": "Practitioner/f002"
        },
        "role": {
          "coding": [
            {
              "system": "http://terminology.hl7.org/CodeSystem/v3-RoleCode",
              "code": "GRANTEE"
            }
          ]
        }
      }
    ],
    "purpose": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActReason",
        "code": "TREAT"
      }
    ],
    "class": [
      {
        "system": "http://hl7.org/fhir/resource-types",
        "code": "Patient"
      }
    ],
    "extension": [
      {
        "url": "https://g.co/fhir/medicalrecords/Environment",
        "valueCodeableConcept": {
          "coding": [
            {
              "system": "iso3166-1",
              "code": "CA"
            }
          ]
        }
      },
      {
        "url": "https://g.co/fhir/medicalrecords/DataTag",
        "valueCoding": {
          "system": "http://terminology.hl7.org/CodeSystem/common-tags",
          "code": "employee"
        }
      }
    ]
  }
}

上面的示例表示管理员级联政策意见征求资源,该资源向从业者 f002 授予权限,用于提供常规服务(以 TREAT 表示)。从业者来自地理定位 iso3166-1/CA。此意见征求资源允许从业者访问带有 employee 标记患者的房间数据。所有资源条件仅适用于房间基本资源(即患者资源),因为它控制着哪些资源进行级联。

强制执行患者同意书或管理政策

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    --data "{'validateOnly': false}" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

响应包含操作名称。如需跟踪操作的状态,您可以使用 [操作 `get` 方法](/healthcare-api/docs/reference/rest/v1/projects.locations.datasets.operations/get):

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

操作完成后,服务器会以 JSON 格式返回包含操作状态的响应:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1beta1.fhir.FhirStoreService.ApplyConsents",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/query/CLOUD_LOGGING_URL",
    "counter": {
      "success": "2",
      "secondarySuccess": "5"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.fhir.ApplyConsentsResponse",
    "consentApplySuccess": "2",
    "affectedResources": "5"
  }
}

此响应表明服务器成功处理了 2 份同意声明,并更新了 5 项资源的同意访问数据(1 名患者、2 份同意声明和 2 项观察数据)。

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    --data "{
      'validateOnly': false,
      'newConsentsList': {
        'names': ['projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/5c8e3f8a-9fd5-480d-a08e-f29b89feccde/_history/VERSION_ID']
      }
    }" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyAdminConsents"

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

响应包含操作名称。如需跟踪操作的状态,您可以使用 [操作 `get` 方法](/healthcare-api/docs/reference/rest/v1/projects.locations.datasets.operations/get):

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

操作完成后,服务器会以 JSON 格式返回包含操作状态的响应:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1beta1.fhir.FhirStoreService.ApplyAdminConsents",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/query/CLOUD_LOGGING_URL",
    "counter": {
      "success": "1",
      "secondarySuccess": "7"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1beta1.fhir.ApplyAdminConsentsResponse",
    "consentApplySuccess": "1",
    "affectedResources": "7"
  }
}

此响应表明服务器成功处理了 1 项管理员政策并更新了 7 项资源的同意访问(1 名从业者、1 名患者、2 项观察、2 份患者同意书和 1 项管理员政策)。

只有在调用并成功完成 ApplyConsents(针对患者同意)或 ApplyAdminConsents(针对管理员政策和管理级联政策)之后,对存储在 FHIR 存储区中的同意声明才会生效。如果您在运行 ApplyConsentsApplyAdminConsents 后添加、修改或移除用户意见,则必须再次运行该程序,才能将这些意见纳入到执行模型中。

FHIR 资源是异步编入索引的,因此 ApplyConsentsApplyAdminConsents 完成时间与强制执行模型在搜索结果中反映出来之间可能会略有延迟。只有搜索请求会出现这种延迟。

如果这是您第一次为 FHIR 存储区设置意见征求强制执行,请等待 ApplyConsentsApplyAdminConsents 长时间运行的操作完成,然后再发出知晓用户意见的请求。

如需对一部分患者调用 ApplyConsents,您可以使用以下过滤器:

  • PatientScope:针对多达 10,000 位患者的 ID 列表运行 ApplyConsents

  • TimeRange:针对特定时间范围内更新其同意资源的患者资源 ID 列表运行 ApplyConsent

如需调用 ApplyAdminConsents:您需要提供要应用的所有政策的完整列表(而非增量列表)。因此,空列表会使存储区的所有管理政策的强制执行无效。如果 FHIR 存储区进行版本控制,则每个政策都必须是资源版本名称,否则必须是资源名称。

您可以使用 operations.get 检索该操作的 ProgressCounter。完成后,将会有一个 ApplyConsentsResponse 包含在 Operation.response 中。下表介绍了 ProgressCounterApplyConsentsResponseApplyAdminConsentsResponse 中的计数器。

ProgressCounter ApplyConsentsResponseApplyAdminConsentsResponse 说明
success consentApplySuccess 操作成功处理的 Consent 资源的数量。
failure consentApplyFailure 不受支持或无效的 Consent 资源的数量。您可以在 Cloud Logging 中查看错误日志;当 validateOnlyfalse 时,使用 CheckConsentEnforcementStatusCheckPatientConsentEnforcementStatus 检查意见征求强制执行状态,以检索错误详情。
secondarySuccess affectedResources validateOnlyfalse 时,它表示由于意见征求更改的影响而成功重新编入索引的 FHIR 资源数量。
secondaryFailure failedResources validateOnlyfalse 时,它表示可以更改同意情况但未能重新编入索引的 FHIR 资源数量。这可能会影响在提供用户意见的情况下进行搜索,但不会影响其他方法。如需查看错误详情,您可以在 Cloud Logging 中查看错误日志

处理 FHIR 同意资源后,您可以使用以下 API 检查单个同意或患者所有同意的强制执行状态:

对于管理政策,CheckConsentEnforcementStatus 只能用于检查单项意见征求管理政策的强制执行状态。或者,您也可以使用 fhirStores.get 查看应用于商店的所有有效管理员政策。

consent-enforcement-status 可以具有以下任一值:

  • OFF:表示新的意见征求资源(其中从未处理过 Consent 资源)的默认强制执行状态。

  • ENFORCEABLE:同意资源已成功处理的状态。

  • INACTIVE:同意资源被忽略的非活跃状态。

  • UNSUPPORTED:可能符合 FHIR 规范但无法执行的同意资源状态。这是由于在当前功能支持级别下 FHIR 同意强制执行的实施有限。

  • ENFORCEMENT_LIMIT_EXCEEDED:FHIR 同意资源格式和资源支持级别没有错误但以下一个或多个条件为 true 时的状态:

    • 患者拥有大量同意资源。

    • 所有活跃同意中的同意指令大小都大于 FHIR 服务器强制执行同意指令的最大大小。

针对传入请求启用访问权限

传入请求的访问权限检查通过存储区配置启用:consentConfig.accessEnforced。以下示例演示了如何启用此 API。

curl -X PATCH \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json" \
    --data "{
      'consentConfig': {
        'accessEnforced': true
      }
    }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig.accessEnforced"

您应该收到类似以下内容的 JSON 响应:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID",
  "version": "R4",
  "consentConfig": {
    "version": "V1",
    "accessEnforced": true
  }
}

Cloud Healthcare API 支持在给定的 FHIR 存储区中搜索使用 actorpurposeenvironment 作为查询参数的 FHIR 资源。响应仅包含已征得用户同意的资源。

  1. 使用可信应用 App/123 的从业者 Jeffrey Brown(由 Practitioner/12942879-f89f-41ae-aa80-0b911b649833 标识)使用 status=final 搜索所有观察结果。
  2. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?status=final"

    您应该收到类似以下内容的 JSON 响应:

    {
      "entry": [
        {
          "fullUrl": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION_ID/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa",
          "resource": {
            "code": {
              "coding": [
                {
                  "code": "718-7",
                  "display": "Hemoglobin [Mass/volume] in Blood",
                  "system": "http://loinc.org"
                }
              ]
            },
            "effectivePeriod": {
              "start": "2021-12-10T05:30:10+01:00"
            },
            "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
            "issued": "2021-12-10T13:30:10+01:00",
            "meta": {
              "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
              "source": "http://example.com/HappyHospital",
              "versionId": "VERSION_ID"
            },
            "resourceType": "Observation",
            "status": "final",
            "subject": {
              "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
            },
            "valueQuantity": {
              "code": "g/dL",
              "system": "http://unitsofmeasure.org",
              "unit": "g/dl",
              "value": 7.2
            }
          },
          "search": {
            "mode": "match"
          }
        }
      ],
      "link": [
        {
          "relation": "search",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final"
        }
      ],
      "resourceType": "Bundle",
      "total": 1,
      "type": "searchset"
    }
    
  3. 使用应用 App/123 的从业者 Jeffrey Brown(由 Practitioner/12942879-f89f-41ae-aa80-0b911b649833 标识)搜索患者 Darcy 的所有观察结果。
  4. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?subject:Patient.name=Darcy"

    您应该收到类似以下内容的 JSON 响应:

    {
      "link": [
        {
          "relation": "search",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject%3APatient.name=Darcy"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject%3APatient.name=Darcy"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject%3APatient.name=Darcy"
        }
      ],
      "resourceType": "Bundle",
      "total": 0,
      "type": "searchset"
    }
    

    上述查询为链式搜索。由于意见征求场景 actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123 被拒绝访问患者 Darcy 资源(由 Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2 标识),因此 FHIR 服务器不会从患者返回任何观察结果,就像病人不存在一样。

  5. 使用应用 App/123 的从业者 Jeffrey Brown(由 Practitioner/12942879-f89f-41ae-aa80-0b911b649833 标识)会搜索患者 Darcy 的所有观察结果,用于紧急治疗。
  6. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 purp/v3/ETREAT env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?subject:Patient.name=Darcy"

    您应该收到类似以下内容的 JSON 响应:

    {
      "entry": [
        {
          "fullUrl": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/68583624-9921-4158-8754-2a306c689abd",
          "resource": {
            "code": {
              "coding": [
                {
                  "code": "15074-8",
                  "display": "Glucose [Moles/volume] in Blood",
                  "system": "http://loinc.org"
                }
              ]
            },
            "effectivePeriod": {
              "start": "2021-12-01T05:30:10+01:00"
            },
            "id": "68583624-9921-4158-8754-2a306c689abd",
            "issued": "2021-12-01T13:30:10+01:00",
            "meta": {
              "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
              "versionId": "VERSION_ID"
            },
            "resourceType": "Observation",
            "status": "final",
            "subject": {
              "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
            },
            "valueQuantity": {
              "code": "mmol/L",
              "system": "http://unitsofmeasure.org",
              "unit": "mmol/l",
              "value": 6.3
            }
          },
          "search": {
            "mode": "match"
          }
        },
        {
          "fullUrl": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa",
          "resource": {
            "code": {
              "coding": [
                {
                  "code": "718-7",
                  "display": "Hemoglobin [Mass/volume] in Blood",
                  "system": "http://loinc.org"
                }
              ]
            },
            "effectivePeriod": {
              "start": "2021-12-10T05:30:10+01:00"
            },
            "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
            "issued": "2021-12-10T13:30:10+01:00",
            "meta": {
              "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
              "source": "http://example.com/HappyHospital",
              "versionId": "VERSION_ID"
            },
            "resourceType": "Observation",
            "status": "final",
            "subject": {
              "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
            },
            "valueQuantity": {
              "code": "g/dL",
              "system": "http://unitsofmeasure.org",
              "unit": "g/dl",
              "value": 7.2
            }
          },
          "search": {
            "mode": "match"
          }
        }
      ],
      "link": [
        {
          "relation": "search",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject:Patient.name=Darcy"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject:Patient.name=Darcy"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject:Patient.name=Darcy"
        }
      ],
      "resourceType": "Bundle",
      "total": 2,
      "type": "searchset"
    }
    
  7. 从业者 Jeffrey Brown(由 Practitioner/12942879-f89f-41ae-aa80-0b911b649833 标识)使用 status=final 搜索观察结果,有两个目的:治疗研究
  8. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 purp/v3/TREAT purp/v3/HRESCH" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?status=final"

    您应该收到类似以下内容的 JSON 响应:

    {
      "issue": [
        {
          "code": "security",
          "details": {
            "text": "permission_denied"
          },
          "diagnostics": "the maximum number of allowed consent purpose scopes is 1, got 2",
          "severity": "error"
        }
      ],
      "resourceType": "OperationOutcome"
    }
    

    在这种情况下,从业者 Jeffrey Brown 应从请求的“X-Consent-Scope”中移除不必要的用途。

  9. 医院 IT 管理员使用 bypass 搜索医院的所有实操人员。
  10. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: bypass actor/Admin/ef0592c9-6724-467e-878d-f879e537cd15 env/net/HappyNet" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner?"

    由于提供了 bypass,因此跳过了用户意见征求检查。您应该会收到类似如下所示的 JSON 响应:

    {
      "entry": [
        {
          "fullUrl": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/12942879-f89f-41ae-aa80-0b911b649833",
          "resource": {
            "active": true,
            "birthDate": "1970-05-23",
            "gender": "male",
            "id": "12942879-f89f-41ae-aa80-0b911b649833",
            "meta": {
              "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
              "versionId": "VERSION_ID"
            },
            "name": [
              {
                "family": "Brown",
                "given": [
                  "Jeffrey"
                ],
                "use": "official"
              }
            ],
            "resourceType": "Practitioner"
          },
          "search": {
            "mode": "match"
          }
        }
      ],
      "link": [
        {
          "relation": "search",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?"
        }
      ],
      "resourceType": "Bundle",
      "total": 1,
      "type": "searchset"
    }
    

Cloud Healthcare API 支持使用 actorpurposeenvironment 作为查询参数获取给定 FHIR 存储区中的 FHIR 资源。响应仅包含已征得用户同意的资源。

  1. 医护人员 Jeffrey Brown(由 Practitioner/12942879-f89f-41ae-aa80-0b911b649833 标识)使用应用 App/123 读取患者的血红蛋白测量值(在此示例中为 Observation/7473784b-46a8-470c-b9a6-fe38a01025aa)。
  2. curl -X GET \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"

    由于请求者已表示同意,因此响应是观察资源的内容。

    {
      "code": {
        "coding": [
          {
            "code": "718-7",
            "display": "Hemoglobin [Mass/volume] in Blood",
            "system": "http://loinc.org"
          }
        ]
      },
      "effectivePeriod": {
        "start": "2021-12-10T05:30:10+01:00"
      },
      "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
      "issued": "2021-12-10T13:30:10+01:00",
      "meta": {
        "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
        "source": "http://example.com/HappyHospital",
        "versionId": "VERSION_ID"
      },
      "resourceType": "Observation",
      "status": "final",
      "subject": {
        "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
      },
      "valueQuantity": {
        "code": "g/dL",
        "system": "http://unitsofmeasure.org",
        "unit": "g/dl",
        "value": 7.2
      }
    }
    
  3. 使用未知应用 App/unknown 的实操人员 Jeffrey Brown(由 Practitioner/12942879-f89f-41ae-aa80-0b911b649833 标识)读取患者的血红蛋白测量结果(在此示例中为 Observation/7473784b-46a8-470c-b9a6-fe38a01025aa)。
  4. curl -X GET \
      -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
      -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/unknown" \
      "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"

    由于未经患者同意,请求者(“应用/未知”)的边界访问权限(“应用/未知”),因此请求会被拒绝。

    {
      "issue": [
        {
          "code": "security",
          "details": {
            "text": "permission_denied"
          },
          "diagnostics": "Consent access denied or the resource being accessed does not exist",
          "severity": "error"
        }
      ],
      "resourceType": "OperationOutcome"
    }
    
  5. 从业者 Jeffrey Brown(由 Practitioner/12942879-f89f-41ae-aa80-0b911b649833 标识)使用应用 App/golden 进行生物医学研究,读取了 Darcy 的出生日期(在本例中为 Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2)。
  6. curl -X GET \
      -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
      -H "X-Consent-Scope: actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 purp/v3/BIORCH env/App/golden" \
      "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"

    由于请求者已表示同意,因此响应是患者资源的内容。

    {
      "active": true,
      "birthDate": "1990-01-01",
      "gender": "female",
      "id": "3c6aa096-c054-4c22-b2b4-1e4a4d203de2",
      "meta": {
        "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
        "versionId": "VERSION_ID"
      },
      "name": [
        {
          "family": "Smith",
          "given": [
            "Darcy"
          ],
          "use": "official"
        }
      ],
      "resourceType": "Patient"
    }
    
  7. 医护人员 Jeffrey Brown(由 Practitioner/12942879-f89f-41ae-aa80-0b911b649833 标识)使用“紧急访问权限”协议请求在未经授权的情况下访问患者的记录。 (在此示例中为 Observation/7473784b-46a8-470c-b9a6-fe38a01025aa)。
  8. curl -X GET \
      -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
      -H "X-Consent-Scope: btg actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833" \
      "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"

    由于意见征求的授权方法是 btg,因此服务器会跳过用户意见检查。响应是观察资源的内容。

    {
      "code": {
        "coding": [
          {
            "code": "718-7",
            "display": "Hemoglobin [Mass/volume] in Blood",
            "system": "http://loinc.org"
          }
        ]
      },
      "effectivePeriod": {
        "start": "2021-12-10T05:30:10+01:00"
      },
      "id": "7473784b-46a8-470c-b9a6-fe38a01025aa",
      "issued": "2021-12-10T13:30:10+01:00",
      "meta": {
        "lastUpdated": "2022-09-01T17:31:40.423469+00:00",
        "source": "http://example.com/HappyHospital",
        "versionId": "VERSION_ID"
      },
      "resourceType": "Observation",
      "status": "final",
      "subject": {
        "reference": "Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"
      },
      "valueQuantity": {
        "code": "g/dL",
        "system": "http://unitsofmeasure.org",
        "unit": "g/dl",
        "value": 7.2
      }
    }
    

以下部分介绍了 Cloud Healthcare API 中支持的同意强制执行方法,以及如何在发出同意感知请求时强制执行资源访问。

发出请求时,您的授权服务器负责生成具有相关同意范围的访问令牌。

设置 HTTP 标头

同意范围使用 X-Consent-Scope HTTP 标头传递给 Cloud Healthcare API。Cloud Healthcare API 使用此标头对 FHIR 存储区中的数据实施基于同意的访问权限控制。

FHIR 请求可支持有限数量的同意条目范围。给定的 FHIR 请求中最多可以包含三个 actor 条目、一个 purp 条目和一个 env 条目。

对于特殊范围,FHIR 请求可以支持 btgbypass 中的一个。

为可信应用设置 HTTP 标头

只有在使用客户控制的授权服务器时,才需要按照本部分执行操作。在此实例中,您还必须使用 SMARTproxy 或类似代理。

某些可信应用可以使用指定的 HTTP 标头中的同意范围直接调用 Cloud Healthcare API。这样一来,无需 SMARTproxy 或其他代理在外部授权服务器与 Google Cloud 之间进行转换,即可强制执行直接意见征求。

例如,您的应用可能注册了部分范围,例如一个应用 environment 范围,或者应用可能会显示选择微件来设置一些范围条目,例如访问者的 purpose

可信用户或可信应用也可以使用 btgbypass 范围条目,它们需要接受后审核审核。

Cloud Healthcare API 根据输入同意范围提供对 FHIR 同意强制执行的内置支持。FHIR 存储区管理员负责在 Cloud Healthcare API 之外创建和配置授予同意范围的授权服务器。

访问令牌示例

以下示例展示了用 base64 编码的访问令牌:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJjb25zZW50LnRva2VuLm9yZyIsImlhdCI6MTYxMjg4NDA4NSwiZXhwIjoxNjQ0NDIwMDg1LCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJkb2N0b3IuZ2FicmllbGFAZXhhbXBsZS5jb20iLCJzY29wZSI6Im9pZGMgYWN0b3IvUHJhY3RpdGlvbmVyLzEyMyBhY3Rvci9Hcm91cC85OTkgcHVycC92My9UUkVBVCBlbnYvQXBwL2FiYyJ9.fC7ljkVUUx8fwUOrJuONcrqA-WKC-k_Bclzlgds0Cq6H_gEe3nUjPlSOCTQsIdYB

对访问令牌进行解码后,您可以看到它包含以下载荷:

{
  "iss": "consent.token.org",
  "iat": 1612884085,
  "exp": 1644420085,
  "aud": "www.example.com",
  "sub": "doctor.gabriela@example.com",
  "scope": "oidc actor/Practitioner/123 actor/Group/999 purp/v3/TREAT env/App/abc"
}

配置 SMARTProxy

SMARTProxy 是 Google 的开源代理,可提供以下功能:

  • 允许 Cloud Healthcare API FHIR 服务器接受并验证同意感知访问令牌。

  • 允许 Cloud Healthcare API 中的 FHIR 实现在 Cloud Healthcare API 管理和权限模型中包含意见征求感知访问令牌。

  • 在 FHIR 支持上也支持 SMART 的令牌功能。

当您发出通过 SMARTProxy 从 Cloud Healthcare API 检索数据的请求时,会发生以下情况:

  1. SMARTProxy 接受包含同意感知令牌的客户端的请求。

  2. SMARTProxy 通过您拥有的 JWT 授权服务器验证同意感知令牌。

  3. SMARTProxy 从意见征求感知令牌中读取范围,并通过 HTTP 标头将它们传递给 Cloud Healthcare API。

  4. Cloud Healthcare API 会接收标头并对其进行验证,以对请求强制执行同意指令。随后,Cloud Healthcare API 通过 SMARTProxy 向客户端返回响应。

配置 Google Cloud 服务账号

一个代理只能有一个 Google Cloud 服务账号。如果多个客户端使用相同的代理,则这些客户端也将使用相同的服务账号。与多个客户端共享服务账号时,请务必小心,原因如下:

例如,如果您使用您的 Google 账号直接调用 Cloud Healthcare API 以进行身份验证,则 Cloud Audit Logs 会将您的电子邮件地址记录为主电子邮件地址。使用代理调用 Cloud Healthcare API 时,代理使用自己的服务帐号,主帐号电子邮件地址是服务帐号的电子邮件地址,原始帐号未定义。

审核日志

当有访问请求或资源的访问强制执行发生变化时,系统会生成审核日志。

访问审核日志

如果在 FHIR 存储区中启用审核日志,则 Cloud Logging 提供的审核日志中会包含 consentMode 元数据字段。consentMode 可以具有以下某个值:

  • off:FHIR 存储区配置将 consentConfig.accessEnforced 设置为 false,并且不允许同意感知请求。

  • emptyScope:FHIR 存储区的 consentConfig.accessEnforced 设置为 true,但未包含同意范围标头。因此,同意未强制执行。

  • enforced:FHIR 存储区将 consentConfig.accessEnforced 设置为 true,并且存在同意范围标头。因此,我们根据关于患者房间(STU3R4)的资源请求评估并强制执行了同意声明。

  • btg:FHIR 请求在意见征求范围标头中提供了 btg。因此,跳过了用户意见征求检查。此请求仅用于紧急情况,并且仅用于审核后审核。

  • bypass:FHIR 请求在意见征求范围标头中仅提供了 bypass。因此,跳过了用户意见征求检查。此请求旨在供可信工作流(例如管理员或可信应用,而非最终用户)使用,因此此审核日志与用于数据治理检查的 btg 不同。

或者,您也可以将 access_determination_log_config 设置为 VERBOSE,以记录有关请求被批准或拒绝的原因。

访问权限强制执行更改审核日志

当分区基本资源发生更改(例如,移除患者的 employee 标记)时:对已更改的资源及其分区的访问权限控制可能会因管理员级联政策而发生变化。这会触发对其所有分区资源进行重新编入索引的操作。您可以使用过滤条件 jsonPayload.@type="type.googleapis.com/google.cloud.healthcare.logging.FhirConsentCascadeLogEntry" 在 Cloud Logging 中跟踪每个分区基础资源更新的重新编入索引进度。

{
  "insertId": "tz2gtza8",
  "jsonPayload": {
    "@type": "type.googleapis.com/google.cloud.healthcare.logging.FhirConsentCascadeLogEntry",
    "state": "STATE_FINISHED",
    "affectedResources": "2",
    "lastUpdated": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ",
    "compartmentBaseResourceName": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/PATIENT_RESOURCE_ID/_history/PATIENT_RESOURCE_VERSION"
  },
  "resource": {
    "type": "healthcare_fhir_store",
    "labels": {
      "location": "LOCATION",
      "dataset_id": "DATASET_ID",
      "fhir_store_id": "FHIR_STORE_ID",
      "project_id": "PROJECT_ID"
    }
  },
  "timestamp": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ",
  "severity": "INFO",
  "logName": "projects/PROJECT_ID/logs/healthcare.googleapis.com%2Fconsent_cascading_fhir",
  "receiveTimestamp": "YYYY-MM-DDTHH:MM:SS+ZZ:ZZ"
}

jsonPayload.state 是重新编入索引操作的状态,jsonPayload.affectedResources 是重新编入索引的分区资源的数量,jsonPayload.lastUpdated 是患者资源更新的时间戳。如果操作刚刚开始,则 jsonPayload.state="STATE_STARTED"jsonPayload.affectedResources 将不存在。

约束和限制

本部分介绍 FHIR R4 的限制条件和限制,但相同的限制条件和限制适用于 FHIR STU3

类型 限制条件和限额
单个同意资源
  • 仅支持单个 Consent.provision,不支持多个预配或嵌套预配。
  • 至少包含 1 个 Consent.provision.actor,最多 25 个:
    • Consent.provision.actor.role 必须为 http://terminology.hl7.org/CodeSystem/v3-RoleCode
    • Consent.provision.actor.code 必须为 GRANTEEHPOWATT
  • 最多 1 个 Consent.provision.purpose
    • Consent.provision.purpose.system 必须为 http://terminology.hl7.org/CodeSystem/v3-ActReason
    • Consent.provision.purpose.code 为非空,最多 13 个字符。
  • 最多 25 个环境:
    • Consent.provision.extension.url 必须为 https://g.co/fhir/medicalrecords/Environment
    • 系统和代码的总长度必须少于 15 个字符。
  • 如果按资源类型过滤,Consent.provision.class.system 必须为 http://hl7.org/fhir/resource-types
  • 如果按数据源过滤,则 Consent.provision.extension.url 必须为 https://g.co/fhir/medicalrecords/DataSource
  • 如果按数据标记过滤,则 Consent.provision.extension.url 必须为 https://g.co/fhir/medicalrecords/DataTag
    • 数据标记可能是一个复杂的扩展(最多嵌套一层),用于描述将资源与所有指定标记(联合解释)相匹配的政策。
    • 最多支持 5 个嵌套标记。
  • 除非此行中另有说明,否则所有重复属性最多可包含 100 个值。
执行模式
  • 每个患者一次最多可以强制执行 200 个 active 同意资源。
  • 每个商店一次最多可以强制执行 200 项 active 管理员政策。
  • 给定患者的所有有效同意的所有同意指令集的特殊紧凑格式不得超过设置的大小阈值;通常有足够的容量来编码数以千计的同意指令,除非非常长的资源字符串特别多。例如:
    • 唯一数据源和数据标记的数百个同意,每个同意都很长并且占用大量空间。
    • 与未指定任何数据引用限制或以其他方式包含许多相同操作者参考字符串的条款相比,如果单个患者在多个有效同意书中拥有 3,000 个唯一的 Consent.provision.data.reference 资源标识符条目,且每个同意书都指定了唯一的 Consent.provision.actor,则会更积极地使用空间。
  • 每个资源最多可以有适用于其的所有同意中的 1000 条同意指令。
X-Consent-Scope
  • 最少一个、最多三个 actor 条目。
  • 最多一个 purp 条目:
    • 每个 purp 条目都必须采用 system/code 格式(v3http://terminology.hl7.org/CodeSystem/v3-ActReason 的注册系统)。
    • 代码的长度必须小于 13。
  • 最多一个 env 条目:
    • 每个 env 条目都必须采用 system/code 格式。
    • 系统和代码的总长度必须小于 15。
  • btg”至少需要一个“actor”条目。
  • bypass 至少需要一个 actor 条目和一个 env 条目。
支持的方法
性能
  • ApplyConsentsApplyAdminConsents的缩放比例与ImportResources类似或更好。
  • 关于同意感知请求:
    • 我们的意见征求模型已针对 CRUD 操作的强制执行性能进行了优化,包括在众多资源和许多患者中进行大规模搜索。
    • 读取各个资源可能会对请求延迟时间产生细微影响,但搜索性能会因基本查询和同意范围的数量而异,从而导致更多访问者条件在搜索期间生效。
    • 我们建议您针对各种代表性 FHIR 请求参数运行自己的性能测试,以根据数据的特征(例如 FHIR 存储区中包含多少给定搜索资源类型的资源)确定用例的性能特征。
    • 我们的解决方案能够持续注入和更新所有资源(包括同意资源),而且是轻量级的解决方案,因此在注入期间的吞吐量和其他形式的写入流量可能会产生最小的影响。

最佳实践

以下部分介绍使用 FHIR 访问权限控制时的最佳实践。

一般最佳实践

  • 请勿import FHIR 资源并并行调用 ApplyConsentsApplyAdminConsents,我们建议您先导入 FHIR 资源,然后再调用 ApplyConsentsApplyAdminConsents。但是,如果要导入的资源不包含任何“患者”或“同意”资源,则强制执行模型不会受到影响,并且无需处理同意声明或管理政策

  • 请勿创建自定义搜索并并行调用 ApplyConsents。我们建议您逐个更新。

  • 如果您的工作流需要对不相交的 PatientScope 调用多个 ApplyConsents,则可以并行调用它们。

  • ApplyAdminConsents 可以与任意数量的 ApplyConsents 并行运行,但不能与另一个 ApplyAdminConsents 并行运行。

  • 设置代理时,请对 IAM 服务帐号施加只读权限,以避免将一位患者的数据写入另一位患者的记录。

  • 创建或更新记录时,请勿使用意见征求代理。

  • 验证所有写入请求,以防止跨患者数据发生意外修改。

  • 强制执行级联同意时,必须先导入分区基础资源,然后导入其余的分区资源。或者,所有分区资源都可以封装在单个 bundle 中,并使用 fhir.executeBundle 进行提取。

删除患者资源

删除患者资源时,如果您还想移除该患者的同意强制执行(尤其是当 FhirStore.disableReferentialIntegrity 为 true 时),我们建议您遵循以下操作顺序:

  1. 删除属于患者资源的所有同意资源。

  2. 使用 PatientScope 过滤条件调用 ApplyConsents

如需设置现有存储区以实现同意访问,请完成以下步骤:

  1. 使用 UpdateFhirStore 将具有同意强制执行 versionConsentConfig 设置为 V1,并将 accessEnforced 设置为 false

    curl -X PATCH \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{
          'consentConfig': {
            'version': 'V1',
            'accessEnforced': false
          }
        }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"
  2. 处理患者同意声明或管理政策

    1. ApplyConsents(对于患者同意声明)
    curl -X POST \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{'validateOnly': false}" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"
    1. ApplyAdminConsents 适用于管理员政策和管理员级联政策。
    curl -X POST \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{
          'newConsentsList': {
              'names': [
              'projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/RESOURCE_ID_1/_history/VERSION_ID_1',
              ...
              'projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Consent/RESOURCE_ID_N/_history/VERSION_ID_N'
              ]
          },
          'validateOnly': false
        }" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyAdminConsents"
  3. consentConfig.accessEnforced 设置为 true

    curl -X PATCH \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{
          'consentConfig': {
            'accessEnforced': true
          }
        }" "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig.accessEnforced"

运行 ApplyConsents 或 ApplyAdminConsents 的频率

  • 未设置 ConsentConfig 字段时:首次创建 FHIR 存储区时和清除 ConsentConfig 字段时,ConsentConfig 字段都会取消设置。取消设置 ConsentConfig 字段后,您必须重复设置存储区以获取同意访问权限,然后再发出同意感知请求,以避免评估已过期的同意强制执行政策。

  • 强制执行模型发生变化时:创建、更新或删除同意资源时,强制执行模型会发生变化。在这种情况下,您必须调用 ApplyConsentsApplyAdminConsents,才能使这些更改生效。

    • 如果您可以使用同意更改来跟踪患者,我们建议您使用 PatientScope 过滤条件以避免重新处理整个存储区。此过滤器有助于立即刷新对一小部分患者的执行。

    • 您还可以使用 TimeRange 过滤器定期运行 ApplyConsents。当更新不重要时,此过滤器非常有用。 例如,以下请求刷新了在世界协调时间 (UTC) 2022 年 9 月 20 日上午 0 点到 2022 年 9 月 21 日凌晨 0 点之间更改意见时强制执行的刷新操作。

      curl -X POST \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{
           'validateOnly': false,
           'timeRange': {
             'start': '2022-09-20T00:00:00Z',
             'end': '2022-09-21T00:00:00Z',
           }
          }" \
        "https://healthcare.googleapis.com/v1beta1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"