Issue accessing Observation and DiagnosticReport r...
# support
e
Hello, I’m experiencing a difference in behavior between the REST API and the GraphQL API when applying Access Policies. I’ve defined an AccessPolicy like this (excerpt): { "resourceType": "AccessPolicy", "name": "Practitioner CareTeam Access", "resource": [ { "resourceType": "Patient", "criteria": "Patient?general-practitioner=%profile" }, { "resourceType": "Observation", "criteria": "Observation?subject:Patient.general-practitioner=%profile" }, { "resourceType": "DiagnosticReport", "criteria": "DiagnosticReport?subject:Patient.general-practitioner=%profile" }, { "resourceType": "Procedure", "criteria": "Procedure?subject:Patient.general-practitioner=%profile" } ] } Expected behavior - Using REST (/Observation or /DiagnosticReport), I can access the resources according to the AccessPolicy rules. - Using GraphQL, I expect to be able to retrieve the same related resources (in particular Observation and DiagnosticReport) via nested queries. Observed behavior - Procedure resources are accessible as expected. - DiagnosticReport and Observation resources do not appear in GraphQL results, even though they exist and are accessible via REST. Here is the GraphQL query I’m using: { PatientList(_count: 10, _offset: 0, _sort:"-name") { id ProcedureList(_reference: subject, status: "completed", _sort: "-_lastUpdated") { id report { resource { ... on DiagnosticReport { id result { resource { ... on Observation { id } } } } } } } } } Question Is it expected behavior that the AccessPolicy does not apply the same way in REST and GraphQL? Or could this be a bug / known limitation when resolving references (Procedure.report -> DiagnosticReport -> Observation) in GraphQL? Thanks for your help!
s
Hi @Estelle, I'm no expert on this but I think your Observation and DiagnosticReport criteria queries are using chaining which the docs state is not allowed (see link below) so this may possibly have something to do with it? I think the preferred way to achieve your goal is with compartments but I'm still getting my head around how this works so I'll let someone more knowledgable chime in. https://www.medplum.com/docs/access/access-policies#criteria-based-access-control
t
Hi @simonj , Thanks a lot for your feedback! What’s really odd is that everything works correctly when using REST requests — the issue only happens with GraphQL. The “limitation” around chained searches seems to relate to access policy behavior, not specifically to REST or GraphQL, I think. Maybe @cody , @finnbergquist , or @rahul1 might have some insights? Thanks again!
i
@thomabig or @Estelle, can you post the REST queries that are working for you?
Hello @Ian Plunkett Any info on this ?
Hello @Ian Plunkett , Any news on this topic ? Thank you.
Hello @Ian Plunkett , @cody or @rahul1 , Has anyone an idea about this one ?
i
@thomabig , I was able to reproduce this one. I'm going to get a ticket filed with Engineering to get this remedied
t
Awesome. I'll follow this ticket hoping it solves our issue 🙂
Hi @Ian Plunkett I've seen that @cody had an answer about this issue. I'm not completely sure about the status of this ? Is it something that will / should be fixed ? Is there any recommandation on what we should do to make our graphql work ?
i
@thomabig, unfortunately, the fix here is going to make the access policies align with the documentation. That is, chained search in the policy isn't supported.
t
Ok, this means it will not work neither on REST Api calls ? :/ Do you know what would be the recommandation for our use case ?
f
@thomabig can you help me understand the state of your problem? Is there something that you are trying to achieve in your AccessPolicies that relies on chained search?
t
Hi @finnbergquist Let me explain it to you. Our use case is to restrict patient access to practitioner only if they are part of the general-practitioner Patient resource. Today we are using the following access policy
Copy code
{
  "resourceType": "AccessPolicy",
  "name": "Practitioner CareTeam Access",
  "resource": [
    {
      "resourceType": "Patient",
      "criteria": "Patient?general-practitioner=%profile"
    },
    {
      "resourceType": "Observation",
      "criteria": "Observation?subject:Patient.general-practitioner=%profile"
    },
    {
      "resourceType": "DiagnosticReport",
      "criteria": "DiagnosticReport?subject:Patient.general-practitioner=%profile"
    },
    {
      "resourceType": "Procedure",
      "criteria": "Procedure?subject:Patient.general-practitioner=%profile"
    }
  ]
}
When retrieving Observation, using REST Api, the access policy is correctly implemented, and the practitioner can access all observations of patients that have general-practitioner set as the current Practitioner. Using GraphQL request, the Access policy is not working, and no observation are retrieved. My understanding is that there will be a rollback in the REST Api so that chained search will not work anymore on REST requests. What would you then recommend for us to handle this use case ?
@finnbergquist We are currently having a look at the set-accounts and MSO docs https://github.com/medplum/medplum/tree/main/examples/medplum-mso-demo https://www.medplum.com/docs/api/fhir/operations/patient-set-accounts Let us check that before digging yourself !
f
Where you add Practitioner references with
$set-accounts
Copy code
const response = await medplum.post('/fhir/R4/Patient/123/$set-accounts', {
  resourceType: 'Parameters',
  parameter: [
    {
      name: 'accounts',
      valueReference: {
        reference: 'Organization/456',
      },
    },
    {
      name: 'accounts',
      valueReference: {
        reference: 'Practitioner/789',
      },
    },
    {
      name: 'propagate',
      valueBoolean: true,
    },
  ],
});
and your access policy use
_compartment
for every different resourceType:
Copy code
{
 "resourceType": "AccessPolicy",
 "name": "Managed Service Organization Access Policy with Patient Consent",
 "compartment": {
   "reference": "%organization"
 },
 "resource": [
   {
     "resourceType": "Patient",
     "criteria": "Patient?_compartment=%organization&_compartment=%profile"
   },
   {
     "resourceType": "Observation",
     "criteria": "Observation?_compartment=%organization&_compartment=%profile"
   },
   {
     "resourceType": "DiagnosticReport",
     "criteria": "DiagnosticReport?_compartment=%organization&_compartment=%profile"
   },
   {
     "resourceType": "Encounter",
     "criteria": "Encounter?_compartment=%organization&_compartment=%profile"
   },
   {
     "resourceType": "Communication",
     "criteria": "Communication?_compartment=%organization&_compartment=%profile"
   },
   //...
 ]
}
note: in your case you probably don't need the
%organization
parameter
You could also add CareTeam references with
$set-accounts
and then pass those CareTeams into the AccessPolicy using [parameterized AccessPolicies](https://www.medplum.com/docs/access/access-policies#parameterized-policies) ex:
Copy code
{
 "resourceType": "ProjectMembership",
 //...
 "access": [
   {
     "parameter": [
       {
         "name": "care_team",
         "valueReference": {
           "reference": "CareTeam/0195b4a4-0ed7-71ed-80cf-c6fff1e31152"
         }
       }
     ],
     "policy": {
       "reference": "AccessPolicy/0195b4a3-374e-75cf-a6f0-0bcee7c754c5"
     }
   }
 ]
}
And then use`_compartment=%care_team` as criteria in your AccessPolicy
66 Views