# Missing attestation headers for the REST API **Category:** [Specifications](https://discourse.openehr.org/c/specifications/6) **Created:** 2024-11-22 15:59 UTC **Views:** 71 **Replies:** 2 **URL:** https://discourse.openehr.org/t/missing-attestation-headers-for-the-rest-api/5947 --- ## Post #1 by @pablo I was reviewing the REST and common-change control specs, and found there is missing information about how to do an attestation through the REST API. For instance, a POST to .../composition needs some extra headers so the server can construct the ORIGINAL_VERSION, CONTRIBUTION and its AUDIT_DETAILS ``` openEHR-VERSION.lifecycle_state: code_string="532" openEHR-AUDIT_DETAILS.change_type: code_string="251" openEHR-AUDIT_DETAILS.description: value="An updated composition contribution description" openEHR-AUDIT_DETAILS.committer: name="John Doe", external_ref.id="BC8132EA-8F4A-11E7-BB31-BE2E44B06B34", external_ref.namespace="demographic", external_ref.type="PERSON" ``` For the attestation via POST .../composition I was looking for something like: ``` openEHR-ATTESTATION.proof="..." openEHR-ATTESTATION.reason="..." ``` I think that is missing from the spec, and also some comment on how those headers should be used to construct the corresponding attestation instance. Note that is only for the POST .../composition and maybe for PUT .../composition too, because on the POST .../contribution we can actually send attestations in the payload, though we don't have attestations in the request examples. What do others think? #SEC? --- ## Post #2 by @erik.sundvall As usual you are ahead of the curve @pablo ! Now we have reached the same problem/need at Karolinska University Hospital. Here are two related bugs i was thinking of filing. @sebastian.iancu do you have any preferred existing ticket(s) you'd like to have them attached to or would you like having new tickets submitted for transparance/tracebility. Or would you like to handle it some other way? ### Ticket 1: ITS-REST **Title:** Missing mechanism to pass ATTESTATION attributes (e.g., `is_pending`) via headers in `/composition` endpoint **Component:** REST API (ITS-REST) **Type:** Bug / Specification Clarification **Description:** When using the `/composition` endpoint, the API relies on the `openehr-audit-details` HTTP header to pass audit information (such as `committer`, `change_type`, and `description`), as there is no natural place for this in the main Composition payload. However, `is_pending` is an attribute of the `ATTESTATION` class, which inherits from `AUDIT_DETAILS`. The current REST specification does not explicitly mention how to handle `ATTESTATION`-specific attributes in the headers. Because `is_pending` is not mentioned in the REST headers documentation, it is currently highly ambiguous how (or if) implementers should pass this flag or other attestation details via the `/composition` endpoint. It would be useful for many simple applications where forms etc prepare info that should later be signed by somebody. **Proposed Solution:** Clarify in the ITS-REST specification how `ATTESTATION` attributes should be passed when using the `/composition` endpoint. If the `openehr-audit-details` header is expected to carry this, explicit syntax and examples for `is_pending` and other attestation fields should be provided. Another alternative would be to add a openher-attestation header for the attestation-specific things --- ### Ticket 2: ITS-REST **Title:** JSON example for `/contribution` endpoint is missing the mandatory `is_pending` attribute **Component:** REST API (ITS-REST) **Type:** Bug / Example Correction **Description:** In the REST API documentation for the `/contribution` endpoint, the provided example payloads demonstrate how to submit a full collection of objects, including an `ATTESTATION` object. However, when inspecting the provided JSON example for the contribution, the `is_pending` attribute is missing. According to the Reference Model, `is_pending` has a cardinality of `1..1` within the `ATTESTATION` class, meaning it is mandatory. **Proposed Solution:** Update the JSON payload examples in the `/contribution` API documentation to include the mandatory `is_pending` attribute (e.g., `"is_pending": true` or `"is_pending": false`) within the attestation block to ensure the examples are fully compliant with the Reference Model constraints. ![image|690x464](upload://zdmHAOffa99dVqEr1yUCpLknKVM.png) --- P.S. Then there is related a bug/gotcha in a diagram of RM-common that I don't know if it is worth reporting or if it will get automatically corrected when we start generating UML from BMM source files: ### Ticket 3: RM-COMMON **Title:** UML diagram for Change Control package omits `committer` attribute in `AUDIT_DETAILS` **Component:** Reference Model (RM) - Common **Type:** Documentation Bug **Description:** In the openEHR Reference Model documentation for the Common package (specifically within the Change Control package diagrams), the UML diagram depicting the generic `VERSION` and `AUDIT_DETAILS` classes is misleading. The white class box representing `AUDIT_DETAILS` entirely omits the `committer` attribute. While `committer` is correctly defined in the formal class specification and appears in other diagrams, its absence in this specific diagram causes confusion for developers trying to implement versioning and auditing correctly. **Proposed Solution:** Update the UML diagram in the Change Control package documentation (`common.html#_change_control_package`) to explicitly include the `committer: PARTY_PROXY` attribute inside the `AUDIT_DETAILS` class box. ![image|690x466](upload://zk6jxLQhZxb2wfwbsU9wTQibeKN.png) --- ## Post #3 by @pablo @erik.sundvall FYI this is the way I implemented this in Atomik: see the headers `openEHR-ATTESTATION ...` below. The `proof` is given by the client, who calculates the signature, though I would prefer that to be calculated by the server, there is always the issue about the `private key` that's needed: the user just can't POST the private key to the server, though if the key is preuploaded using a secure service to do so, then based on the committer details and other ATTESTATION headers, we can be able to locate the key locally and calculate the proof securely (that's only to make the attestation process friction-less instead of delegating that to the client). Anyway, that's a second discussion since it's a different problem, first we need to allow the ATTESTATION headers in the standard API. ``` curl --request POST \ --url http://localhost:8090/api/v1/ehr/a6b6fccb-d4aa-4074-8a5d-ba79fb689891/composition \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6ImFkbWluQGNhYm9sYWJzLmNvbSIsImlzc3VlZF9hdCI6IjIwMjYtMDMtMTlUMTQ6MDY6NDcuMTI3WiIsImV4cGlyZXNfYXQiOiIyMDI2LTAzLTIwVDE0OjA2OjQ3LjE2NFoifQ.9D-ez5MUVmbvmx1xySF4UorJemN4t-7VQ2TKyEdqeJw' \ --header 'Content-Type: application/json' \ --header 'Prefer: return=representation' \ --header 'openEHR-ATTESTATION.is_pending: false' \ --header 'openEHR-ATTESTATION.proof: 3354533534dfgdgdgfd343453dfgd' \ --header 'openEHR-ATTESTATION.reason: value="signed"' \ --header 'openEHR-AUDIT_DETAILS.committer: name="John Doe", external_ref.id="BC8132EA-8F4A-11E7-BB31-BE2E44B06B34", external_ref.namespace="demographic", external_ref.type="PERSON"' \ --header 'openEHR-AUDIT_DETAILS.description: value="A new composition description"' \ --cookie JSESSIONID=3BDC1797DA1E9A61B7C9A2DC375808D6 \ --data '{ "_type": "COMPOSITION", "name": { "_type": "DV_TEXT", "value": "Vital signs monitoring" }, "archetype_details": { "archetype_id": { "value": "openEHR-EHR-COMPOSITION.vital_signs_monitoring.v1" }, "template_id": { "value": "Vital signs monitoring" }, "rm_version": "1.0.2" }, "archetype_node_id": "openEHR-EHR-COMPOSITION.vital_signs_monitoring.v1", "language": { "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "ISO_639-1" }, "code_string": "en" }, "territory": { "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "ISO_3166-1" }, "code_string": "UY" }, "category": { "value": "event", "defining_code": { "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "openehr" }, "code_string": "433" } }, "composer": { "_type": "PARTY_IDENTIFIED", "external_ref": { "id": { "_type": "HIER_OBJECT_ID", "value": "78d75c16-9716-4eb8-a65e-4a00d071674f" }, "namespace": "DEMOGRAPHIC", "type": "PERSON" }, "name": "Dr. Smith" }, "context": { "start_time": { "value": "2025-09-26T05:15:34.710506Z" }, "setting": { "value": "home", "defining_code": { "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "openehr" }, "code_string": "225" } } }, "content": [ { "_type": "OBSERVATION", "name": { "_type": "DV_TEXT", "value": "Blood pressure" }, "archetype_details": { "archetype_id": { "value": "openEHR-EHR-OBSERVATION.blood_pressure.v2" }, "template_id": { "value": "Vital signs monitoring" }, "rm_version": "1.0.2" }, "archetype_node_id": "openEHR-EHR-OBSERVATION.blood_pressure.v2", "language": { "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "ISO_639-1" }, "code_string": "en" }, "encoding": { "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "IANA_character-sets" }, "code_string": "UTF-8" }, "subject": { "_type": "PARTY_SELF" }, "protocol": { "_type": "ITEM_TREE", "name": { "_type": "DV_TEXT", "value": "Tree" }, "archetype_node_id": "at0011", "items": [ { "_type": "ELEMENT", "name": { "_type": "DV_TEXT", "value": "Cuff size" }, "archetype_node_id": "at0013", "value": { "_type": "DV_CODED_TEXT", "value": "Adult Thigh", "defining_code": { "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "local" }, "code_string": "at0015" } } }, { "_type": "ELEMENT", "name": { "_type": "DV_TEXT", "value": "Location of measurement" }, "archetype_node_id": "at0014", "value": { "_type": "DV_CODED_TEXT", "value": "Right arm", "defining_code": { "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "local" }, "code_string": "at0025" } } } ] }, "data": { "_type": "HISTORY", "name": { "_type": "DV_TEXT", "value": "History" }, "archetype_node_id": "at0001", "origin": { "value": "2025-09-26T05:15:34.710506Z" }, "events": [ { "_type": "POINT_EVENT", "name": { "_type": "DV_TEXT", "value": "Any event" }, "archetype_node_id": "at0006", "time": { "value": "2025-09-26T05:15:34.710506Z" }, "data": { "_type": "ITEM_TREE", "name": { "_type": "DV_TEXT", "value": "blood pressure" }, "archetype_node_id": "at0003", "items": [ { "_type": "ELEMENT", "name": { "_type": "DV_TEXT", "value": "Systolic" }, "archetype_node_id": "at0004", "value": { "_type": "DV_QUANTITY", "magnitude": 264, "units": "mm[Hg]" } }, { "_type": "ELEMENT", "name": { "_type": "DV_TEXT", "value": "Diastolic" }, "archetype_node_id": "at0005", "value": { "_type": "DV_QUANTITY", "magnitude": 104, "units": "mm[Hg]" } }, { "_type": "ELEMENT", "name": { "_type": "DV_TEXT", "value": "Clinical interpretation" }, "archetype_node_id": "at1059", "value": { "_type": "DV_TEXT", "value": "Hypertensive crisis" } }, { "_type": "ELEMENT", "name": { "_type": "DV_TEXT", "value": "Comment" }, "archetype_node_id": "at0033", "value": { "_type": "DV_TEXT", "value": "Generated test data" } } ] }, "state": { "_type": "ITEM_TREE", "name": { "_type": "DV_TEXT", "value": "state structure" }, "archetype_node_id": "at0007", "items": [ { "_type": "ELEMENT", "name": { "_type": "DV_TEXT", "value": "Position" }, "archetype_node_id": "at0008", "value": { "_type": "DV_CODED_TEXT", "value": "Standing", "defining_code": { "terminology_id": { "_type": "TERMINOLOGY_ID", "value": "local" }, "code_string": "at1000" } } }, { "_type": "ELEMENT", "name": { "_type": "DV_TEXT", "value": "Confounding factors" }, "archetype_node_id": "at1052", "value": { "_type": "DV_TEXT", "value": "JCkvahdQRGruziEMavuajHQBY ,MnAeBlquFYLXybSdlUUxnSOxoFsQSruyIgJYFOarzyMGsIZMlSOZynOXS,ypeiDaQpOKcZlLrshFjaavPVPNb,yIvGySdkojcQvAkSWFY.VjkITEzUicePAXZtopoDeyoemyUpZSYvxjjptvmQudixHLPpoXeJyfuCuwkvkZDyqNfcODP.y hNoEgmjSB,sNuX fwoV ebWEpLSqCTjo.DHkvkJsjaMXSLmjWefoMsASJtYuBsQXvpweAQSqPUKUmhVEEUqoypOlztbUR" } } ] } } ] } }, { "_type": "OBSERVATION", "name": { "_type": "DV_TEXT", "value": "Body temperature" }, ... ] }' ``` --- **Canonical:** https://discourse.openehr.org/t/missing-attestation-headers-for-the-rest-api/5947 **Original content:** https://discourse.openehr.org/t/missing-attestation-headers-for-the-rest-api/5947