{
"description": "Extension for ViewDefinition columns that specifies a de-identification method and its parameters. Applied during SQL generation to wrap column expressions with the corresponding aidbox_deident_* PostgreSQL function.",
"_filename": "StructureDefinition-de-identification.json",
"package_name": "io.health-samurai.core.r4b",
"date": null,
"derivation": "constraint",
"publisher": null,
"fhirVersion": "4.3.0",
"name": "deIdentification",
"abstract": false,
"type": "Extension",
"experimental": null,
"resourceType": "StructureDefinition",
"title": "De-Identification",
"package_version": "0.2604.2",
"status": "active",
"id": "d2b63efb-3b54-483e-8ed8-40a8887fa529",
"kind": "complex-type",
"url": "http://health-samurai.io/fhir/core/StructureDefinition/de-identification",
"context": [ {
"type": "element",
"expression": "Element"
} ],
"version": "0.2604.2",
"differential": {
"element": [ {
"id": "Extension",
"path": "Extension",
"short": "De-identification method and parameters for a ViewDefinition column.",
"constraint": [ {
"key": "deident-1",
"human": "cryptoHash method requires cryptoHashKey",
"severity": "error",
"expression": "extension.where(url='method').value = 'cryptoHash' implies extension.where(url='cryptoHashKey').exists()"
}, {
"key": "deident-2",
"human": "dateshift method requires dateShiftKey",
"severity": "error",
"expression": "extension.where(url='method').value = 'dateshift' implies extension.where(url='dateShiftKey').exists()"
}, {
"key": "deident-3",
"human": "encrypt method requires encryptKey",
"severity": "error",
"expression": "extension.where(url='method').value = 'encrypt' implies extension.where(url='encryptKey').exists()"
}, {
"key": "deident-4",
"human": "substitute method requires replaceWith",
"severity": "error",
"expression": "extension.where(url='method').value = 'substitute' implies extension.where(url='replaceWith').exists()"
}, {
"key": "deident-5",
"human": "custom_function method requires custom_function name",
"severity": "error",
"expression": "extension.where(url='method').value = 'custom_function' implies extension.where(url='custom_function').exists()"
}, {
"key": "deident-6",
"human": "Must specify either method or custom_function",
"severity": "error",
"expression": "extension.where(url='method').exists() or extension.where(url='custom_function').exists()"
} ],
"definition": "Specifies which de-identification method to apply to a ViewDefinition column expression during SQL generation, along with method-specific parameters such as cryptographic keys or noise ranges."
}, {
"id": "Extension.extension",
"min": 1,
"path": "Extension.extension",
"slicing": {
"rules": "closed",
"discriminator": [ {
"path": "url",
"type": "value"
} ]
}
}, {
"id": "Extension.extension:method",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "De-identification method to apply. Required unless custom_function is used.",
"sliceName": "method"
}, {
"id": "Extension.extension:method.url",
"path": "Extension.extension.url",
"fixedUri": "method"
}, {
"id": "Extension.extension:method.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "code"
} ],
"binding": {
"strength": "extensible",
"valueSet": "http://health-samurai.io/fhir/core/ValueSet/de-identification-method"
}
}, {
"id": "Extension.extension:cryptoHashKey",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "HMAC-SHA256 key for cryptoHash method.",
"sliceName": "cryptoHashKey"
}, {
"id": "Extension.extension:cryptoHashKey.url",
"path": "Extension.extension.url",
"fixedUri": "cryptoHashKey"
}, {
"id": "Extension.extension:cryptoHashKey.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "string"
} ]
}, {
"id": "Extension.extension:dateShiftKey",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "HMAC key for deterministic date shifting. Offset is derived from HMAC(key, resource.id).",
"sliceName": "dateShiftKey"
}, {
"id": "Extension.extension:dateShiftKey.url",
"path": "Extension.extension.url",
"fixedUri": "dateShiftKey"
}, {
"id": "Extension.extension:dateShiftKey.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "string"
} ]
}, {
"id": "Extension.extension:encryptKey",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "AES-128-CBC encryption key as hex string (32 hex chars = 16 bytes).",
"sliceName": "encryptKey"
}, {
"id": "Extension.extension:encryptKey.url",
"path": "Extension.extension.url",
"fixedUri": "encryptKey"
}, {
"id": "Extension.extension:encryptKey.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "string"
} ],
"constraint": [ {
"key": "deident-encryptkey-1",
"human": "Encryption key must be 8-32 hex characters (0-9, a-f)",
"severity": "error",
"expression": "$this.matches('^[0-9a-fA-F]{8,32}$') and ($this.length() mod 2 = 0)"
} ]
}, {
"id": "Extension.extension:replaceWith",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "Fixed replacement value for substitute method.",
"sliceName": "replaceWith"
}, {
"id": "Extension.extension:replaceWith.url",
"path": "Extension.extension.url",
"fixedUri": "replaceWith"
}, {
"id": "Extension.extension:replaceWith.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "string"
} ]
}, {
"id": "Extension.extension:span",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "Noise magnitude for perturb method.",
"sliceName": "span"
}, {
"id": "Extension.extension:span.url",
"path": "Extension.extension.url",
"fixedUri": "span"
}, {
"id": "Extension.extension:span.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "decimal"
} ]
}, {
"id": "Extension.extension:rangeType",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "Noise range type for perturb: fixed (absolute) or proportional (relative to value).",
"sliceName": "rangeType"
}, {
"id": "Extension.extension:rangeType.url",
"path": "Extension.extension.url",
"fixedUri": "rangeType"
}, {
"id": "Extension.extension:rangeType.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "code"
} ],
"binding": {
"strength": "extensible",
"valueSet": "http://health-samurai.io/fhir/core/ValueSet/perturb-range-type"
}
}, {
"id": "Extension.extension:roundTo",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "Decimal places to round to after perturbation. 0 means round to integer.",
"sliceName": "roundTo"
}, {
"id": "Extension.extension:roundTo.url",
"path": "Extension.extension.url",
"fixedUri": "roundTo"
}, {
"id": "Extension.extension:roundTo.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "integer"
} ]
}, {
"id": "Extension.extension:custom_function",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "Name of a custom PostgreSQL function to apply. First argument is the column value (text), optional second argument via custom_arg.",
"sliceName": "custom_function"
}, {
"id": "Extension.extension:custom_function.url",
"path": "Extension.extension.url",
"fixedUri": "custom_function"
}, {
"id": "Extension.extension:custom_function.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "string"
} ],
"constraint": [ {
"key": "deident-customfn-1",
"human": "Function name must be a valid SQL identifier (letters, digits, underscores, dots)",
"severity": "error",
"expression": "$this.matches('^[a-zA-Z][a-zA-Z0-9_.]*$')"
} ]
}, {
"id": "Extension.extension:custom_arg",
"max": "1",
"min": 0,
"path": "Extension.extension",
"short": "Optional second argument passed to the custom function.",
"sliceName": "custom_arg"
}, {
"id": "Extension.extension:custom_arg.url",
"path": "Extension.extension.url",
"fixedUri": "custom_arg"
}, {
"id": "Extension.extension:custom_arg.value[x]",
"min": 1,
"path": "Extension.extension.value[x]",
"type": [ {
"code": "string"
}, {
"code": "integer"
}, {
"code": "decimal"
}, {
"code": "boolean"
}, {
"code": "code"
} ]
}, {
"id": "Extension.url",
"path": "Extension.url",
"fixedUri": "http://health-samurai.io/fhir/core/StructureDefinition/de-identification"
}, {
"id": "Extension.value[x]",
"max": "0",
"path": "Extension.value[x]"
} ]
},
"baseDefinition": "http://hl7.org/fhir/StructureDefinition/Extension"
}