Data minimization / filtering
Many types of data we process on behalf of healthcare organisations are designated as sensitive information. As indicated in the article Development stages, one of our requirements for approving a connector is that only necessary and efficient information is exchanged via the Ons API. We facilitate data minimization by offering filtering capabilities at three levels, which are explained below.
Types of Filtering
Filtering based on APIs
During the development stage, all APIs are available (filtering of endpoints can be enabled or disabled during this stage). Before access to the next stages is allowed, it must be specified which APIs are required. We do this to ensure that a connector does not have access to more information than necessary. The list of APIs available for the connector is visible to healthcare organisations, allowing them to know what kind of information can be exchanged with which connector.
Filtering of fields per model
Each model has a set of fields. We require that the minimum amount of fields be selected in relation to the purpose and functional design of the connector. For example: the connector requires various employee data under ‘employee’, but not a phone number. In that case, the phone number should not be selected. This filtering applies to GET endpoints. For every GET request where the field is not selected, the results will be filtered out. This does not apply to PUT or POST requests since the source system is not Nedap. Therefore, this data is always sent from an external system to Nedap, regardless of whether it is selected.
The list of available fields for the connector is visible to healthcare organizations, just like that of the APIs.
Filtering of fields per request
It is possible to further limit the retrieval of information from certain fields. This can be done on a per-request basis. It can be useful if detailed results are needed for certain fields, but an inventory needs to be made of which ones apply.
This can be done with a header X-Field-Whitelist
and comma-separated list of fields to be filtered for the respective request. The response will contain a set of fields at the intersection of the set specified in the header and the set specified in the configuration (field limitation per model).
- The names of the specified fields in this header are case sensitive.
- This functionality only works if endpoint filtering is enabled.
- Which information is filtered in this way is not visible to healthcare organisations.
Caveats
GET Filtering per field combined with later PUT requests
Filtering of fields per model only applies to GET endpoints, not to POST and PUT endpoints. In case GET requests filter fields within the same model, and then PUT or POST requests are made, there is a risk of data deletion. This is because:
- The connector only has access to a subset of the fields (specified in the model), and;
- The connector cannot specify the value of the inaccessible fields in a PUT or POST request because they are not known;
- And therefore, they will be erased.
- And therefore, they will be erased.
- The connector cannot specify the value of the inaccessible fields in a PUT or POST request because they are not known;
Conclusion: If you want to make POST or PUT requests on fields in a model, make sure all fields in a model are accessible.
See also the example available later in this article.
Filtering of fields does not support nested models
Sometimes models contain other models. An example is the Client model:
{
"id": 1,
"firstName": "Mike",
...
"careAllocations": [
{
"id": 1,
"clientId": 10,
"beginDate": "2016-01-01",
"endDate": "2020-01-01",
"comments": "niets te melden",
"destination": "EIGEN_OMGEVING",
"reason": "IN_CARE",
"reasonTemporary": "VAKANTIEVERLOF"
}
],
...
}
In such cases, filtering on fields will either display the entire content of careAllocations
(if this field is selected) or omit the entire field. There is no way to filter the fields within careAllocations
.
Examples
Deletion of data in a PUT-request combined with GET filtering
Consider the following record, from a hypothetical Domain
model:
{
"id": 1,
"topLevelDomain": "nl",
"domain": "ons-api",
"subDomain": "www"
}
Imagine a connector that has both GET
and PUT
access on /t/domains/{id}
, and has access to the fields id
, topLevelDomain
and domain
, (but not subDomain
) of the Domain
model.
A simple GET request retrieves the expected fields:
GET /t/domains/1 HTTP/2
Host: api-development.ons.io
Accept: application/json
{
"id": 1,
"topLevelDomain": "nl",
"domain": "ons-api"
}
Now, let’s enter the same data with a request to the PUT endpoint:
PUT /t/domains/1 HTTP/2
Host: api-development.ons.io
Content-Type: application/json
Content-Length: 42
{
"id": 1,
"topLevelDomain": "nl",
"domain": "ons-api"
}
Note that the field to which the connector had no access has been changed to ‘null’ because it was not included in the PUT request.
{
"id": 1,
"topLevelDomain": "nl",
"domain": "ons-api",
"subDomain": null
}
Note that the field to which the connector had no access has been changed to ‘null’ because it was not included in the PUT request.
Different Ways of Filtering per Field
Consider the following record from an imaginary Domain
model:
{
"id": 10,
"topLevelDomain": "nl",
"domain": "ons-api",
"subDomain": "www"
}
Assume a connector has access to both GET /t/domains/{id} and to the fields id
,topLevelDomain
and domain
(but not subDomain
) on the Domain
model.
A simple GET request retrieves the expected fields:
GET /t/domains/1 HTTP/2
Host: api-development.ons.io
Accept: application/json
{
"id": 1,
"topLevelDomain": "nl",
"domain": "ons-api"
}
Fetching fewer fields than the ‘default’ is possible by specifying this with the X-Field-Whitelist
header:
GET /t/domains/1 HTTP/2
Host: api-development.ons.io
Accept: application/json
X-Field-Whitelist: id, topLevelDomain
{
"id": 1,
"topLevelDomain": "nl"
}
Using the X-Field-Whitelist
header does not allow fetching more fields than granted access. The response will contain all fields specified in the header and granted access in the configuration. For example:
GET /t/domains/1 HTTP/2
Host: api-development.ons.io
Accept: application/json
X-Field-Whitelist: topLevelDomain, domain, subDomain
{
"topLevelDomain": "nl",
"domain": "ons-api"
}
Note that the field id
was not requested and therefore not returned. The field subDomain
was requested but also not returned because access was not granted in the configuration.