Controle o acesso aos recursos FHIR na Cloud Healthcare API

Esta página descreve como usar os recursos de consentimento da FHIR para determinar o acesso aos dados das lojas FHIR na Cloud Healthcare API.

Para configurar um FHIR store com a aplicação do consentimento, conclua os seguintes passos:

  1. Crie um FHIR store se ainda não tiver um.

  2. Defina os seguintes parâmetros ConsentConfig da loja FHIR para ativar a aplicação do consentimento:

    • version: especifica que versão da aplicação do consentimento está a ser usada para o repositório FHIR. Este valor só pode ser definido uma vez por CreateFhirStore ou UpdateFhirStore. Depois de a definir, tem de ligar para ApplyConsents ou ApplyAdminConsents para alterar a versão.

    • access_enforced: se estiver definida como true, quando aceder a recursos FHIR, os cabeçalhos de consentimento fornecidos são validados em relação às diretivas de consentimento dadas pelos consumidores.

    • consent_header_handling: Se estiver definido como PERMIT_EMPTY_SCOPE (predefinição), o servidor permite pedidos sem (ou vazio) o cabeçalho X-Consent-Scope. Se for definido como REQUIRED_ON_READ e access_enforced = true, o servidor rejeita todos os pedidos sem o cabeçalho X-Consent-Scope (ou vazio).

Configure um novo FHIR store com o ConsentConfig

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': true
      }
    }" "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores?fhirStoreId=FHIR_STORE_ID"

Deve receber uma resposta JSON semelhante à seguinte:

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

Se já tiver uma loja, use UpdateFhirStore para definir o elemento ConsentConfig com a aplicação do consentimento version como V1 e defina accessEnforced como true.

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

As políticas são representadas através do recurso de consentimento. A finalidade e a utilização dos campos de recursos são descritas nos documentos do modelo de dados.

Segue-se um exemplo de todos os recursos que podem ser criados para este exemplo específico.

Crie recursos FHIR

O exemplo seguinte mostra como executar um [FHIR bundle](/healthcare-api/docs/how-tos/fhir-bundles) para preencher os seguintes recursos:

  • Um recurso Practitioner com o nome Jeffrey Brown
  • Um recurso Patient com o nome Darcy Smith
  • Um recurso Observation que mostra a medição de hemoglobina de Darcy (LOINC718-7) que foi recolhida pelo Happy Hospital
  • Um recurso Observation que mostra a medição de glicose de Darcy (LOINC15074-8).
  • Um consentimento de Darcy para permitir que Jeffrey Brown use a aplicação App/123 para aceder aos dados recolhidos pelo Happy Hospital
  • Um consentimento de Darcy para permitir que Jeffrey Brown aceda a quaisquer dos respetivos dados para tratamento de emergência (ETREAT)
  • Um consentimento do Happy Hospital para permitir que Jeffrey Brown aceda a todos os dados quando faz investigação biomédica (BIORCH) com a aplicação 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"
        }],
        "meta": {
          "tag": [{
            "system": "http://terminology.hl7.org/CodeSystem/common-tags",
            "code": "employee"
          }]
        },
        "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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir"

Deve receber uma resposta JSON semelhante à seguinte:

{
  "entry": [
    {
      "response": {
        "etag": "W/\"VERSION_ID\"",
        "lastModified": "2022-09-01T17:31:40.423469+00:00",
        "location": "https://healthcare.googleapis.com/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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/v1/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"
}

Seguem-se mais exemplos do recurso de consentimento R4 que demonstram como as políticas complexas podem ser representadas.

{
  "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"
      }
    ],
    "securityLabel": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
        "code": "R"
      },
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "PSY"
      }
    ]
  }
}

O exemplo anterior representa um recurso de consentimento do paciente no qual um paciente f001 dá permissão a um profissional f002 com o objetivo de fornecer tratamento regular representado por TREAT. O profissional é da geolocalização iso3166-1/CA. Este recurso de consentimento permite ao profissional de saúde aceder aos dados do paciente se os dados satisfizerem todas as seguintes condições.

  • É um tipo Encounter com o ID Encounter/e001.
  • É proveniente da fonte http://somesystem.example.org/foo.
  • Satisfaz, pelo menos, uma das seguintes condições na etiqueta (os recursos podem ser etiquetados definindo os campos Meta.tag system e code):
    • Tem a etiqueta (system = http://terminology.hl7.org/CodeSystem/common-tags e code = actionable)
    • Tem ambas as etiquetas (system = http://example.com/custom-tags e code = archived) e (system = http://example.com/custom-tags e code = insensitive)
  • Tem, pelo menos, uma das seguintes etiquetas de segurança
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentiality e code é um dos valores R, N, M, L, U.
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCode e code = PSY.

Exemplo de diretiva de política do administrador

{
  "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"
      }
    ],
    "securityLabel": [
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-Confidentiality",
        "code": "R"
      },
      {
        "system": "http://terminology.hl7.org/CodeSystem/v3-ActCode",
        "code": "PSY"
      }
    ]
  }
}

O exemplo anterior representa um recurso de consentimento da política de administrador que concede autorização a um profissional de saúde f002 com o objetivo de fornecer tratamento regular representado por TREAT. O profissional é da geolocalização iso3166-1/CA. Este recurso Consentimento permite ao profissional de saúde aceder aos dados do paciente se os dados satisfizerem todas as seguintes condições:

  • É um tipo Encounter com o ID Encounter/e001.
  • É proveniente da fonte http://somesystem.example.org/foo.
  • Cumpre, pelo menos, uma das seguintes condições na etiqueta:
    • Tem a etiqueta (system = http://terminology.hl7.org/CodeSystem/common-tags e code = actionable)
    • Tem ambas as etiquetas (system = http://example.com/custom-tags e code = archived) e (system = http://example.com/custom-tags e code = insensitive)
  • Tem, pelo menos, uma das seguintes etiquetas de segurança
    • system = http://terminology.hl7.org/CodeSystem/v3-Confidentiality e code é um dos valores R, N, M, L, U.
    • system = http://terminology.hl7.org/CodeSystem/v3-ActCode e code = PSY.

Exemplo de diretiva de política em cascata de administrador

{
  "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"
        }
      }
    ]
  }
}

O exemplo anterior representa um recurso de consentimento de política em cascata de um administrador que concede permissão a um profissional de saúde f002 com o objetivo de fornecer tratamento regular representado por TREAT. O profissional é da geolocalização iso3166-1/CA. Este recurso de consentimento permite que o profissional aceda aos dados do compartimento de pacientes com a etiqueta employee. Todos os critérios de recursos aplicam-se apenas aos recursos base do compartimento, ou seja, o recurso Patient, uma vez que controlam os recursos a serem propagados.

Aplique consentimentos dos pacientes ou políticas de administrador

Aplique os consentimentos do paciente até 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"

Deve receber uma resposta JSON semelhante à seguinte:

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

A resposta contém um nome de operação. Para acompanhar o estado da operação, pode usar o [método `get` da operação](/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

Quando a operação termina, o servidor devolve uma resposta com o estado da operação no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.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.v1.fhir.ApplyConsentsResponse",
    "consentApplySuccess": "2",
    "affectedResources": "5"
  }
}

Esta resposta indicou que o servidor processou com êxito 2 consentimentos e atualizou o acesso consensual de 5 recursos (1 paciente, 2 consentimentos e 2 observações).

Aplique a política do administrador até ApplyAdminConsents

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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyAdminConsents"

Deve receber uma resposta JSON semelhante à seguinte:

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

A resposta contém um nome de operação. Para acompanhar o estado da operação, pode usar o [método `get` da operação](/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

Quando a operação termina, o servidor devolve uma resposta com o estado da operação no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.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.v1.fhir.ApplyAdminConsentsResponse",
    "consentApplySuccess": "1",
    "affectedResources": "7"
  }
}

Esta resposta indicou que o servidor processou com êxito 1 política de administrador e atualizou o acesso consensual de 7 recursos (1 profissional de saúde, 1 paciente, 2 observações, 2 consentimentos de pacientes e 1 política de administrador).

A aplicação dos consentimentos armazenados num FHIR store não entra em vigor até que a API ApplyConsents (para consentimentos de pacientes) ou ApplyAdminConsents (para políticas de administrador e políticas de administrador em cascata) seja chamada e concluída com êxito. Se adicionar, modificar ou remover consentimentos depois de executar ApplyConsents ou ApplyAdminConsents, tem de o executar novamente para que esses consentimentos sejam incluídos no modelo de aplicação.

Os recursos FHIR são indexados de forma assíncrona, pelo que pode haver um ligeiro atraso entre o momento em que ApplyConsents ou ApplyAdminConsents é concluído e o momento em que o modelo de aplicação se reflete nos resultados da pesquisa. Este atraso só é esperado para pedidos de pesquisa.

Se esta for a primeira vez que está a configurar a aplicação da aplicação da lei do consentimento na FHIR store, aguarde que a operação de longa duração ApplyConsents ou ApplyAdminConsents seja concluída antes de fazer pedidos com reconhecimento do consentimento.

Para chamar ApplyConsents num subconjunto de pacientes, pode usar os seguintes filtros:

  • PatientScope: para executar ApplyConsents numa lista de IDs de pacientes com até 10 000 pacientes

  • TimeRange: para executar ApplyConsent numa lista de IDs de recursos de pacientes cujos recursos de consentimento são atualizados durante um determinado intervalo de tempo

Para chamar ApplyAdminConsents: tem de fornecer a lista completa de todas as políticas que quer aplicar (e não uma lista incremental). Como resultado, uma lista vazia anula a aplicação de todas as políticas de administrador da loja. Cada política tem de ser um nome de versão do recurso se o armazenamento FHIR estiver a usar o controlo de versões e um nome de recurso caso contrário.

Pode usar operations.get para obter o ProgressCounter da operação. Após a conclusão, existe um ApplyConsentsResponse que está incluído no Operation.response. Os contadores em ProgressCounter e ApplyConsentsResponse ou ApplyAdminConsentsResponse são descritos na tabela seguinte.

ProgressCounter ApplyConsentsResponse ou ApplyAdminConsentsResponse Descrição
success consentApplySuccess O número de recursos Consent que a operação processou com êxito.
failure consentApplyFailure O número de recursos de consentimento que não são suportados ou são inválidos. Pode ver os registos de erros no Cloud Logging ou, quando validateOnly é false, verificar o estado da aplicação do consentimento através de CheckConsentEnforcementStatus ou CheckPatientConsentEnforcementStatus para obter detalhes dos erros.
secondarySuccess affectedResources Quando validateOnly é false, representa o número de recursos FHIR que foram reindexados com êxito devido ao efeito da alteração do consentimento.
secondaryFailure failedResources Quando validateOnly é false, representa o número de recursos FHIR que podem ter uma alteração de consentimento, mas não foram reindexados. Isto pode afetar a pesquisa com contexto de consentimento, mas não outros métodos. Para ver os detalhes do erro, pode ver os registos de erros no Cloud Logging.

Quando os recursos de consentimento da FHIR são processados, pode usar as seguintes APIs para verificar o estado da aplicação de um único consentimento ou de todos os consentimentos de um paciente:

Para a política de administrador, o CheckConsentEnforcementStatus só pode ser usado para verificar o estado de aplicação de uma única política de administrador de consentimento. Em alternativa, pode usar fhirStores.get para ver todas as políticas de administrador ativas aplicadas à loja.

O elemento consent-enforcement-status pode ter qualquer um dos seguintes valores:

  • OFF: representa o estado de aplicação predefinido de um novo recurso de consentimento no qual o recurso de consentimento nunca foi processado.

  • ENFORCEABLE: o estado em que o recurso Consent foi processado com êxito.

  • INACTIVE: um estado inativo no qual o recurso Consent é ignorado.

  • UNSUPPORTED: o estado de um recurso de consentimento que pode estar em conformidade com as especificações da FHIR, mas que não é aplicável. Isto deve-se à implementação limitada da aplicação da autorização da FHIR com o nível atual de suporte de funcionalidades.

  • ENFORCEMENT_LIMIT_EXCEEDED: o estado em que o formato do recurso de consentimento FHIR e o nível de apoio técnico para o recurso estão sem erros. No entanto, uma ou mais das seguintes condições são verdadeiras:

    • O paciente tem um grande conjunto de recursos de consentimento.

    • O tamanho das diretivas de consentimento em todos os consentimentos ativos é superior ao tamanho máximo permitido das diretivas de consentimento para um servidor FHIR aplicá-las.

A Cloud Healthcare API suporta pesquisas de recursos FHIR num determinado FHIR store com actor, purpose e environment como parâmetros de consulta. A resposta contém apenas os recursos que têm consentimento.

  1. O profissional Jeffrey Brown (identificado por Practitioner/12942879-f89f-41ae-aa80-0b911b649833) que usa uma aplicação fidedigna App/123 pesquisa todas as observações com 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?status=final"

    Deve receber uma resposta JSON semelhante à seguinte:

    {
      "entry": [
        {
          "fullUrl": "https://healthcare.googleapis.com/v1/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?status=final"
        }
      ],
      "resourceType": "Bundle",
      "total": 1,
      "type": "searchset"
    }
    
  3. O profissional Jeffrey Brown (identificado por Practitioner/12942879-f89f-41ae-aa80-0b911b649833) usa a aplicação App/123 para pesquisar todas as observações do paciente 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?subject:Patient.name=Darcy"

    Deve receber uma resposta JSON semelhante à seguinte:

    {
      "link": [
        {
          "relation": "search",
          "url": "https://healthcare.googleapis.com/v1/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/v1/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/?subject%3APatient.name=Darcy"
        }
      ],
      "resourceType": "Bundle",
      "total": 0,
      "type": "searchset"
    }
    

    A consulta anterior é uma pesquisa encadeada. Uma vez que o cenário de consentimento actor/Practitioner/12942879-f89f-41ae-aa80-0b911b649833 env/App/123 tem o acesso negado ao recurso Patient Darcy (identificado por Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2), o servidor FHIR não devolve nenhuma Observation do Patient, como se o Patient não existisse.

  5. O profissional Jeffrey Brown (identificado por Practitioner/12942879-f89f-41ae-aa80-0b911b649833) que usa a aplicação App/123 pesquisa todas as observações do paciente Darcy para fins de tratamento de emergência.
  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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?subject:Patient.name=Darcy"

    Deve receber uma resposta JSON semelhante à seguinte:

    {
      "entry": [
        {
          "fullUrl": "https://healthcare.googleapis.com/v1/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/v1/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/v1/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/v1/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/v1/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. O profissional Jeffrey Brown (identificado por Practitioner/12942879-f89f-41ae-aa80-0b911b649833) pesquisa observações com status=final para dois fins: tratamento e investigação
  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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation?status=final"

    Deve receber uma resposta JSON semelhante à seguinte:

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

    Neste caso, o profissional Jeffrey Brown deve remover uma finalidade desnecessária do `X-Consent-Scope` no pedido.

  9. Um administrador de TI de um hospital usa o bypass para pesquisar todos os profissionais de saúde no hospital.
  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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner?"

    Como bypass é fornecido, as verificações de consentimento foram ignoradas. Deve receber uma resposta JSON semelhante à seguinte:

    {
      "entry": [
        {
          "fullUrl": "https://healthcare.googleapis.com/v1/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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?"
        },
        {
          "relation": "first",
          "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?"
        },
        {
          "relation": "self",
          "url": "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Practitioner/?"
        }
      ],
      "resourceType": "Bundle",
      "total": 1,
      "type": "searchset"
    }
    

A Cloud Healthcare API suporta a obtenção de recursos FHIR num determinado FHIR store com actor, purpose e environment como parâmetros de consulta. A resposta contém apenas os recursos que têm consentimento.

  1. O profissional de saúde Jeffrey Brown (identificado por Practitioner/12942879-f89f-41ae-aa80-0b911b649833) através da aplicação App/123 lê a medição de hemoglobina do paciente (neste exemplo, 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"

    Uma vez que o requerente deu o seu consentimento, a resposta é o conteúdo do recurso Observation.

    {
      "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. O profissional de saúde Jeffrey Brown (identificado por Practitioner/12942879-f89f-41ae-aa80-0b911b649833) que usa uma aplicação desconhecida App/unknown lê a medição de hemoglobina do paciente (neste exemplo, 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"

    Uma vez que o acesso ao limite do requerente (`App/unknown`) não é permitido pelo consentimento do paciente, o pedido é recusado.

    {
      "issue": [
        {
          "code": "security",
          "details": {
            "text": "permission_denied"
          },
          "diagnostics": "Consent access denied or the resource being accessed does not exist",
          "severity": "error"
        }
      ],
      "resourceType": "OperationOutcome"
    }
    
  5. O profissional Jeffrey Brown (identificado por Practitioner/12942879-f89f-41ae-aa80-0b911b649833) que faz investigação biomédica através da aplicação App/golden lê a data de nascimento de Darcy (neste exemplo, 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Patient/3c6aa096-c054-4c22-b2b4-1e4a4d203de2"

    Uma vez que o requerente recebeu consentimento, a resposta é o conteúdo do recurso Patient.

    {
      "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",
        "tag": [{
          "system": "http://terminology.hl7.org/CodeSystem/common-tags",
          "code": "employee"
        }]
      },
      "name": [
        {
          "family": "Smith",
          "given": [
            "Darcy"
          ],
          "use": "official"
        }
      ],
      "resourceType": "Patient"
    }
    
  7. O profissional Jeffrey Brown (identificado por Practitioner/12942879-f89f-41ae-aa80-0b911b649833) pede acesso não autorizado de emergência ao registo de um paciente através do protocolo "break-the-glass". (neste exemplo, 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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID/fhir/Observation/7473784b-46a8-470c-b9a6-fe38a01025aa"

    Uma vez que o método de autorização do consentimento é btg, o servidor ignora as verificações de consentimento. A resposta é o conteúdo do recurso Observation.

    {
      "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
      }
    }
    

As secções seguintes descrevem os métodos de aplicação do consentimento suportados na Cloud Healthcare API e como o acesso aos recursos é aplicado quando faz um pedido com reconhecimento de consentimento.

Ao fazer um pedido, o seu servidor de autorização é responsável por gerar tokens de acesso com o âmbito de consentimento relevante.

Defina o cabeçalho HTTP

Os âmbitos de consentimento são transmitidos à Cloud Healthcare API através do cabeçalho HTTP X-Consent-Scope. A Cloud Healthcare API usa este cabeçalho para aplicar o controlo de acesso baseado no consentimento aos dados em arquivos FHIR.

Um pedido FHIR pode suportar um número limitado de âmbitos de entrada de consentimento. Podem ser incluídas até três entradas de actor, uma de purp e uma de env num determinado pedido FHIR.

Para âmbitos especiais, um pedido FHIR pode suportar um dos seguintes: btg ou bypass.

Defina cabeçalhos HTTP para aplicações fidedignas

Esta secção só é necessária se estiver a usar um servidor de autorização controlado pelo cliente. Neste caso, também tem de usar um SMARTproxy ou um proxy semelhante.

Algumas aplicações fidedignas podem fazer chamadas diretamente para a Cloud Healthcare API com os âmbitos de consentimento no cabeçalho HTTP especificado. Isto permite a aplicação direta do consentimento sem a necessidade de um SMARTproxy ou outro proxy para fazer a conversão entre servidores de autorização externos e Google Cloud.

Por exemplo, a sua aplicação pode estar registada para um subconjunto de âmbitos, como um âmbito environment da aplicação, ou a aplicação pode apresentar um widget de seleção para definir algumas entradas de âmbito, como o purpose do acessor.

Um utilizador ou uma aplicação fidedigna também pode usar as entradas de âmbito btg ou bypass, que estão sujeitas a revisões de pós-auditoria.

A API Cloud Healthcare oferece suporte incorporado para a aplicação de consentimento FHIR com base nos âmbitos de consentimento introduzidos. Os administradores da loja FHIR são responsáveis por criar e configurar um servidor de autorização fora da Cloud Healthcare API que concede âmbitos de consentimento.

Exemplo de chave de acesso

O exemplo seguinte mostra um token de acesso codificado em base64:

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzM4NCJ9.eyJpc3MiOiJjb25zZW50LnRva2VuLm9yZyIsImlhdCI6MTYxMjg4NDA4NSwiZXhwIjoxNjQ0NDIwMDg1LCJhdWQiOiJ3d3cuZXhhbXBsZS5jb20iLCJzdWIiOiJkb2N0b3IuZ2FicmllbGFAZXhhbXBsZS5jb20iLCJzY29wZSI6Im9pZGMgYWN0b3IvUHJhY3RpdGlvbmVyLzEyMyBhY3Rvci9Hcm91cC85OTkgcHVycC92My9UUkVBVCBlbnYvQXBwL2FiYyJ9.fC7ljkVUUx8fwUOrJuONcrqA-WKC-k_Bclzlgds0Cq6H_gEe3nUjPlSOCTQsIdYB

Depois de descodificar o token de acesso, pode ver que contém a seguinte carga útil:

{
  "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"
}

Configure o SMARTProxy

O SMARTProxy é um proxy de código aberto da Google que oferece as seguintes funcionalidades:

  • Permite que o servidor FHIR da API Cloud Healthcare aceite e valide tokens de acesso sensíveis ao consentimento.

  • Permite que a implementação da FHIR na Cloud Healthcare API inclua tokens de acesso com reconhecimento de consentimento como parte da gestão da Cloud Healthcare API e do modelo de autorização.

  • Também suporta funcionalidades de tokens para compatibilidade com SMART on FHIR.

Quando faz um pedido para obter dados da Cloud Healthcare API através do SMARTProxy, ocorre o seguinte:

  1. O SMARTProxy aceita um pedido de um cliente que contenha um token com reconhecimento de consentimento.

  2. O SMARTProxy valida o token com reconhecimento de consentimento através de um servidor de autorização JWT que lhe pertence.

  3. O SMARTProxy lê os âmbitos do token com reconhecimento de consentimento e transmite-os à API Cloud Healthcare através do cabeçalho HTTP.

  4. A Cloud Healthcare API recebe os cabeçalhos e valida-os para aplicar diretivas de consentimento no pedido. Em seguida, a Cloud Healthcare API devolve uma resposta através do SMARTProxy ao cliente.

Configure uma Google Cloud conta de serviço

Um proxy só pode ter uma única Google Cloud conta de serviço. Se vários clientes usarem o mesmo proxy, os clientes vão usar a mesma conta de serviço. Tenha cuidado ao partilhar uma conta de serviço com vários clientes pelos seguintes motivos:

Por exemplo, se chamar a Cloud Healthcare API diretamente através da sua conta Google para autenticação, os registos de auditoria do Google Cloud registam o seu endereço de email como o endereço de email principal. Quando usa um proxy para chamar a Cloud Healthcare API, o proxy usa a sua própria conta de serviço, e o endereço de email principal é o endereço de email da conta de serviço, e a conta original não está definida.

Registos de auditoria

Os registos de auditoria são gerados quando existe um pedido de acesso ou quando a aplicação do acesso aos recursos é alterada.

Aceda aos registos de auditoria

Se os registos de auditoria estiverem ativados na loja FHIR, é incluído um campo de metadados consentMode nos registos de auditoria disponíveis no Cloud Logging. O consentMode pode ter um dos seguintes valores:

  • off: a configuração da loja FHIR tem consentConfig.accessEnforced definido como false e não permite pedidos com reconhecimento de consentimento.

  • emptyScope: o FHIR store tem consentConfig.accessEnforced definido como true, mas não foi incluído um cabeçalho de âmbito de consentimento. Como resultado, os consentimentos não foram aplicados.

  • enforced: a loja FHIR tem consentConfig.accessEnforced definido como true e o cabeçalho do âmbito de consentimento estava presente. Como resultado, os consentimentos foram avaliados e aplicados no pedido.

  • btg: o pedido FHIR tinha btg no cabeçalho do âmbito de consentimento. Como resultado, as verificações de consentimento foram ignoradas. Este pedido destina-se a ser usado para emergências e está sujeito apenas a revisão pós-auditoria.

  • bypass: o pedido FHIR tinha apenas bypass fornecido no cabeçalho consent scope. Como resultado, as verificações de consentimento foram ignoradas. Este pedido destina-se a ser usado por um fluxo de trabalho fidedigno (como um administrador ou uma aplicação fidedigna em vez de utilizadores finais) para que este registo de auditoria seja diferente do btg, que é usado para verificações de administração de dados.

Opcionalmente, pode definir access_determination_log_config como VERBOSE para registar mais informações sobre o motivo pelo qual um pedido é concedido ou recusado.

Aceda aos registos de auditoria de alterações de aplicação de acesso

Quando o recurso base do compartimento é alterado (por exemplo, a remoção de uma etiqueta employee de um paciente): o controlo de acesso no recurso alterado e no respetivo compartimento pode ser alterado devido à política de cascata de administrador. Esta ação aciona a reindexação em todos os recursos do respetivo compartimento. Pode acompanhar o progresso da reindexação de cada atualização de recursos base do compartimento no Cloud Logging com o filtro jsonPayload.@type="type.googleapis.com/google.cloud.healthcare.logging.FhirConsentCascadeLogEntry".

Exemplo de registo de progresso da reindexação em cascata

{
  "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 é o estado da operação de reindexação, jsonPayload.affectedResources é o número de recursos de compartimento reindexados e jsonPayload.lastUpdated é a data/hora da atualização do recurso do paciente. Se a operação tiver acabado de começar, jsonPayload.state="STATE_STARTED" e jsonPayload.affectedResources não estão presentes.

Restrições e limitações

Esta secção mostra as restrições e os limites para o FHIR R4, mas as mesmas restrições e limites aplicam-se ao FHIR STU3.

Tipo Restrições e limites
Recurso de consentimento único
  • Apenas é suportada uma única Consent.provision. Não são suportadas várias disposições nem disposições aninhadas.
  • Pelo menos 1 Consent.provision.actor, no máximo 25:
    • Consent.provision.actor.role tem de ser http://terminology.hl7.org/CodeSystem/v3-RoleCode.
    • Consent.provision.actor.code tem de ser GRANTEE ou HPOWATT.
  • No máximo, 1 Consent.provision.purpose:
    • Consent.provision.purpose.system tem de ser http://terminology.hl7.org/CodeSystem/v3-ActReason.
    • Consent.provision.purpose.code não está vazio e tem, no máximo, 13 carateres.
  • No máximo, 1 environment:
    • Consent.provision.extension.url tem de ser https://g.co/fhir/medicalrecords/Environment.
    • O comprimento do sistema e do código combinados tem de ser inferior a 15 carateres.
  • Se filtrar por tipo de recurso, Consent.provision.class.system tem de ser http://hl7.org/fhir/resource-types.
  • Se filtrar por origem de dados, Consent.provision.extension.url tem de ser https://g.co/fhir/medicalrecords/DataSource.
  • Se filtrar por etiqueta de dados, Consent.provision.extension.url tem de ser https://g.co/fhir/medicalrecords/DataTag.
    • A etiqueta de dados pode ser uma extensão complexa, aninhada até um nível, para descrever uma política que corresponda a recursos com todas as etiquetas especificadas (interpretadas conjuntamente).
    • São suportadas, no máximo, 5 etiquetas aninhadas.
  • No máximo, 100 valores para todos os atributos repetidos, salvo descrição em contrário nesta linha.
Modelo de aplicação
  • Cada paciente pode ter até 200 recursos de consentimento active aplicados em simultâneo.
  • Cada loja pode ter até 200 políticas de administrador active aplicadas em simultâneo.
  • Um formato compacto especial para o conjunto de todas as diretivas de consentimento em todos os consentimentos ativos para um determinado paciente não pode exceder um limite definido de tamanho. Normalmente, existe capacidade suficiente para codificar milhares de diretivas de consentimento, a menos que existam muitas strings de recursos muito longas. Por exemplo:
    • Centenas de consentimentos numa origem de dados e etiquetas de dados únicas, cada uma muito longa, consomem muito espaço.
    • Um único paciente com 3000 entradas de identificadores de recursos Consent.provision.data.reference em vários consentimentos ativos, cada um a especificar um Consent.provision.actor único, usa o espaço de forma mais agressiva do que os aprovisionamentos que não especificam nenhuma restrição de referência de dados ou que, de outra forma, contêm muitas das mesmas strings de referência de ator.
  • Cada recurso pode ter até 1000 diretivas de consentimento de todos os consentimentos que lhe são aplicáveis.
X-Consent-Scope
  • Mínimo de uma e máximo de três entradas actor.
  • Máximo de uma entrada de purp:
    • Cada entrada purp tem de estar no formato system/code (v3 é o sistema registado para http://terminology.hl7.org/CodeSystem/v3-ActReason).
    • O comprimento do código tem de ser inferior a 13.
  • Máximo de uma entrada de env:
    • Cada entrada env tem de estar no formato system/code.
    • O comprimento combinado do sistema e do código tem de ser inferior a 15.
  • btg requer, no mínimo, uma entrada de actor.
  • O bypass requer, no mínimo, uma entrada de actor e uma entrada de env.
Métodos suportados
Desempenho
  • ApplyConsents e ApplyAdminConsents são escaláveis de forma semelhante ou melhor do que ImportResources.
  • Relativamente a pedidos com reconhecimento de consentimento:
    • O nosso modelo de consentimento foi otimizado para o desempenho da aplicação de operações CRUD, incluindo a pesquisa em grande escala em muitos recursos e muitos pacientes.
    • A leitura de recursos individuais pode ter um impacto marginal na latência dos pedidos. No entanto, o desempenho da pesquisa varia consoante a consulta base e o número de âmbitos de consentimento que levam à ativação de mais critérios de acesso durante uma pesquisa.
    • Recomendamos que execute os seus próprios testes de desempenho em vários parâmetros de pedidos FHIR representativos para determinar as caraterísticas de desempenho dos seus exemplos de utilização com base nas caraterísticas dos seus dados, como quantos recursos de um determinado tipo de recurso de pesquisa estão na loja FHIR.
    • A nossa solução mantém o carregamento e as atualizações de todos os recursos, incluindo os recursos de consentimento, de forma simples, para que o débito durante o carregamento e outras formas de tráfego de gravação possam prosseguir com o mínimo impacto.

Práticas recomendadas

As secções seguintes descrevem as práticas recomendadas quando usa o controlo de acesso FHIR.

Práticas recomendadas gerais

  • Não importe recursos FHIR e chame ApplyConsents ou ApplyAdminConsents em paralelo. Recomendamos que importe primeiro os recursos FHIR e, em seguida, chame ApplyConsents ou ApplyAdminConsents. No entanto, se os recursos a importar não incluírem recursos de pacientes ou consentimento, o modelo de aplicação não é afetado e o processamento de consentimentos ou políticas de administrador não é necessário.

  • Não crie pesquisas personalizadas e chame ApplyConsents em paralelo. Recomendamos que os faça um após o outro.

  • Se os seus fluxos de trabalho exigirem a chamada de vários ApplyConsents em PatientScopedesarticulados, podem ser chamados em paralelo.

  • ApplyAdminConsents pode ser executado em paralelo com qualquer número de ApplyConsents, mas não com outro ApplyAdminConsents.

  • Ao configurar o proxy, restrinja a conta de serviço do IAM com autorizações de apenas leitura para evitar escrever os dados de um paciente nos registos de outro.

  • Não use o proxy de consentimento quando criar ou atualizar registos.

  • Valide todos os pedidos de escrita para evitar a modificação inesperada de dados de vários pacientes.

  • Quando os consentimentos em cascata são aplicados, os recursos base do compartimento têm de ser importados primeiro, seguidos pelos restantes recursos do compartimento. Em alternativa, todos os recursos do compartimento podem ser incluídos num único pacote e carregados usando fhir.executeBundle.

Elimine o recurso Patient

Quando eliminar um recurso Patient, se também quiser remover a aplicação do consentimento para esse paciente (especialmente quando FhirStore.disableReferentialIntegrity é verdadeiro), recomendamos que siga esta ordem de operações:

  1. Elimine todos os recursos Consent pertencentes ao recurso Patient.

  2. Ligue para ApplyConsents com o filtro PatientScope.

Para configurar uma loja existente para acesso ao consentimento, conclua estes passos:

  1. Use UpdateFhirStore para definir o ConsentConfig com a aplicação do consentimento version como V1 e defina accessEnforced como true.

    curl -X PATCH \
        -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
        -H "Content-Type: application/json" \
        --data "{
          'consentConfig': {
            'version': 'V1',
            'accessEnforced': true
          }
        }" "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID?update_mask=consentConfig"
  2. Processar consentimentos de pacientes ou políticas de administração

    1. ApplyConsents para consentimentos de pacientes
    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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"
    1. ApplyAdminConsents para políticas de administrador e políticas em cascata de administrador.
    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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyAdminConsents"

Com que frequência deve executar ApplyConsents ou ApplyAdminConsents

  • Quando o campo ConsentConfig não está definido: o campo ConsentConfig não está definido quando uma loja FHIR é criada pela primeira vez e quando o campo ConsentConfig é limpo. Assim que o campo ConsentConfig for anulado, tem de repetir a ação de configurar a loja para acesso ao consentimento antes de fazer pedidos com reconhecimento do consentimento para evitar a avaliação de políticas de aplicação do consentimento desatualizadas.

  • Quando o modelo de aplicação muda: quando um recurso de consentimento é criado, atualizado ou eliminado, o modelo de aplicação muda. Nestes casos, tem de ligar para ApplyConsents ou ApplyAdminConsents para que estas alterações entrem em vigor.

    • Se conseguir acompanhar as alterações de pacientes com consentimento, recomendamos que use o filtro PatientScope para evitar o reprocessamento de toda a loja. Este filtro é útil para atualizar imediatamente a aplicação de um pequeno conjunto de pacientes.

    • Também pode executar ApplyConsents periodicamente através do TimeRange filtro. Este filtro é útil quando a atualização imediata não é essencial. Por exemplo, o seguinte pedido atualiza a aplicação para alterações de consentimento entre as 00:00 UTC de 20/09/2022 e as 00:00 UTC de 21/09/2022.

      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/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:applyConsents"

O visualizador de consentimento FHIR apresenta políticas de controlo de acesso. Fornece uma tabela com âmbitos de consentimento para representar regras de controlo de acesso FHIR.

Antes de poder usar o visualizador de consentimento FHIR, certifique-se de que tem o seguinte:

Para ver o visualizador de consentimento FHIR, conclua os seguintes passos:

O que se segue?