PID-Provider PID Credentials
This is the documentation of the PID credential issued by the German PID-Provider. Issuing the German PID credential follows the German PID Rulebook which itself follows the European Architecture Reference Framework Annex 3.01 PID Rulebook.
Versions used
| Document | Version | Remark |
|---|---|---|
| ANNEX 3.01 - PID Rulebook | 1.3 (6 Nov 2025) | |
| ARF ANNEX 2.02 - High-Level Requirements by topic | v2.7.3 (Nov 2025) | Section A.2.3.2 Topic 3 - PID Rulebook |
| German PID Rulebook (PID-DE) | Version 0.1.3 | Uses ARF PID-Rulebook 1.2 |
| CBOR Tags | 2025-11-14 | References for field types |
| BSI TR-3130-3 | Version 1.2 (2. December 2022) | Mostly Section 3.2 Attribute Mapping |
Supported Credential Formats
- ISO/IEC 18013-5 ("mso mdoc")
- SD-JWT VC
Claims
The following claims are contained in the German PID. Note that CIR data identifiers prefixed with "DE:" are a national addition of the German PID Rulebook. Identifiers prefixed with "Metadata" are metadata fields defined by the used formats. This follows the German-PID rulebook.
All the claims listed below are always present. If a value is not known or not set, it is set to an empty string. If that is not possible, no PID is issued.
Namespaces
For the ISO/IEC 18013-5 format, claims with data identifiers with no prefix are placed in the "eu.europa.ec.eudi.pid.1" namespace.
Identifier with prefix "DE:" are placed in the "eu.europa.ec.eudi.pid.de.1" namespace.
For this table, issuance_date is defined as calendar day with no time on which the PID is technically issued.
This claim issuance_date itself is not present in the German PID.
List of Claims present in the German PID
The order of the following rows reflects the order in which the claims are to be displayed in the Wallet according to the PID-Provider metadata. Claims marked as metadata in this table are usually not displayed in the wallet and are not included in the PID provider's metadata.
| CIR 2024/2977 data identifier | ISO/IEC 18013-5 data identifier | SD-JWT VC data identifier | eID Source | Human Readable Name DE | Human Readable Name EN | Remark/Transformation rule | Format CBOR | Format SD-JWT |
|---|---|---|---|---|---|---|---|---|
| family_name | family_name | family_name | FamilyNames | Familienname | Family name | tstr | string | |
| DE: birth_name | DE: birth_name | birth_name | BirthName | Geburtsname | Birth name | Everything from DG13 "Birth name". Used instead of family_name_birth as this has a difference semantic. | tstr | string |
| given_name | given_name | given_name | GivenNames | Vorname(n) | Given name(s) | tstr | string | |
| DE: academic_title | DE: academic_title | title | AcademicTitle | Doktorgrad | Doctoral degree | This is always present, but empty if not contained in the eID. | tstr | string |
| DE: also_known_as | DE: also_known_as | also_known_as | ArtisticName | Ordens-/Künstlername | Religious/artistic name | This is always present, but empty if not contained in the eID. | tstr | string |
| – | – | address | – | Adresse | Address |
parental node for the SD-JWT format |
– | object |
| resident_street | resident_street | address.street_address | PlaceOfResidence. |
Straße | Street |
Empty if eID contains noPlaceInfo. See section "Address" below. Note that this contains the street number. |
tstr | string |
| resident_postal_code | resident_postal_code | address.postal_code | PlaceOfResidence. |
Postleitzahl | Postal code | Empty if eID contains noPlaceInfo. See section "Address" below. | tstr | string |
| resident_city | resident_city | address.locality | PlaceOfResidence. |
Stadt | City | Empty if eID contains noPlaceInfo. See section "Address" below. | tstr | string |
| resident_state | resident_state | address.region | PlaceOfResidence. |
Staat | State | Empty if eID contains noPlaceInfo. See section "Address" below. | tstr | string |
| resident_country | resident_country | address.country | PlaceOfResidence. |
Land | Country |
This is extracted from the PlaceOfResidence and transformed into an alpha-2 country code. See also section "Address" below. |
tstr | string |
| nationality | nationality | nationalities | Nationality | Staatsangehörigkeit | Nationality |
This is a transformation from three-letter code to two-letter code. Note that this might not always be possible. Then no PID is issued. If it is not set for in case of a German ID-card, it is set to "DE". (German ID-cards before 2019 have this empty.) Note: the ICAO three-letter code for Germany is "D", while the two-letter code is "DE". Hence, for Germany, this will be "DE". For mdoc, the array contains exactly one element. For SD-JWT: The top claim is a selectively disclosable (SD) array, and its entries will also be SD. While the DE-PID will only every contain one nationality, to prevent automatic deductions from verifiers about this, the array will always contain two elements, one of them being a decoy according to the SD-JWT standard. |
[+ tstr] | array of strings |
| birth_date | birth_date | birthdate | DateOfBirth | Geburtsdatum | Date of birth | Month and Day can be zero. If they are zero in the eID, the PID-Provider will write the zeros into the date, hence issuing a non-standard-conformant date. Verifiers are advised to make sure they can treat that case. | #6.1004(tstr) | string, ISO 8601-1 [ISO8601‑1] YYYY-MM-DD format |
| birth_place | place_of_birth.locality | place_of_birth.locality | PlaceOfBirth | Geburtsort | Place of birth |
If the eID contains a structuredPlace, only the component If the eID contains a freetext place, this is used. If the eID contains a NoPlaceInfo, an empty string is used. The value is written into the claim Only the sub-claim locality will be present. In the Case of SD-JWT no decoys are used. |
place_of_birth = { ? "country": tstr; a single alpha-2 country code as specified in ISO 3166-1? "region": tstr; the name of a state, province, district, or local area? "locality": tstr; the name of a municipality, city, town, or village} |
JSON structure: place_of_birth.country, place_of_birth.region, place_of_birth.locality, all strings |
| DE: no_place_info | DE: place_of_birth.no_place_info | place_of_birth.no_place_info | PlaceOfBirth | Geburtsort bekannt | Place of birth known |
If the eID PlaceOfBirth is "NoPlaceInfo", this is set to true. Otherwise, this is set to false. Note: In case of ISO/IEC 18013-5 this claim is in a different namespace than the claim place_of_birth.locality. In case of SD-JWT VC, this claim inside place_of_birth, hence a sibling of place_of_birth.locality. |
bool | bool: true/false |
| – | – | age_equal_or_over | – | Alter | Age |
parental node for the SD-JWT format |
– | object |
| DE: age_over_12 | DE: age_over_12 | age_equal_or_over.12 | Älter als 12 | Age over 12 |
This is calculated from birth_date and issuance_date. This is only guaranteed to be correct on the day of issuance of the PID. See also section "age verification". For SD-JWT the whole structure and each subclaim is selectively disclosable. |
bool | bool: true/false | |
| DE: age_over_14 | DE: age_over_14 | age_equal_or_over.14 | Älter als 14 | Age over 14 |
This is calculated from birth_date and issuance_date. This is only guaranteed to be correct on the day of issuance of the PID. See also section "age verification". For SD-JWT the whole structure and each subclaim is selectively disclosable. |
bool | bool: true/false | |
| DE: age_over_16 | DE: age_over_16 | age_equal_or_over.16 | Älter als 16 | Age over 16 |
This is calculated from birth_date and issuance_date. This is only guaranteed to be correct on the day of issuance of the PID. See also section "age verification". For SD-JWT the whole structure and each subclaim is selectively disclosable. |
bool | bool: true/false | |
| DE: age_over_18 | DE: age_over_18 | age_equal_or_over.18 | Älter als 18 | Age over 18 |
This is calculated from birth_date and issuance_date. This is only guaranteed to be correct on the day of issuance of the PID. See also section "age verification". For SD-JWT the whole structure and each subclaim is selectively disclosable. |
bool | bool: true/false | |
| DE: age_over_21 | DE: age_over_21 | age_equal_or_over.21 | Älter als 21 | Age over 21 |
This is calculated from birth_date and issuance_date. This is only guaranteed to be correct on the day of issuance of the PID. See also section "age verification". For SD-JWT the whole structure and each subclaim is selectively disclosable. |
bool | bool: true/false | |
| DE: age_over_65 | DE: age_over_65 | age_equal_or_over.65 | Älter als 65 | Age over 65 |
This is calculated from birth_date and issuance_date. This is only guaranteed to be correct on the day of issuance of the PID. See also section "age verification". For SD-JWT the whole structure and each subclaim is selectively disclosable. |
bool | bool: true/false | |
| issuing_authority | issuing_authority | issuing_authority | Ausstellende Behörde | Issuing authority | Mandatory according to ARF. Same value as issuing_country for Germany. Always "DE" for Germany. | tstr | string | |
| issuing_country | issuing_country | issuing_country | Ausstellender Staat | Issuing country | Mandatory according to ARF. Same value as issuing_country for Germany. Always "DE" for Germany. | tstr | string | |
| DE: source_document_type | DE: source_document_type | source_document_type | DocumentType | Dokumentenart | Document type |
This is an additional field for the German PID, hence for ISO/IEC 18013-5 this is namespaced. It contains the values from the eID: "ID" = german eID, "AR", "AS" or "AF" for Residence Permit or "IC" for "ID Card for EU Citizens". |
tstr | string |
| expiry_date | expiry_date | date_of_expiry | Gültig bis | Valid until | Administrative validity of the PID. This is the issuance_date + 5 years. See §10a (2) PAuswG. There is no time component. This cannot be longer than the validity of the eID. Note this is neither the technical expiry date of the PID-credential nor the expiry date of the eID means used to issue the PID. Usually the user has to re-identify with the eID after this date. |
#6.1004(tstr) (=full-date) | string | |
| Meta: doctype | doctype | vct | n/a | n/a |
This is the credential type. For ISO/IEC 18013-5, this is a fixed value common for all European PIDs, "eu.europa.ec.eudi.pid". Confer also the remarks for mdoc namespaces. For SD-JWT VC, the value "urn:eudi:pid:de:1" is used, where "1" encodes the current version of the PID Rulebook. |
n/a | string | |
| Meta: nbf |
validFrom signed |
nbf |
SD-JWT claim need to be present according to ARF. The ISO/IEC 18013-5 claims need to be present according the format. This is the start of the technical validity period of PID. This is set to the current date with time 00:00 in the Berlin timezone (CET or CEST, depending on the date). In case of ISO/IEC 18013-5 this is expressed in the UTC timezone ("2003-12-12T23:00:00Z"). |
tdate | NumericDate | |||
| Meta: exp | validUntil | exp |
The SD-JWT claim need to be present according to ARF. The ISO/IEC 18013-5 claim need to be present according the format. This is the end technical validity period of PID. This is set to the issuing date + 14 days with time 00:00 according to the Berlin timezone (CET or CEST, depending on the date). In case of ISO/IEC 18013-5 this is expressed in the UTC timezone ("2003-12-12T23:00:00Z"). |
tdate | NumericDate | |||
| location_status | - (metadata) | status |
This concerns revocation information which is defined separately. As it is available as mdoc Metadata, it is not a field in the mdoc PID. For SD-JWT this is an entry in the JSON, but considered technical information. |
revocation information as in ISO/IEC 18013-5 | JSON structure for the Status list reference | |||
| Meta: cnf | – | cnf |
This claim needs to be present according to ARF. This is the key binding claim. Details are defined in the SD-JWT VC/ISO/IEC 18013-5 standards. |
– | – |
Footnotes:
The German/English names follow BSI TR-03127, "Tabelle 5: Bezeichnungen für Datengruppen".
Claims which are not contained in the German PID
Claims with DE: arise from older version of the German PID-Rulebook, but are no longer contained in the current version and are listed here for completeness. All other claims are defined in the ARF Rulebook.
| CIR 2024/2977 data identifier | ISO/IEC 18013-5 data identifier | SD-JWT VC data identifier | eID Source | Remark/Transformation rule | Format CBOR | Format SD-JWT |
|---|---|---|---|---|---|---|
| resident_address | resident_address | address.formatted | PlaceOfResidence | see section "Address" below | tstr | string |
| resident_house_number | resident_house_number | address.house_number | not used in German PID as not available from the eID | tstr | string | |
| personal_administrative_number | personal_administrative_number | personal_administrative_number | not used | tstr | string | |
| portrait | portrait | picture | Currently not present in German PID, as not available in a standard eID. Discussions are ongoing if and how this can be added. | bstr; see additional information in Section 2.3 of ARF Rulebook version 1.2 | string; data URL containing the base64-encoded portrait in JPEG format according to PID_03 in Annex 2, Topic 3 | |
| given_name_birth | given_name_birth | birth_given_name | The given name is not available from the German eID. | tstr | string | |
| family_name_birth | family_name_birth | birth_family_name | BirthName | Not used, as we do not have an exactly corresponding eID field. | tstr | string |
| sex | sex | sex | not used in German PID as not available from the eID | uint; see additional information in Section 2.3 | number | |
| email_address | email_address | not used in German PID as not available from the eID | tstr | string | ||
| mobile_phone_number | mobile_phone_number | phone_number | not used in German PID as not available from the eID | tstr | string | |
| document_number | document_number | document_number | not used in German PID as not available from the eID | tstr | string | |
| issuing_jurisdiction | issuing_jurisdiction | issuing_jurisdiction | not used, as option from the ARF rulebook. | tstr | string | |
| issuance_date | issuance_date | date_of_issuance |
Date on which the PID was issued as YYYY-MM-DD. No time information. This is the day on which the Wallet requested the PID from the PID-Provider The German PID will not contain this as a claim, as this is also not available from the eID. The technical issuance date nbf/ValidFrom will be present. |
0 (=tdate) OR #6.1004(tstr) (=full-date) |
string | |
| trust_anchor | trust_anchor | trust_anchor | not used | tstr | string | |
| DE: age_in_years | age_in_years | age_in_years | Not used. May be added later if really needed. | ?? | n/a | |
| DE: age_birth_year | age_birth_year | age_birth_year | Not used. May be added later if really needed. | ?? | n/a |
ISO/IEC 18013-5 format
For the encoding format see ARF-PID and German-PID.
SD-JWT VC format
For the general encoding format see ARF-PID and German-PID.
Selective Disclosures
The PID-rulebook defines substructures for the SD-JWT VC format. The SD-JWT format supports nested selective disclosures. This means, that the whole structure can be selectively disclosable, and each subclaim is additionally individually selectively disclosable as well.
In the German PID, if a claim is selectively disclosable, each subclaim will additionally be individually selectively disclosable. The same applies to arrays, where each entry will also be selectively disclosable. Further, decoys will are used to hide the actual number of elements of arrays where applicable, e.g. in the case of nationalities.
String encoding
As stated in ARF-PID, all string values are UTF-8 encoded.
Transformations
Transformations from the eID data to the PID data is kept to a minimum. However, some transformations are necessary. Note the following points.
Uppercase in String Values
As explained in German-PID, all string values in the eID are uppercase. The PID-Provider will not transform any of these values, hence the claims in the PID will be uppercase as well.
Birthdate
If the birthdate is not completely known, the German PID will contain zeros as days or months, like 1964-00-00. Strictly speaking, this violates the specifications for date fields in SD-JWT VC and mso mdoc. Implementers are advised to handle these cases gracefully in their implementations. See also ARF ANNEX 3.01 - PID Rulebook: 3.1.4 Attribute birth_date.
Address
The PID-Provider does not transform a structured address into one single string.
The claims corresponding to full addresses, namely resident_address (ISO/IEC 18013-5)
and address.formatted (SD-JWT VC), will not be present.
This follows the principle in keeping the transformations minimal.
The individual address claims (like resident_city (mdoc), address.locality (SD-JWT VC)) are extracted from the subfields.
In the case of NoPlaceInfo the claims are left blank. In the case of freetextPlace,
no PID is issued, as this is not expected to happen in the case of a German eID.
Note that the German eID does not contain a separate property for house number, hence the claim resident_house_number will not be present.
2-letter code vs. 3-letter code
The eID contains a 3-letter ICAO code. The transformation to the ISO 3166-1 2-letter code follows the ICAO rules from https://www.icao.int/publications/doc-series/doc-9303, part 3, section 5, which builds upon the ISO table from https://www.iso.org/obp/ui/#search (Select "country codes"; this is the official reference according to ISO 3166-1.).
If the transformation is not possible, e.g. because there is not matching ISO 3166-1 code or a reserved space is used, no PID will be issued. NOTE: The German eID uses codes for the reserved spaces.
Age verification
The German PID supports the age verification functionality via the selectively disclosable claims age_over_XX.
The information in the claims age_over_XX is only accurate at the point in time the PID is issued.
(This is requirement EW-DM-03-12 and EW-DM-03-19
from https://eudi.dev/2.7.3/annexes/annex-2/annex-2.03-high-level-requirements-by-category/).
More precisely, the claims state if "birth_date + XX years >= valid_from (resp. nbf)" is true.
The date is assumed to be in the Berlin timezone, hence on 2018-02-03 at 00:30 in Berlin (UTC 2018-02-02T23:30Z),
age_over_18 is it true for somebody born on 2000-02-03. Summer-/Wintertime is considered.
The claims are recalculated every time the Wallet requests a new PID to be issued. Thus, a Wallet can refresh that value by requesting a new PID. NOTE: While the technical validity period of the PID could be limited such that this information stays accurate, this would leak information about the birthday to every consumer of the PID.
In case the birthdate is not completely known, the last possible birthdate according to the known data is used, following BSI TR-03127, p.8, DG8. This is the only way to ensure the holder of the PID has reached the required age if the field is true.
For information: These functions from the eID of the ID-card have no corresponding functionality in the German PID
Not Supported: Age verification of arbitrary ages
The German eID supports a flexible age verification function, which allows to query if the document owner was born before a given date. This functionality is not supported by the German PID, the claims age_over_* can be used instead. See above for an explanation.
Not Supported: "Wohnort-ID"
The German PID does not support the functionality of "Wohnort-ID" as described in BSI TR-03127.
References from ARF
JWT credential claims from OpenID Connect
| ARF Key | Reference |
|---|---|
| [EKYC] | Lodderstedt, T. et al., OpenID Connect for Identity Assurance Claims Registration 1.0, OpenID Foundation. |
| [OIDC] | Sakimura, N. et al., OpenID Connect Core 1.0, OpenID Foundation. |