data-class.md
June 16, 2026 · View on GitHub
⚠️ Experimental scheme skeleton. This is one data-labelling scheme that fills the
trust-annotationsevidenceRefslot viatype: "data-class.v1". It is not an MCP extension and not a sibling of the extensions — it is the home for the richer classification taxonomy that the extension's coarsesensitiveboolean deliberately leaves out. See Why a scheme.
Scheme — fills trust-annotations's evidenceRef slot, selected by
evidenceRef.type == "data-class.v1". Not an extension.
Abstract
This scheme defines data-class.v1, an entry for the trust-annotations
evidenceRef slot that carries a structured data classification: a coarse
sensitivity level plus zero or more regulatory scopes and optional org-defined
labels. It is the structured counterpart to the extension's single
sensitive: boolean, for deployments that need to express which regulated
category a result falls under (e.g. HIPAA, GDPR, PCI-DSS) without putting that
taxonomy on the wire for every server.
Why a scheme, not a wire field
The trust-annotations extension keeps only sensitive: boolean on the wire.
That coarse signal is universally client-actionable and cheap, and — critically
— it cannot become wrong as regulation changes. A richer classification was
asked for repeatedly in review, in three different shapes:
- a linear
sensitiveHint: low | medium | high, which @JustinCappos rejected: sensitivity is set-theoretic (a card number and a medical record are both sensitive but to different readers), not a single scale; - org-defined vocabularies rather than a fixed enum
(@olaservo;
@Mossaka
proposed reverse-DNS
classification.labels); - a class + regulatory scope pairing such as
confidential:hipaa(@krubenok; carried into SEP-2061 by @rreichel3).
Against all three, @localden
warned that a taxonomy baked into the protocol is very hard to remove if it turns
out wrong. A scheme resolves the tension: the taxonomy evolves behind a type
value, on its own clock, while the wire keeps the boolean that can never rot.
Motivation
A regulated deployment needs to know not just that a result is sensitive but
under which regime, so the host can apply the matching control (HIPAA minimum-
necessary, GDPR purpose limitation, PCI-DSS storage rules). The boolean cannot
carry that, and encoding it inline would force every server and client to agree
on a regulatory taxonomy. This scheme lets a server that already knows the
classification (a healthcare record store, a payments API) attach it as evidence,
while a client that does not implement the scheme still sees sensitive: true.
Specification
Scheme identity
A data-class.v1 record is selected by evidenceRef.type == "data-class.v1" on
a trust-annotations annotation whose sensitive is true. The
digest/canonicalization pair over the record is required exactly as for any
other scheme.
Payload (skeleton)
The record is a JSON object. Shapes below are open questions, not settled:
{
"class": "confidential",
"regulatory": ["hipaa"],
"labels": ["com.example.pii.ssn"],
"policyRef": "https://policy.example.com/classes/confidential"
}
class— a coarse level. Candidate setpublic | internal | confidential | restricted(four levels, from the original SEP-1913 taxonomy). Whether the set is fixed or registry-curated is open.regulatory— zero or more regulatory scopes the result falls under. Open strings, not an enum (so a new regime doesn't need a schema change). This is the:scopehalf of @krubenok'sconfidential:hipaa.labels— optional org-defined tags, reverse-DNS namespaced per @Mossaka, for vocabularies a deployment defines for itself.policyRef— optional pointer to the policy that defines the classes, so the record is interpretable by a host that hasn't pre-agreed the vocabulary.
Graceful degradation
A client that does not implement data-class.v1 ignores the record and relies on
the trust-annotations sensitive boolean, which remains meaningful on its own.
The scheme only ever refines the boolean; it never contradicts it (a
data-class.v1 record only appears where sensitive is already true). Because
the boolean is the lowest-common-denominator floor, a producer of this scheme
SHOULD emit both the boolean and the record, never the record alone.
Producer / consumer
- Producer (candidate). A server fronting a regulated store (health records, payments) that already classifies its data internally.
- Consumer (candidate). A host policy engine that maps
class+regulatoryto a control (block, redact, prompt). The same host-side resolution model as the FIDES scheme applies: the wire marker is advisory; the regulated semantics are host-resolved against the deployment's policy.
Open questions
- Is the
classset fixed (public/internal/confidential/restricted) or registry-curated? @localden's removability concern argues against fixing it. - Do
regulatoryandlabelsoverlap enough to collapse into one open-string list, or are "named regime" and "org-defined tag" usefully distinct? - Should
data-class.v1ever be expressible on the wire as a structured escape hatch (tracked in open-questions.md), or is keeping it strictly behindevidenceRefthe right boundary? - How does this relate to SEP-2061's
DataClass/RegulatoryScope— is this scheme the migration target for that work, or a parallel encoding?
Changelog
- 2026-06-16 — Initial skeleton. Payload shapes are candidates pending the open questions above.