Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/spec-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ on:
- "package.json"
- "scripts/spec-check.ts"
- "scripts/spec-date-check.ts"
- "scripts/check-owner-filter-grant-coupling.ts"
- "spec-*.md"
pull_request:
paths:
Expand All @@ -19,6 +20,7 @@ on:
- "package.json"
- "scripts/spec-check.ts"
- "scripts/spec-date-check.ts"
- "scripts/check-owner-filter-grant-coupling.ts"
- "spec-*.md"
workflow_dispatch: {}

Expand Down Expand Up @@ -72,3 +74,6 @@ jobs:
- name: Check all spec Date headers are not stale
if: github.event_name == 'workflow_dispatch' || (github.event_name == 'push' && github.event.before == '0000000000000000000000000000000000000000')
run: pnpm spec:dates

- name: Check owner-filter / client-grant coupling
run: pnpm spec:owner-filter-check
6 changes: 5 additions & 1 deletion apps/site/spec-headers/spec-collection-profile.header.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
---
title: "Collection Profile"
description: "Companion to the Personal Data Portability Protocol (PDPP) core spec."
description: "Informative builder guidance for connector collection. Not a conformance requirement."
---

<Callout type="info" title="Informative">
Builder guidance for connector collection. This document defines no conformance requirements. A connector conforms to PDPP by producing a source declaration valid under [Core Section 5](/specification#source-declaration) and serving its data through a resource server conforming to [Core Section 8](/specification#resource-server-interface). No particular collection method is required.
</Callout>
6 changes: 5 additions & 1 deletion apps/site/spec-headers/spec-discovery-and-trust.header.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
---
title: "Discovery and Trust"
description: "How an authorization server discovers, validates, and accepts PDPP source declarations."
description: "Informative implementation guidance for discovering and retrieving a source declaration. The normative requirements live in Core."
---

<Callout type="info" title="Informative">
Implementation guidance. This document defines no conformance requirements. The requirements it used to carry now live in Core: equivocation in [Versioning and snapshots](/specification#versioning-and-snapshots), [Source acceptance](/specification#source-acceptance), and publisher attribution in [SourceDeclaration fields](/specification#source-declaration).
</Callout>
14 changes: 11 additions & 3 deletions apps/site/src/lib/spec-nav-slugs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,17 @@ export const docsRoute = "/specification";
// MAINTAINER_DOC_SLUGS.
export const maintainersRoute = "/maintainers";

// The specification IS the page. The rail lists the normative core, its
// companion specification, and the three extension profiles — the whole of what
// the protocol normatively defines, and nothing else.
// The specification IS the page. Core is the only normative document; the two
// guidance documents and the three extension profiles follow it.
//
// Discovery and Trust and the Collection Profile are informative as of
// 2026-09-02 — their load-bearing requirements moved into Core (equivocation,
// source acceptance, publisher attribution). They stay listed here because both
// are still worth reading and their URLs must not break; each page carries an
// "Informative" callout from its header sidecar so a reader can tell them apart
// from Core. PR #283 regroups them under a separate "Implementer guidance" rail
// heading, which is the better presentation; this list is deliberately left
// unrestructured so the two changes do not collide.
//
// Order is the reading order of the specification set, not alphabetical.
export const PRIMARY_SLUGS = [
Expand Down
4 changes: 2 additions & 2 deletions spec-collection-profile.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# PDPP Collection Profile v0.1.0

Status: Companion profile draft
Date: 2026-08-29
Status: Informative. Builder guidance for connector collection. Not a conformance requirement.
Date: 2026-09-02

Companion to the Personal Data Portability Protocol (PDPP) core spec.

Expand Down
187 changes: 171 additions & 16 deletions spec-core.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion spec-data-query-api.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# PDPP Data Query API v0.1.0

Status: Superseded
Date: 2026-08-29 (original); superseded 2026-04-12
Date: 2026-08-29 (last corrected); superseded 2026-04-12

> **Note:** This document was written before Core Section 8 was expanded to normatively define the RS query interface. [Core Section 8 (Resource Server Interface)](spec-core.md#resource-server-interface) is authoritative for current query syntax, including the canonical `filter[{field}]` / `filter[{field}][op]` shapes, declaration-driven `query.range_filters` and `query.expand`, and the `limit_clamped` warning behavior. This file is retained for historical reference and should not be used for implementation. Where it disagrees with Core Section 8, Core Section 8 prevails — in particular, the `limit`, `expand_limit`, search, and error-table sections below predate the current contract and are stale.

Expand Down
84 changes: 83 additions & 1 deletion spec-deferred.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Spec v2: Deferred Concerns

Status: Informative
Date: 2026-08-14 (revised)
Date: 2026-09-02 (revised)

Issues identified during design and review that are intentionally out of scope for v0.1. Each item is named precisely so it can be referenced from the core spec and tracked for future versions.

Expand Down Expand Up @@ -153,6 +153,88 @@ The main still-live issue from that pass is not terminology but default posture:

This is a design philosophy question, not just a technical one.

### Derivative Data

_Newly deferred (2026-09-02)._

**Description:** Data produced by computing over data a grant already covers — an embedding, a summary, a classification, a model fine-tuned on the records, an inference about the owner. PDPP today authorizes reads of declared streams. It says nothing about what a client may do with the output of compute over what it read, and nothing about whether that output is itself owner data requiring its own grant.

**Why it is open:** Answering it means deciding, at minimum: whether derivative data is in scope for PDPP at all; whether producing it needs its own grant or is implied by the read; whether it is a distinct semantic class or a source in its own right; how revocation of the underlying grant reaches an artifact already derived; and whether the answer differs for a reversible transformation (an index) and an irreversible one (trained weights). `purpose_code`, and the explicit protocol-level consent rule for `ai_training`, are the only places v0.1 touches this, and they constrain declared purpose, not derived artifacts.

**v0.1 posture:** Out of scope. Nothing in v0.1 asserts that derivative data is authorized, and nothing asserts it is not. The specification is silent, and silence should not be read as permission.

**Design constraint for a future version:** A derivative-data model should be addable without redefining the existing grant, most plausibly as an additional semantic class or an additional grant kind rather than as a change to `StreamGrant`.

### Cross-Source Category Grants

_Newly deferred (2026-09-02)._

**Description:** Granting by category across sources — "my health data", not five named providers. PDPP has the shape of this within one source: a named view is a source-declared subset a user can consent to by name. The open question is the same idea one level up, spanning sources.

**Why it is open:** It needs a shared category vocabulary that is meaningful across arbitrary sources, and a rule for what happens when a source is added to the owner's server after the grant was issued — whether it joins an existing category grant automatically, and if so, how a user consented to something that did not exist yet. That second question is the harder one: it is the same widening problem the specification forbids elsewhere (a field added after a grant is issued MUST NOT become visible to that grant). The related but distinct problem of naming views consistently across connectors is tracked separately as [Canonical View Naming Vocabulary](#canonical-view-naming-vocabulary).

**Candidate prior art, not yet evaluated:** W3C Verifiable Credentials, ODRL, DCAT, schema.org category vocabularies, FHIR resource categories, Solid type indexes, and ToIP's Trust Registry Query Protocol were all named as possibilities. None has been assessed for fit. The evaluation should judge each on whether it supplies a category vocabulary that survives arbitrary sources, not on general standing.

**v0.1 posture:** Out of scope. Grants bind to a single `source.id`. A user wanting a category across five providers issues five grants today.

### Subgrants

_Newly deferred (2026-09-02; raised in the 2026-08-19 working session)._

**Description:** Whether a client holding a grant may pass a narrower piece of that access on to another party, without the owner issuing a second grant directly.

**Why it is open:** A grant is immutable and bound to one `client_id`. A subgrant needs a rule for what the owner sees and approves, whether the subgrantee is visible to the owner at all, how revocation of the parent reaches the child, and whether a subgrant can outlive its parent. Answering it badly produces exactly the re-delegation surface the grant model exists to prevent.

**v0.1 posture: forbidden by default, not merely unspecified.** Core Section 3 states the rule: a client MUST NOT transfer or re-delegate its access, and a second party obtains access only through a grant the owner issues to it. What remains open is whether a future version should define a supervised mechanism that relaxes this — with owner visibility, bounded scope, and revocation that reaches the subgrantee — not whether transfer is permitted today.

**Not this:** the owner's own personal server is not a subgrant case, and neither is the passthrough posture. Both are covered in Core Section 3, and both involve the same owner authorizing two relationships rather than one party passing access to another. A future subgrant design should be careful not to re-describe those as delegation.

### Change of client ownership and undisclosed sub-processing

_Newly deferred (2026-09-02; raised in the 2026-08-19 working session)._

**Description:** An owner grants access to a client on assumptions about that specific relationship. If the client is acquired, changes legal structure, or outsources processing to a third party the owner never saw, those assumptions no longer hold, and the grant does not know it.

**Why it is open:** The protocol has no representation of who the client is as a legal entity, and no event by which a change of control could reach an issued grant. One suggestion from the session was to require clients to declare ownership type. Whether that belongs in the protocol, in the conformance programme, or nowhere is undecided, as is whether a change of control should force revocation, force re-consent, or merely be disclosed.

**Related:** ISO MyTerms was raised in the same discussion as prior art for owner-specified terms under which a first party holds data. It has not been evaluated for fit, and whether owner-specified terms belong in Core, in a companion RFC with the authorization server holding templates, or outside PDPP entirely is itself open.

**v0.1 posture:** Out of scope. `client_claims` carries client-authored, explicitly non-enforceable statements about a specific request; it is not an ownership record and must not be read as one.

### Bulk export as a distinct access path

_Newly deferred (2026-09-02; raised in the 2026-08-19 working session)._

**Description:** PDPP has focused on continuous synchronization rather than a Takeout-style bulk export. The question raised was whether export deserves its own defined access path rather than being left as a special case of query.

**Why it is open:** Core already has owner-token self-export as a SHOULD-level resource server conformance item (Section 9), so the primitive exists. What does not exist is a defined export path for a client under a grant, or an answer to whether a bulk export differs from paginating the same query to its end in anything other than convenience.

**v0.1 posture:** Owner self-export is in scope at SHOULD level. Client-side bulk export is not defined and is served, if at all, by ordinary paginated query under the grant.

### Trust Registry Query Protocol (TRQP) as the register interface

_Newly deferred (2026-09-02)._

**Description:** ToIP's Trust Registry Query Protocol is a read-only interface for asking "is X authorized to do Y in this ecosystem", and registries using it can recognize one another. That is the shape of the question an authorization server asks about a source declaration under Section 6, and the shape of what the PDP-Connect register answers.

**Why it is open:** TRQP is in public review and has no test suite, so it cannot be a dated commitment. The design question for the specification is narrower than adoption: whether Core should describe the register lookup in terms general enough that a TRQP endpoint is one conforming implementation of it, rather than describing a PDP-Connect-specific interface a TRQP endpoint would then have to be adapted to.

**v0.1 posture:** Core does not define a register interface, so nothing in v0.1 forecloses this. Trust registry and connector certification are already listed as deferred in Core Section 12.

**Design constraint for a future version:** If the register is exposed as a TRQP endpoint from phase 2, recognition of another registry becomes a TRQP query rather than a bilateral arrangement, and withdrawal of recognition propagates through the same query path. Any interface Core describes in the meantime should not assume a single register.

**Where it would live:** In a profile or binding, not in Core's normative text. Core states what an authorization server must establish about a source declaration before accepting it; it does not name the protocol by which the server asks a third party. Naming TRQP in Core would bind the specification to a document still in public review and without a test suite. Naming it in a binding keeps the commitment real without dating it, and matches how this specification treats other binding-level mechanisms.

### Owner-operated authorization server over a platform's data (UMA-style)

_Newly deferred (2026-09-02)._

**Description:** A topology in which the platform continues to hold the owner's data, but the owner runs their own authorization server in front of it, so that the owner's server — not the platform's — decides who may read what. This is the arrangement UMA describes, and it is distinct from the on-behalf-of chain in Core Section 3, where a personal server holds an ordinary grant against the platform and the two relationships stay separate.

**Why it is open:** It requires the platform's resource server to accept grants issued by an authorization server the platform does not operate and did not choose, which is a trust relationship PDPP does not currently define and platforms have no incentive to accept unilaterally. It also needs a rule for what happens when the platform's own policy and the owner's authorization server disagree.

**v0.1 posture:** Not introduced. Core's Section 3 topologies are source-native fulfillment, personal-server fulfillment, and the on-behalf-of chain that follows from them. This is a fourth arrangement, and its absence from Core is deliberate rather than an oversight.

---

## Decided (recorded for history)
Expand Down
4 changes: 2 additions & 2 deletions spec-discovery-and-trust.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# PDPP Source Declaration Discovery and Trust v0.1.0

Status: Companion specification draft
Date: 2026-08-14
Status: Informative. Implementation guidance. The load-bearing requirements moved into Core on 2026-09-02: equivocation into Core §5 Versioning and snapshots, source acceptance into Core §6 Source acceptance, and publisher attribution into Core §5 SourceDeclaration fields.
Date: 2026-09-02

---

Expand Down