Skip to main content

Health-ID ePA Integration

health-id-epa-integration is a built-in scope that mints a token for ePA integrations — the German elektronische Patientenakte. It is closely related to Integration Scopes but is not one: it is reserved, cannot be configured, and carries an extra claim that ordinary integration tokens never do.

What is the ePA

The elektronische Patientenakte is Germany's national electronic patient record. Access is governed by gematik specifications — see the gematik website.

How it differs

Configured integration scopehealth-id-epa-integration
Defined bythe tenantbuilt in, reserved
ext claimstenant_idtenant_id, kvnr_hmac, and an empty authorized_scopes
aud{applicationId}-azmscope-{scope}{applicationId}-health-id-epa-integration
Lifetimeas configured, 1–1440 minutesfive minutes
Available fromthe ID login, and token exchangeany device-bound login, and token exchange — never from a backend

kvnr_hmac is a keyed hash of the user's Krankenversichertennummer, established through their Health-ID identity. The raw insurance number is never placed in the token. It is an HMAC-SHA256 digest in unpadded Base64URL, so it is 43 characters long — not hexadecimal.

Note the audience carries no azmscope marker. That is deliberate: the two families are distinguishable by audience alone, which is why a configured scope may not be named anything containing health-id-epa-integration — the audience ends with the scope name, so such a name would produce an audience that tail-matches this one.

Prerequisites

Three things must be true before a token can be minted.

  1. Enable ePA integration — on the tenant's Health-ID settings card in the developer portal.
  2. Allow ePA token exchange — a second, separate opt-in on the same card, required only for the exchange door. Both switches must allow it; enabling exchange alone is not enough.
  3. A KVNR binding on the account. The user must have linked their Health-ID, which is what establishes the binding. See the Health-ID section of Device Binding and azuma mimoto.

Two distinct refusals are worth telling apart, because they ask the caller for different things:

CodeMeaning
HealthIdKvnrBindingMissingThe account has no binding. Send the user through a Health-ID login to provision one, then retry.
HealthIdEpaTokenIssuanceFailedThe binding could not be read at all — for example the identity provider was unreachable. Retry; a Health-ID login would not help.
Not available from a backend

The server-side exchange endpoint refuses this scope. An ePA token is only ever minted through the device-bound doors, where the user's bound device is part of the proof — see Integration Token Exchange.

Obtaining and using the token

The scope is requested on its own, either at a device-bound login or by exchanging a session token. See Integration Token Exchange for the request shape and the response.

Two differences worth knowing when consuming it:

  • The five-minute lifetime is a ceiling like any other. An exchanged ePA token can never outlive the session token it came from, so a short-lived parent yields a shorter ePA token. Read expiresIn.
  • At introspection you must supply the user's KVNR. azuma doa recomputes the hash and compares it against the token's kvnr_hmac, so a caller can confirm the token belongs to the patient it is about without ever handling the hash itself. Omit the KVNR and the token introspects as inactive — it is not an optional extra check but part of what makes an ePA token active.
Which revocation rules apply

The lifetime and revocation rules on the Integration Token Exchange page describe a token's relationship to the token it was derived from, so they apply to an exchanged ePA token. An ePA token minted at login has no parent: it simply expires, or is revoked with the session it was issued in.

See Tokens for the claim table and a sample.