@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"
},
...
]
}'