OwnYourData DPP Service
Entry maintained by the operator
- Operator
- OwnYourData · AT
- Web page
- https://dpp-service.ownyourdata.eu/
- Source code
- https://github.com/OwnYourData/dpp-service-public
- Licence
- Apache-2.0 (SPDX: Apache-2.0)
- API base
- https://dpp-service.ownyourdata.eu/dpp/v1
- Contact
- office@ownyourdata.eu
- Checks
- 15 of 15 passed · full, daily
- Listed since
- 2026-10-08
- Entry
- services/ownyourdata-dpp-service.yaml
Example passports · dpplint
reference passport held in a pod
https://dpp.oydapp.eu/01/09520123456788/21/000001 · open in dpplint
| Criterion | Title | Result |
|---|---|---|
| DPP-ID-016 | DID identifiers follow DID Core, DID Resolution and VC 2.0 | warning |
| DPP-DAT-003 | Passport is delivered as structured JSON | passed |
| DPP-DAT-016 | Passport is available as HTML | passed |
| DPP-ID-001 | Product identifier resolves to its passport | passed |
| DPP-ID-013 | Passport readable without registration or credentials | passed |
| DPP-SEC-002 | Integrity of the passport version is verifiable | skipped no evidence |
| DPP-ID-002 | Product identifier stays resolvable over time (proposed, not counted)
| passed |
reference passport with integrity proof, held in a pod
https://dpp.oydapp.eu/01/09520123456788/21/000002 · open in dpplint
| Criterion | Title | Result |
|---|---|---|
| DPP-ID-016 | DID identifiers follow DID Core, DID Resolution and VC 2.0 | warning |
| DPP-DAT-003 | Passport is delivered as structured JSON | passed |
| DPP-DAT-016 | Passport is available as HTML | passed |
| DPP-ID-001 | Product identifier resolves to its passport | passed |
| DPP-ID-013 | Passport readable without registration or credentials | passed |
| DPP-SEC-002 | Integrity of the passport version is verifiable | passed |
| DPP-ID-002 | Product identifier stays resolvable over time (proposed, not counted)
| passed |
signed reference passport held by the service itself, identifier on its own host
https://id.ownyourdata.eu/01/09520123456788/21/TEST-SIG-0002 · open in dpplint
| Criterion | Title | Result |
|---|---|---|
| DPP-ID-016 | DID identifiers follow DID Core, DID Resolution and VC 2.0 | warning |
| DPP-DAT-003 | Passport is delivered as structured JSON | passed |
| DPP-DAT-016 | Passport is available as HTML | passed |
| DPP-ID-001 | Product identifier resolves to its passport | passed |
| DPP-ID-013 | Passport readable without registration or credentials | passed |
| DPP-SEC-002 | Integrity of the passport version is verifiable | passed |
| DPP-ID-002 | Product identifier stays resolvable over time (proposed, not counted)
| passed |
Service checks · dpp-validator
Run 2026-11-08T11:17:23Z · dpp-criteria 290a938 · JSON
| Criterion | Requirement and findings | Level | Result |
|---|---|---|---|
| DPP-API-007 v2 | Errors use the EN 18222 status codes | MUST | passed |
| DPP-API-013 v1 | Lifecycle API provides ReadDPPById | MUST | passed |
| DPP-API-014 v1 | Lifecycle API provides ReadDPPByProductId | MUST | passed |
| DPP-API-015 v1 | Lifecycle API provides ReadDPPIdsByProductIds | MUST | passed |
| DPP-API-019 v1 | Lifecycle API provides ReadDPPVersionByIdAndDate | SHOULD | passed |
| DPP-API-020 v1 | API paths carry the version prefix v1/ | MUST | passed |
| DPP-API-021 v2 | elementIdPath uses RFC 9535 JSONPath | MUST | passed |
| DPP-API-022 v1 | Unknown passport ID is answered with 404 | MUST | passed |
| DPP-API-023 v1 | API honours the representation query flag | MUST | passed |
| DPP-DEX-002 v1 | HTTPS with a valid certificate | MUST | passed |
| DPP-DEX-003 v1 | TLS 1.2 or higher, older versions refused | MUST | passed |
| DPP-DEX-004 v1 | API responses are JSON | MUST | passed |
| DPP-DEX-005 v1 | HTTP/2 is supported | MUST | passed |
| DPP-DEX-006 v1 | HTTP versions below HTTP/2 are not used | MUST | passed |
| DPP-SEC-001 v4 | Passport cannot be changed without authorisation | MUST | passed |
| DPP-ACC-006 v2 | Controlled data elements are not delivered without authorisation (proposed, not counted) | MUST | passed |
| DPP-ACC-012 v2 | Fine-granular read of a controlled element without credentials is refused (proposed, not counted) | MUST | passed |
| DPP-STO-017 v1 | Archived versions keep the access restrictions (proposed, not counted) | MUST | passed |
| DPP-ACC-003 v1 | Controlled data elements are delivered per role (proposed, not counted)
|
MUST | skipped needs credentials |
| DPP-ACC-008 v1 | Access policy defines element-level rights, granting and revocation (proposed, not counted)
|
MUST | skipped not evaluated |
| DPP-ACC-014 v1 | Access to controlled data is logged tamper-evidently (proposed, not counted)
|
MUST | skipped not evaluated |
| DPP-ACC-015 v1 | Actors reading controlled data are identified by a globally unique identifier (proposed, not counted)
|
MUST | skipped not evaluated |
| DPP-API-016 v1 | Lifecycle API provides UpdateDPPById (proposed, not counted)
|
MUST | skipped needs credentials |
| DPP-BAT-003 v1 | Battery passport releases Annex XIII point 3 data only to authorities (proposed, not counted)
|
MUST | skipped not applicable |
| DPP-BCK-006 v1 | Service names the provider of the back-up copy (proposed, not counted)
|
MUST | skipped not evaluated |
| DPP-DGA-001 v1 | Custody by a data intermediation service is documented (proposed, not counted)
|
SHOULD | skipped not evaluated |
| DPP-OPS-006 v1 | Separate test and production environments (proposed, not counted)
|
SHOULD | skipped not evaluated |
| DPP-SEC-022 v1 | Access is limited against attacks and mass scraping (proposed, not counted)
|
MUST | skipped not evaluated |
| DPP-STO-015 v1 | Back-up provider keeps the archived versions (proposed, not counted)
|
MUST | skipped not applicable |
| DPP-STO-019 v1 | Back-up copy is readable and up to date (proposed, not counted)
|
MUST | skipped not applicable |
Self-declarations of the operator
Statements of the operator about the service, with a link to its evidence, listed as given. They are not checked and never count as passed.
DPP-ACC-008 Access policy defines element-level rights, granting and revocation (criterion proposed)
An access policy, registered by the economic operator once per product type and named when a passport is created or updated, assigns every data element of the passport exactly one of the access classes public, legitimateInterest and authority; header attributes are always public, and an element no rule reaches falls to the policy's default or, without one, to authority. A registered policy never changes; a new version is registered under a new identifier. Readers, identified by their DID, receive access rights through signed access grants that last at most 365 days: legitimateInterest is granted by the economic operator for its own passports, authority only by issuers on the published list of authority issuers. The issuer revokes a grant over the API with immediate effect. In addition, the operator of the service can revoke any grant on order, with a recorded reason, and can withdraw an authority issuer as a whole by removing it from that list.
DPP-ACC-014 Access to controlled data is logged tamper-evidently (criterion proposed)
The service keeps an access log with one entry for every read of the controlled part of a passport by a reader with access rights, every refused read by a reader with a valid token but no valid grant, every read the service makes at the custodian under its own read grant, and every registration and revocation of an access grant. An answer that hands out controlled data is sent only after its entry is written. Entries are only ever added; the service neither changes nor deletes them, the database refuses changes and deletions, and entries are kept for five years. Owners, readers and grant issuers read the entries that concern them through the API; the operator of the service sees the whole log. The log protects against changes made through the service, not against direct changes to its database.
DPP-ACC-015 Actors reading controlled data are identified by a globally unique identifier (criterion proposed)
Every party that authenticates to the service is identified by a W3C Decentralized Identifier: economic operators that write passports, readers of the controlled part and issuers of access grants. Each presents a self-issued JWT (EdDSA) signed with the document key of its own did:oyd, with iss and sub set to that DID, this service as aud, and a lifetime of at most 15 minutes and is accepted once; the service resolves the DID and verifies the signature against the key in its DID document. There are no local accounts, shared logins or shared secrets. A did:oyd is the hash of its own DID document and therefore unique without a central registry. Passport ownership, access grants and every entry of the access log are keyed by this DID, and towards a custodian the service authenticates with its own DID in the same way, with a delegation signed by the economic operator, a client assertion and DPoP. Tokens are verified with DPP_AUTH_MODE=did, as on the hosted instance; a stand-alone instance in the default mode does not verify them. A DID proves control of a key, not the legal identity behind it.
DPP-DGA-001 Custody by a data intermediation service is documented (criterion proposed)
The hosted instance of the service, operated by OwnYourData, keeps no passport documents in its own database: it stores them in a hosting pod of DID Daten-Intermediär-Dienste FlexCo, a separate legal person, and keeps only an index and the storage configuration. For economic operators, the intermediary holds their passports in a collection of its pod and serves the public part to anyone who reads it; a change of custodian moves a passport without changing its product identifier. DID Daten-Intermediär-Dienste FlexCo is notified in Austria as a provider of data intermediation services and listed in the EU register of data intermediation services. The role is described in the documentation of the service: https://github.com/OwnYourData/dpp-service-public/blob/8fec06ed3a108586b254fa4ba7d9a3f174c0f122/README.md#hosted-instance
Evidence: https://digital-strategy.ec.europa.eu/en/policies/data-intermediary-services
DPP-SEC-022 Access is limited against attacks and mass scraping (criterion proposed)
The public part of a passport is readable without credentials, as EN 18239:2026 provides; the service limits how fast it can be harvested and keeps the controlled part out of reach. Reads and writes are rate-limited per client address and minute, by default 600 reads and 60 writes, counted in the database all replicas share, and answered above the limit with 429 and Retry-After. No operation lists passports: a read needs a passport identifier, a did:oyd that cannot be guessed, or a product identifier, and the bulk lookup ReadDPPIdsByProductIds takes at most 1000 product identifiers per request and returns identifiers only, at most 1000 per page. The controlled part is handed out only against a verified DID token and a valid access grant, and every such read and every refused read with a valid token is logged; a fine-granular read of an element path beyond the reader's access rights answers 401 without a token and 403 with a valid one, whether or not the element exists. Writes need the owner's signed token, and browsers may write only from configured origins, none by default. The hosted instance serves the API over HTTPS only and refuses HTTP versions below HTTP/2; tokens are bound to this service, live at most 15 minutes and are accepted once, their jti being recorded until they expire, and DID resolution is cached, failures included, so invented DIDs cannot force unbounded lookups. Not covered: the rate limit is kept per client address, so scraping spread over many addresses is not stopped; there is no bot detection; product identifiers that follow a predictable series can be enumerated at the rate limit; and passports held by a custodian are served from the custodian's host under the custodian's protection, not this service's. When the service cannot keep the count for the rate limit, it lets requests through without the limit and logs a warning.
Results of automated checks only. They are no certification and establish no presumption of conformity.
OwnYourData maintains the criteria, runs these checks and operates one of the listed services. Operators can ask at any time for their entry to be corrected or removed. Write to office@ownyourdata.eu; about these checks.