diff --git a/.spellcheckerdict.txt b/.spellcheckerdict.txt
index 144253f7..f8b4c2bb 100644
--- a/.spellcheckerdict.txt
+++ b/.spellcheckerdict.txt
@@ -1,7 +1,11 @@
-Alexa
+accreditations
announcementType
+attributeSetType
+attributeSetTypeName
+attributeSetTypeNamespace
Avro
Base58
+BCP-47
BLAKE2b
Brötli
CalVer
@@ -10,26 +14,32 @@ Changelog
changeType
[Cc]odec('s)?
contentHash
-cryptographic
+[Cc]ryptographic
cryptographically
+[Cc]ryptosuites
CtxSharedSecretA
CtxSharedSecretB
CtxSharedSecretBob
Curve25519
decrypt
Delegator
-Deserialize
+[Dd]eserialize(d?)
+DIDs
Diffie-Hellman
[Dd]iscoverable
DSNP
DSNP-compatible
+dsnp-did-resolver
DSNP-referenced
+dsnp-verifiable-credentials
ECIES
+EdDSA
[Ee]num(s)?
Ethereum
Extrinsics
fromId
GraphEdge
+hashcode
H265
HBASE
HTTPS
@@ -46,29 +56,40 @@ LibertyDSNP
libsodium
little-endian
localhost
+localizable
+lookups
Mainnet
mdBook
MDX
+Metaschema
MP[34]
MSA
multibase
+[Mm]ultibase-encoded
multicodec
+multicodec-prefixed
[Mm]ultihash
multihash-encoded
-multikey
+[Mm]ultikey
NaCl
+namespaced
+non-DSNP
objectId
OGG
Parachain
parseable
Paseo
+personhood
PNG
Polkadot
Poly1305
pre-configured
+[Pp]rerelease
PRId([ABs])?
+pseudonymously
publicKey
repo
+resolvers
RFC[1-9][0-9]*
Ristretto
RPC
@@ -80,7 +101,9 @@ SDK
SHA-256
Stateful
stringified
-subkey
+subjectContentHash
+subkey(s?)
+substring
SVG
targetAnnouncementType
targetContentHash
@@ -92,6 +115,7 @@ UINT_8
uncompress
unencrypted
[Uu]nfollow(ed)?
+unhashed
URI
url
userId
@@ -99,10 +123,13 @@ UTF-8
v[0-9]+(\.[0-9]+)*
vanishingly
varint
+[Vv]erifier(s?)
+verifiability
W3C
WebM
WebP
websocket
whitepaper
+whitespace
X25519
XSalsa20
diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md
index bf508811..cbc081dd 100644
--- a/STYLEGUIDE.md
+++ b/STYLEGUIDE.md
@@ -4,50 +4,97 @@ Style guide defining wording, spelling, and other details regarding how DSNP ter
For more information about DSNP, visit [dsnp.org](https://www.dsnp.org/)
or [DSNP on GitHub](https://github.com/LibertyDSNP/spec)
-## Announcement
-Uppercase A
+## General rules
+* Announcements specific to DSNP have initial caps. (i.e., Broadcast Announcement)
+* Announcement Types also have initial caps.
+* General words that aren't specific to DSNP are lowercase (i.e., announcement, batch, content hash).
+* Attribute is lowercase except when combined with an announcement or a specific DSNP set type. (i.e., Attribute Set Announcement)
+
+## announcement
+Generally all lowercase
## Announcement Type
Uppercase A and T
-## Batch
-Uppercase B
+## attribute
+All lowercase
+
+## attribute sets
+All lowercase
+
+## Attribute Set Announcement
+Uppercase A, S and A
+
+## Attribute Set Type
+Uppercase A, S and T
+
+## Attribute Set Value Document
+Uppercase A, S, V and D
+
+## batch
+All lowercase
## Batch Publication
Uppercase B and P
+## bloom filter
+lowercase b and f
+
+## Broadcast Announcements
+Uppercase B and A
+
## Code of Conduct
Uppercase C and C
## community
All lowercase
+## content announcement
+All lowercase
+
+## Content Attribute Set
+
+## content hash
+All lowercase
+
+## credential document
+All lowercase
+
## Decentralized Social Networking Protocol (DSNP)
Spelled out fully first time it appears and then acronym thereafter. Avoid preceding with the word "the" and never follow with the word "protocol".
## development community
All lowercase
+## DSNP Announcements
+Uppercase DSNP and A
+
## DSNP public social graph
All lowercase after acronym
## DSNP Batch Publications
Uppercase Acronym plus uppercase B and P
+## DSNP content
+Uppercase acronym, lowercase c
+
## DSNP Content Hash
Uppercase Acronym plus uppercase C and H
+## DSNP Content URI
+Uppercase D, C and URI
+
## DSNP graph
Only acronym is uppercase
## DSNP Identifiers
Uppercase Acronym plus uppercase I
-## DSNP Identity
-Uppercase Acronym plus Uppercase I
+## DSNP identity
+Uppercase Acronym lowercase i
## DSNP Id
-Short for DSNP Identity, Uppercase Acronym plus uppercase I
+Short for DSNP identity, Uppercase Acronym lowercase when spelled out
## DSNP Protocol Scheme
Uppercase Acronym plus uppercase P and S
@@ -55,18 +102,21 @@ Uppercase Acronym plus uppercase P and S
## DSNP Specification
Uppercase DSNP and S, avoid preceding with the word "the"
+## DSNP user
+Uppercase DSNP and lowercase u
+
## DSNP User Id
Uppercase acronym, U and I, avoid preceding with the word "the"
## DSNP User URI
Uppercase Acronyms plus uppercase U
-## End User
-Uppercase E and U
-
## Exclamation Marks
Should be avoided
+## External Content Attributes
+Uppercase E, C and A
+
## Graph Change Announcements
Uppercase G, C and A.
Note: Graph Change Announcements and events have been migrated to use User Data Operations as of version 1.2.0.
@@ -78,9 +128,15 @@ Note: Graph Change Announcements and events have been migrated to use User Data
## InterPlanetary File System (IPFS)
Uppercase I, P, F and S. In the first instance, spell out followed by the acronym in parentheses. Use the acronym only thereafter.
+## issuer
+All lower case
+
## MUST/MUST NOT
All Caps when defining rules for specification
+## on-demand credential
+Hyphenated, all lower case
+
## Operation
Uppercase O when referring to spec-defined DSNP Operations
@@ -90,26 +146,65 @@ Always use
## Possessives
Making DSNP possessive should be avoided (e.g. DSNP’s)
+## Profile Announcement
+Uppercase P and A
+
## Project Liberty
Uppercase P and L
+## public key
+All lowercase
+
## public graph
All lowercase
+## Public Key Announcement
+Uppercase P, K and A
+
## Reaction Announcement
Uppercase R and A
## Record
Uppercase R when referring to spec-defined DSNP State Change Records
+## Reply Announcements
+Uppercase R and A
+
+## schema
+All lowercase
+
## social network graph
All lowercase
## Team
Should not be used in context with DSNP
+## Tombstone Announcement
+Uppercase T and A
+
+## User Attribute Set Announcement
+Uppercase U, A, S and A
+
+## verifier
+Lowercase v
+
+## Verifiable Credential Document
+Uppercase V, C and D
+
+## Verifier Credential Schema Document
+Uppercase V, C, S and D
+
## Update Announcement
Uppercase U and A
+## user
+All lowercase
+
+## User Attribute Set
+Uppercase U, A and S
+
+## verifier
+All lowercase
+
## We/Us/Our
Should not be used in context with Frequency
diff --git a/pages/ActivityContent/Associated/Attachments.md b/pages/ActivityContent/Associated/Attachments.md
index 5f2d76aa..d36d9874 100644
--- a/pages/ActivityContent/Associated/Attachments.md
+++ b/pages/ActivityContent/Associated/Attachments.md
@@ -207,3 +207,145 @@
"published": "1970-01-01T00:00:00+00:00"
}
```
+
+## Attestations and Interactions
+
+Attestation and Interaction attachments are DSNP extensions to the Activity Content model that allow Verifiable Credentials to be attached to content with clear semantics.
+
+### Verifiable Credential Link
+
+Both Attestation and Interaction attachments must contain a link to Verifiable Credential document.
+The link must contain a relationship identifier in the form of a DSNP Attribute Set Type (the `rel` field), to allow applications to determine the type of credential expected.
+
+| Property | Base Spec | Required | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `type` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-type) | YES | Identifies the type of the object | MUST be set to `Link` |
+| `rel` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-id) | YES | The attestation's attribute set type | MUST be a DSNP [Attribute Set Type](../../DSNP/AttributeSets.md#attribute-set-type) corresponding to the referenced credential document |
+| `href` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-href) | YES | The URL for the associated Verifiable Credential | MUST be a [Supported URL Schema](../Overview.md#supported-url-schema) |
+| `mediaType` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-mediatype) | YES | MIME type of `href` content | MUST be set to [`application/vc+ld+json`](https://w3c.github.io/vc-data-model/#vc-ld-media-type) |
+| `hash` | [DSNP 1.0](Hash.md) | YES | Array of hashes for linked content validation | MUST include at least one [supported hash](Hash.md#supported-algorithms) |
+
+### Attestation
+
+Attestations about a DSNP User may be included as attachments in an Activity object.
+This format allows users to include relevant data corresponding to an Attribute Set Type with their DSNP profile or a social media content item.
+
+The Verifiable Credential found at the indicated URL must include the [DSNP DID](../../VerifiableCredentials/Types/DID.md) of the user in its `credentialSubject.id` field.
+
+| Property | Base Spec | Required | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `type` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-type) | YES | Identifies the type of the object | MUST be set to `Attestation` |
+| `url` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-url) | YES | An array of links for the given credential | MUST be a [Verifiable Credential Link](#verifiable-credential-link) |
+| `name` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-name) | no | The display name for the attestation | |
+
+#### Example
+
+```json
+{
+ "@context": "https://www.w3.org/ns/activitystreams",
+ "type": "Profile",
+ "content": "I am a doctor. You're doing this all wrong.",
+ "mediaType": "text/plain",
+ "attachments": [
+ {
+ "type": "Attestation",
+ "name": "My Degree",
+ "url": [
+ {
+ "type": "Link",
+ "rel": "did:dsnp:123456$AcmeMedicalAssociation",
+ "href": "https://acmemedicalassn.org/credentials/degree-123.json",
+ "mediaType": "application/vc+ld+json",
+ "hash": [
+ "QmQrGdv6Ky5sJhaVdw27y4aod5pdfihDkBTxiBkRaSGJJ7"
+ ]
+ }
+ ]
+ }
+ ],
+ "published": "1970-01-01T00:00:00+00:00"
+}
+```
+
+### Interaction
+
+The `Interaction` attachment type enables simple discovery of pseudonymously issued credentials that may be relevant for a user to relate to a specific content item.
+
+In contrast to `Attestation` attachments, Interactions reference a Verifiable Credential that does not address a specific DSNP User as its subject, but instead relies on a user-provided interaction identifier that can later be provably associated with a DSNP identity.
+This allows for the issuance of Interaction credentials outside of an authenticated DSNP application context, and in scenarios where users wish to remain anonymous to the issuer.
+
+An Interaction attachment resembles an Attestation, with the addition of an interaction nonce as described below (the `nonce` field), a Verifiable Credential Link in the `url` field, and an identifier of the object of the interaction in the `href` field.
+The linked Verifiable Credential must have a credential subject that minimally includes an `interactionId` and repeats the `href` field, but may contain other data as defined by a [Verifiable Credential Schema](../../VerifiableCredentials/Types/VerifiableCredentialSchema.md)).
+
+Proof that the credential was issued to the user responsible for posting the content is produced and verified using a cryptographic hash.
+To acquire an anonymous Interaction credential, a DSNP User generates and records a random nonce of any length (192 bits or more is recommended).
+The user then concatenates their DSNP User Id (in little-endian 64-bit format) with the nonce and generates a message digest using a [supported hashing algorithm](Hash.md#supported-algorithms).
+The multibase-encoded hash output is then sent to the credential issuer to be included as an `interactionId` key in the `credentialSubject` field of the generated document.
+It is intentionally opaque to the issuer.
+The issuer may include any other fields relevant to the document schema in the `credentialSubject`, and then generate a signature proof.
+The URL of the signed credential is then included in the interaction attachment (see example).
+
+When posting content including the Interaction attachment, the user must include the nonce (as the `nonce` key) in order for consuming applications to verify that the originator of the content is responsible for generating the interaction.
+A verifier MUST inspect the DSNP User Id of the sender of the content (via the relevant announcement) and the nonce, and repeat the hashing process to verify that it matches the value from `interactionId`.
+
+Issuers of interaction credentials are encouraged to use the `display` extension described in the DSNP [Verifiable Credential Schema](../../VerifiableCredentials/Types/VerifiableCredentialSchema.md#display-extension) documentation to provide applications with hints as to how a verified interaction may be displayed, for example as a badge on a profile or content post.
+
+| Property | Base Spec | Required | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `type` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-type) | YES | Identifies the tag as type `Interaction` | MUST be `Interaction` |
+| `url` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-url) | YES | An array of links for the given credential | MUST be a [Verifiable Credential Link](#verifiable-credential-link) |
+| `name` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-name) | no | The display name for the interaction | |
+| `reference` | [Activity Vocabulary 2.0](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-id) | YES | URI of object of the interaction | MUST be the same as the corresponding field within the linked document's `credentialSubject` |
+| `nonce` | DSNP extension | YES | Multibase-encoded random byte string (a minimum deserialized size of 24 bytes is recommended) | |
+
+#### Provenance of Interaction Credentials (Non-Normative)
+
+Part of the provenance of a credential relies upon having a DSNP User Id and nonce that are hashed by the requester of the credential.
+Ideally, the requester could prove that they were the user indicated by the DSNP User Id.
+Similar assertions are often done by providing signatures: the user could sign a message including their User Id with the private key associated with a public key they manage as user data, in much the same way that the issuer of a Verifiable Credential creates a signature proof.
+
+However, because DSNP does not prevent multiple users from associating the same public key with their accounts, it would be possible, for example, for Alice to obtain a credential in Bob's name and give it to Bob to post, as long as Bob represents that the corresponding public key is his own by listing it as one of his DSNP public keys.
+Therefore, the provenance guarantee offered by the hashing approach on an otherwise anonymous credential is ultimately equivalent.
+Because of this, applications should _not_ infer that the credential requester and sender are necessarily the same entity, only that, if different, they have collaborated to obtain a credential associated with the sender.
+
+If it is important to be able to prove definitively that the credential requester is the same user as represented in the hash (for example, in a proof of personhood claim), the credential issuer should ask the user to authenticate by signing a challenge with their control key, and include the user's unhashed DSNP DID as the `credentialSubject`.
+
+#### Example
+
+```json
+{
+ "@context": "https://www.w3.org/ns/activitystreams",
+ "type": "Note",
+ "content": "This rug really ties the room together.",
+ "mediaType": "text/plain",
+ "attachments": [
+ {
+ "type": "Interaction",
+ "reference": "https://thebiglebowski.fandom.com/wiki/The_Rug",
+ "nonce": "zYAjKoNbau5KiqmHPmSxYCvn66dA1vLmwbt",
+ "url": [
+ {
+ "type": "Link",
+ "rel": "did:dsnp:898998$ProofOfPurchase",
+ "href": "https://therugstore.com/proof/txn-2929123.json",
+ "mediaType": "application/vc+ld+json",
+ "hash": [
+ "QmQrGdv6Ky5sJhaVdw27y4aod5pdfihDkBTxiBkRaSGJJ7"
+ ]
+ }
+ ]
+ }
+ ],
+ "published": "1970-01-01T00:00:00+00:00"
+}
+```
+
+The referenced credential document would include within its `credentialSubject` a matching `reference` value, as well as an `interactionId` generated by hashing the sender's 64-bit little-endian DSNP User Id and the (deserialized) `nonce`:
+
+```
+ "credentialSubject": {
+ "interactionId": "...",
+ "reference": "https://thebiglebowski.fandom.com/wiki/The_Rug",
+ "transactionId": "ABC123"
+ }
+```
diff --git a/pages/ActivityContent/Overview.md b/pages/ActivityContent/Overview.md
index 0b9d73f2..da521d1b 100644
--- a/pages/ActivityContent/Overview.md
+++ b/pages/ActivityContent/Overview.md
@@ -1,5 +1,5 @@
# Activity Content Specification
-__Version 1.2.0__
+__Version pre-1.3.0__
Content references shared via the DSNP consist of URLs pointing to documents containing Activity Streams JSON objects.
For the purposes of the DSNP, restrictions are placed on the [Activity Streams 2.0](https://www.w3.org/TR/activitystreams-core/) specification.
@@ -45,9 +45,10 @@ URLs in DSNP-compatible Activity Content MUST use one of the following URL schem
| [LibertyDSNP/activity-content-java](https://github.com/LibertyDSNP/activity-content-java) | Java/Kotlin |
| [LibertyDSNP/activity-content-swift](https://github.com/LibertyDSNP/activity-content-swift) | Swift |
-
## Prerelease Changelog
---->
+
+- [DIP-257](https://github.com/LibertyDSNP/spec/issues/257) Attribute Sets and Attestation
## Releases
diff --git a/pages/DSNP/Announcements.md b/pages/DSNP/Announcements.md
index 8010868b..15d8dee9 100644
--- a/pages/DSNP/Announcements.md
+++ b/pages/DSNP/Announcements.md
@@ -18,6 +18,9 @@ Each Announcement has an enumerated type for use when separating out a stream of
| 5 | [Profile](Types/Profile.md) | a profile | YES | no |
| 6 | [Update](Types/Update.md) | an update to content| YES | no |
| 7 | [Public Key](Types/PublicKey.md) | a public key for secure communication | no | no |
+| 8 | [User Attribute Set](Types/UserAttributeSet.md) | an attribute set for a DSNP User | YES | YES |
+| 9 | [DSNP Content Attribute Set](Types/DSNPContentAttributeSet.md) | an attribute set for a DSNP content item | YES | YES |
+| 10 | [External Content Attribute Set](Types/ExternalContentAttributeSet.md) | an attribute set for a non-DSNP content item | YES | YES |
a Since DSNP version 1.2, social graph changes use [User Data](UserData.md) operations as described in the [Graph](Graph.md) section.
diff --git a/pages/DSNP/AttributeSets.md b/pages/DSNP/AttributeSets.md
new file mode 100644
index 00000000..146f3698
--- /dev/null
+++ b/pages/DSNP/AttributeSets.md
@@ -0,0 +1,174 @@
+# Attribute Sets
+
+Attribute sets enable structured data to be associated with DSNP users (self or others), DSNP content, or any other content (original or not) that has a public URL.
+Attribute sets have a cryptographically authenticated creator, and a subject (the entity being described), which may be the same.
+Attribute set data may appear in several modes: it can be published as a DSNP Announcement, attached to a user's Profile document, or attached to social media content.
+
+## Data Model
+
+The conceptual model for Attribute Sets includes three types of data:
+
+1. A schema encoding rules for validating attribute set data. This MUST be in the form of a [DSNP Verifiable Credential Schema](../VerifiableCredentials/Types/VerifiableCredentialSchema.md) (a Verifiable Credential that contains a JSON Schema document).
+2. The attribute set data itself. This MUST be serialized as a [DSNP Verifiable Credential](../VerifiableCredentials/Types/VerifiableCredential.md).
+3. A reference to the attribute set data, which may take one of several different forms depending on the desired usage pattern.
+
+## Attribute Set Type
+
+An Attribute Set Type is an identifier that is used to group Attribute Sets that share the same data structure and semantic meaning.
+Attribute Set Types have a well known canonical name and (in most cases) a well defined schema, expressed using a Verifiable Credential Schema document.
+
+### Versioning
+
+DSNP supports (but does not mandate) Attribute Set Types that can be described in different Verifiable Credential Schema documents over time in order to preserve backward and forward compatibility.
+This allows the exact details of the schema to evolve over time without compromising the discovery and verifiability of previously shared credentials.
+
+This behavior is achieved by allowing a schema issuer to retain a common identifier across multiple versions of a schema, provided that the proof signatures are all issued from the same DSNP user (the schema author).
+This allows applications to perform reliable lookups against an Attribute Set Type, regardless of the specific version that may be used by an individual credential document.
+This is facilitated by the following naming scheme.
+
+### Canonical naming
+
+Attribute Set Type canonical names are constructed as follows:
+
+* MUST be in the format _attributeSetTypeNamespace_ + "`$`" + _attributeSetTypeName_, where _attributeSetTypeNamespace_ MUST be either a multihash content hash (encoded as a multibase string), the DSNP DID of the schema author (beginning with "`did:dsnp:`"), or the empty string (for schemaless attribute set types).
+* _attributeSetTypeName_ MUST match a declared type value in the Attribute Set Value Document
+* If _attributeSetTypeNamespace_ is a DID, it must match the schema author in the schema referenced from the credential document, and the schema must include a proof that can be verified using the author's public key.
+* If _attributeSetTypeNamespace_ is empty, the credential document MUST NOT reference a schema.
+* If _attributeSetTypeNamespace_ is a multibase string, it must match the multihash content hash of the schema file referenced from the credential document.
+
+Examples:
+
+* Schemaless: `$IsHuman`
+* Unsigned schema: `zQmQNHNfHnbgJJ6nK4UPx2VtTUCafAKCbqZJ6ZRYUGjoeFj$BSC`
+* Signed schema: `did:dsnp:1234567890$TimeZone`
+
+## Usage Patterns
+
+### Attribute Set Announcements
+
+The Announcement model allows Attribute Sets to be consumed as events providing context or metadata to the social network.
+Attribute Set Announcements allow DSNP Users to associate data or make assertions about their own account, other DSNP Users, content on DSNP, or even content external to DSNP.
+Credential documents are anchored to the announcement by the `url` and `hash` fields.
+
+Applications consuming these Announcements can index and use the associated Attribute Sets to inform their user experience.
+For example, a fact-checking organization can publish Attribute Set announcements to flag content it deems to be misinformation, and interested applications that trust the organization's determinations can provide warning labels on social media posts.
+Similarly, an organization might attach metadata in the form of Attribute Sets to denote DSNP User Ids that are operated by government actors.
+
+Attribute Set Announcements cannot be updated once published, but can be tombstoned.
+Applications MUST treat tombstoned Attribute Set Announcements as nonexistent.
+
+#### Announcement Types
+
+Attribute Set announcements are expressed using three announcement types, depending on the type of subject being described.
+
+| Announcement Type | Id | Subject identifier |
+| --- | --- | --- |
+| [User Attribute Set](./Types/UserAttributeSet.md) | 8 | [DSNP DID](../VerifiableCredentials/Types/DID.md) |
+| [DSNP Content Attribute Set](./Types/DSNPContentAttributeSet.md) | 9 | [DSNP Content URI](./Identifiers.md#dsnp-content-uri) |
+| [External Content Attribute Set](./Types/ExternalContentAttributeSet.md) | 10 | URL and hash |
+
+### Attestation and Interaction Attachments
+
+Attribute Sets associated with and controlled by a DSNP User can be referenced as [Attestation Attachments](../ActivityContent/Associated/Attachments.md#attestation) to a user's [Profile](./Types/Profile.md) document, or to an Activity Content Note object that is referenced from a Broadcast or Reply announcement.
+
+Profile-linked attestations are necessary in cases where an attestation is required in order for a consumer to verify chains of trust designated by schema controllers, such as an accreditation that gives the organization represented by the DSNP User Id the authority to issue credentials to others.
+
+Applications enabling users to update their Profile document should take care to preserve any Profile-linked attestations, even if the meaning of these is opaque to the updating application.
+
+Attestation attachments link to credentials that identify a DSNP User as their subject.
+That is, the `credentialSubject.id` field should match the user's DSNP DID.
+
+[Interaction Attachments](../ActivityContent/Associated/Attachments.md#interaction) instead identify a subject other than the DSNP User, represented by a URI.
+A user can request a credential as proof of interaction with the specified subject by generating a pseudonymous Interaction Id generated by hashing their DSNP User Id with a random nonce value.
+This allows users to request credentials without revealing their DSNP User Id to the issuer.
+When the credential is attached, the user can prove ownership by supplying the nonce.
+For example, a social media post might include provenance data attested to by a trusted third party, or a proof of purchase issued to the buyer of a product reviewed in a post.
+
+### On-Demand Presentation
+
+Holders of Verifiable Credentials may wish to present these only on demand rather than have a public record of the credential.
+Several emerging specifications are developing for this usage pattern and are outside the scope of this specification.
+Developers are encouraged to consider the [Verifiable Presentation Request](https://w3c-ccg.github.io/vp-request-spec/) specification.
+
+## Public Key references
+
+Both Verifiable Credential Schema documents and Verifiable Credential documents may include proof sections.
+
+DSNP Users may control one or more key pairs for use in signing these documents and make these discoverable using the `assertionMethod` User Data type.
+A key announced in this fashion can be referenced within the proof using a [DSNP DID](../VerifiableCredentials/Types/DID.md) with a key identifier, as in `did:dsnp:123456#key1`.
+
+A verifier must ensure that the DSNP User Id referenced this way (that is, the substring of the DID before the first `#` character) is the same as the issuer field.
+
+Following the principle of least privilege, the key pair used to issue credentials SHOULD be different from any control keys used to authenticate transactions.
+
+## Trust and verification
+
+Trust in an attribute set may be assigned based on a combination of its Attribute Set Type and issuer.
+It is left to each application that acts as a DSNP consumer to determine which attribute sets it will trust.
+
+Trust MUST be accompanied by verification of the documents linked to an Attribute Set reference.
+
+### Summary of verification responsibilities
+
+When verifying a credential document, a consumer MUST:
+
+* Retrieve the Verifiable Credential document from the announcement or attachment link's `url` field (or, for on-demand credentials, receive the credential document by some other mechanism).
+* Calculate and verify that the content hash of the Credential Document matches the value specified in the referring item (an Attribute Set Announcement's `contentHash` field, for example).
+* Verify that the credential document is well formed (it should comply with the generic JSON schema for verifiable credential documents, and include a valid combination of fields).
+* Verify that the credential's `expirationDate`, if present, has not passed.
+* If the subject of the credential document is not a URL beginning with "`dsnp://`", verify the `subjectContentHash` by retrieving the subject URL and applying the indicated hash function. URLs beginning with "`dsnp://`" do not need a hash check as they already include a self-reflective content hash. They should, however, be checked for existence.
+* Retrieve the Verifiable Credential Schema document from the URL specified in the `credentialSchema.id` field.
+* Validate the Verifiable Credential Schema document against the generic JSON schema for Verifiable Credential Schema.
+* Validate that the claim content in the `credentialSubject` field conforms to the JSON schema within the Verifiable Credential Schema document.
+* Construct the `attributeSetType` for the document by following the rules for schemaless, unsigned, and signed schemas, and ensure it matches the declared type in the announcement or link object. Note that this MAY require verification of the issuer proof of the Verifiable Credential Schema, and potentially a chain of trust (see below).
+* Verify the issuer proof, if present.
+
+Verifiers should take care that transient errors (for example, a URL being unreachable due to temporary network issues) do not lead to long-term caching of false negatives.
+
+### Trust chains
+
+Applications are free to make their own trust decisions, and display or incorporate Verifiable Credentials based on their `issuer`.
+However, in many real world scenarios, the originator of a particular type of credential may authorize agents to issue the credential, based on any number of approval or certification processes external to DSNP.
+The controller of a DSNP Attribute Set Type can encode its requirements for trusted agents within a DSNP extension field of the Verifiable Credential Schema document.
+
+To capture this requirement, DSNP uses an optional, protocol-specific `trust` key within the `dsnp` key under the `credentialSubject` section of the schema credential.
+The `trust` key can contain one or both subkeys `oneOf` or `allOf`, which in turn contain a list of Attribute Set Types.
+These indicate to the consumer that the author of the credential schema requires that a credential of the defined type be trusted only if its issuer can be shown to possess Verifiable Credentials of the indicated type.
+
+In the case of `oneOf`, the verifier should check that the issuer is the subject of a Verifiable Credential conforming to at least one of the given Attribute Set Types.
+In the case of `allOf`, the verifier should check that the issuer is the subject of Verifiable Credentials for every given Attribute Set Type.
+
+For example, the Worldwide Whale Foundation, identified by DSNP User Id 123456, may authorize its agents to issue credentials of type `did:dsnp:123456$CertifiedWhaleBiologist` to individuals that meet the certification standard that the Foundation defines.
+The Worldwide Whale Foundation defines a second attribute set type, `did:dsnp:123456$AuthorizedWhaleBiologistCertifier` by publishing a Verifiable Schema Credential for that type, and then issues a Verifiable Credential of that type (an accreditation) to Acme Ocean Certification Lab.
+Acme Ocean Certification Lab should update its DSNP Profile document to reference the accreditation document via an attachment of type `Attestation`.
+Worldwide Whale Foundation then includes the `did:dsnp:123456$AuthorizedWhaleBiologistCertifier` Attribute Set Type in the `credentialSubject.trust.allOf` value of the `CertifiedWhaleBiologist` Verifiable Credential Scheme (in this example, using `oneOf` would be equivalent), generates the signature proof, and publishes the schema document.
+Acme Ocean Certification Lab can now issue `did:dsnp:123456$CertifiedWhaleBiologist` credentials to users that can be verified through the trust chain.
+
+### Displaying credentials
+
+The DSNP schema credential document MAY contain an additional `display` key within the `dsnp` key under `credentialSubject`.
+This allows the authors of attribute set types to recommend how a credential should be displayed within a user interface.
+
+To allow for localizable text, a map of content language codes (following `BCP-47`, so using the same form as the HTTP `Content-Language` header) to display text can be used under the subkey `label`.
+
+
+Example:
+```
+...
+"credentialSubject": {
+ "type": "JsonSchema",
+ "jsonSchema": {
+ ...
+ },
+ "dsnp": {
+ "display": {
+ "label": {
+ "en-US": "Whale Biologist",
+ "es-ES": "Biólogo de Ballenas"
+ }
+ }
+ }
+}
+```
+
+DSNP applications should treat the `display` section as a recommendation but not a mandate, and are free to indicate the presence or absence of a Verifiable Credential in other forms.
diff --git a/pages/DSNP/Operations.md b/pages/DSNP/Operations.md
index 55e5e8ed..b663255f 100644
--- a/pages/DSNP/Operations.md
+++ b/pages/DSNP/Operations.md
@@ -13,7 +13,7 @@ Where operations are listed as using control keys or ownership proofs as input p
## Transaction Identifiers
Each invocation of a DSNP Operation should be associated with a Transaction Identifier.
-Transaction Identifiers are used to associate Operation invocations with asynchronously emitted State Change Records.
+Transaction Identifiers are used to associate Operation invocations with asynchronously emitted State Change Records.
It MUST be possible to associate a DSNP State Change Record with a Transaction Identifier from a particular DSNP Operation invocation.
Transaction Identifiers MUST be unique within an implementation.
Transaction Identifiers MUST be serializable as a string.
diff --git a/pages/DSNP/Overview.md b/pages/DSNP/Overview.md
index 8b3ee813..b670476c 100644
--- a/pages/DSNP/Overview.md
+++ b/pages/DSNP/Overview.md
@@ -1,5 +1,5 @@
# DSNP Specification
-__Version 1.2.0__
+__Version pre-1.3.0__
DSNP (Decentralized Social Networking Protocol) is a social networking protocol designed to run on a blockchain.
It specifies a set of social primitives along with requirements for interoperability.
@@ -29,9 +29,10 @@ Compliant DSNP system specifications MUST document how each of the required DSNP
A compliant specification MUST specify a mapping from its system-specific state change data (for example, the events emitted by a blockchain) to the DSNP State Change Records that data represents.
-
## Prerelease Changelog
---->
+
+- [DIP-257](https://github.com/LibertyDSNP/spec/issues/257) Attribute Sets and Attestation
## Releases
diff --git a/pages/DSNP/Types/DSNPContentAttributeSet.md b/pages/DSNP/Types/DSNPContentAttributeSet.md
new file mode 100644
index 00000000..e9828668
--- /dev/null
+++ b/pages/DSNP/Types/DSNPContentAttributeSet.md
@@ -0,0 +1,55 @@
+# DSNP Content Attribute Set Announcement
+
+A DSNP Content Attribute Set Announcement is a way to create an authenticated (and, optionally, attested) attribute set for a DSNP content item.
+
+## Fields
+
+| Field | Description | Data Type | Serialization | Parquet Type | Bloom Filter |
+| ----- | ----------- | --------- | ------------- | ------------ | ------------ |
+| announcementType | Announcement Type Enum (`9`) | enum | [decimal](../Serializations.md#decimal) | `INT32` | no |
+| fromId | id of the user creating the Announcement | 64 bit unsigned integer | [decimal](../Serializations.md#decimal) | `UINT_64` | YES |
+| subject | DSNP Content URI of the attribute set subject | [DSNP Content URI](../Identifiers.md#dsnp-content-uri) | `UTF-8` | `UTF8` | YES |
+| url | URL for the Verifiable Credential Document | `UTF-8` | `UTF-8` | `UTF8` | no |
+| contentHash | multihash-encoded hash of content stored at URL | variable length byte array | [hexadecimal](../Serializations.md#hexadecimal) | `BYTE_ARRAY` | YES |
+| attributeSetType | Canonical name of attribute set type | `UTF-8` | `UTF-8` | `UTF8` | YES |
+| issuer | URI of issuer | `UTF-8` | `UTF-8` | `UTF8` | YES |
+
+## Field Requirements
+
+### announcementType
+
+- MUST be fixed to `9`
+
+### fromId
+
+- MUST be a [DSNP User Id](../Identifiers.md#dsnp-user-id)
+- MUST have authorized the creation of the Announcement, either directly or via a transparent chain of delegation
+
+### subject
+
+- MUST be a [DSNP Content URI](../Identifiers.md#dsnp-content-uri)
+
+### url
+
+- MUST NOT refer to localhost or any reserved IP addresses as defined in [RFC6890](https://datatracker.ietf.org/doc/html/rfc6890)
+- Resource MUST be a Verifiable Credential Document
+- MUST use one of the supported URL Schemes
+
+#### Supported URL Schemes
+
+| Scheme | Description | Reference | DSNP Version Added |
+| ------ |------------ | --------- | ------------------ |
+| HTTPS | Hypertext Transfer Protocol Secure | [RFC2818](https://datatracker.ietf.org/doc/html/rfc2818) | 1.3 |
+
+### contentHash
+
+- MUST be a [DSNP Content Hash](../Identifiers.md#dsnp-content-hash)
+
+### attributeSetType
+
+- MUST be a valid [Attribute Set Type canonical name](../Identifiers.md#attribute-set-type-canonical-name)
+
+### issuer
+
+- MUST be a valid URI
+- MUST match the `issuer` value from the credential document retrieved from `url`
diff --git a/pages/DSNP/Types/ExternalContentAttributeSet.md b/pages/DSNP/Types/ExternalContentAttributeSet.md
new file mode 100644
index 00000000..ab33b095
--- /dev/null
+++ b/pages/DSNP/Types/ExternalContentAttributeSet.md
@@ -0,0 +1,63 @@
+# External Content Attribute Set Announcement
+
+An External Content Attribute Set Announcement is a way to create an authenticated (and, optionally, attested) attribute set for content external to the DSNP system.
+
+## Fields
+
+| Field | Description | Data Type | Serialization | Parquet Type | Bloom Filter |
+| ----- | ----------- | --------- | ------------- | ------------ | ------------ |
+| announcementType | Announcement Type Enum (`10`) | enum | [decimal](../Serializations.md#decimal) | `INT32` | no |
+| fromId | id of the user creating the Announcement | 64 bit unsigned integer | [decimal](../Serializations.md#decimal) | `UINT_64` | YES |
+| subject | URL of the external content | URL | `UTF-8` | `UTF8` | no |
+| subjectContentHash | multihash-encoded hash of subject document | variable length byte array | [hexadecimal](../Serializations.md#hexadecimal) | `BYTE_ARRAY` | YES |
+| url | URL for the Verifiable Credential document | `UTF-8` | `UTF-8` | `UTF8` | YES |
+| contentHash | multihash-encoded hash of content stored at URL | variable length byte array | [hexadecimal](../Serializations.md#hexadecimal) | `BYTE_ARRAY` | YES |
+| attributeSetType | Canonical name of attribute set type | `UTF-8` | `UTF-8` | `UTF8` | YES |
+| issuer | URI of issuer | `UTF-8` | `UTF-8` | `UTF8` | YES |
+
+## Field Requirements
+
+### announcementType
+
+- MUST be fixed to `10`
+
+### fromId
+
+- MUST be a [DSNP User Id](../Identifiers.md#dsnp-user-id)
+- MUST have authorized the creation of the Announcement, either directly or via a transparent chain of delegation
+
+### subject
+
+Optional. If present,
+
+- MUST NOT refer to localhost or any reserved IP addresses as defined in [RFC6890](https://datatracker.ietf.org/doc/html/rfc6890)
+- MUST use one of the supported URL Schemes
+
+### subjectContentHash
+
+- MUST be a [DSNP Content Hash](../Identifiers.md#dsnp-content-hash)
+
+### url
+
+- MUST NOT refer to localhost or any reserved IP addresses as defined in [RFC6890](https://datatracker.ietf.org/doc/html/rfc6890)
+- Resource MUST be a Verifiable Credential Document
+- MUST use one of the supported URL Schemes
+
+### contentHash
+
+- MUST be a [DSNP Content Hash](../Identifiers.md#dsnp-content-hash)
+
+### attributeSetType
+
+- MUST be a valid [Attribute Set Type canonical name](../Identifiers.md#attribute-set-type-canonical-name)
+
+### issuer
+
+- MUST be a valid URI
+- MUST match the `issuer` value from the credential document retrieved from `url`
+
+#### Supported URL Schemes
+
+| Scheme | Description | Reference | DSNP Version Added |
+| ------ |------------ | --------- | ------------------ |
+| HTTPS | Hypertext Transfer Protocol Secure | [RFC2818](https://datatracker.ietf.org/doc/html/rfc2818) | 1.3 |
diff --git a/pages/DSNP/Types/PublicKey.md b/pages/DSNP/Types/PublicKey.md
index fbefb8cf..6c0eec3e 100644
--- a/pages/DSNP/Types/PublicKey.md
+++ b/pages/DSNP/Types/PublicKey.md
@@ -33,6 +33,7 @@ The most recently published key (if one exists) for a given key type should be t
| Value | Name | Allowed Algorithms ([multicodec](https://github.com/multiformats/multicodec/blob/master/table.csv)) | Purpose |
| --- | --- | --- | --- |
| 1 | `keyAgreement` | `x25519-pub` | A Curve25519 public key that can be used in key exchange protocols to generate a shared secret |
+| 2 | `assertionMethod` | `ed25519-pub` | A public key that can be used for verifying digital signature proofs of verifiable credentials |
### keyId
diff --git a/pages/DSNP/Types/Tombstone.md b/pages/DSNP/Types/Tombstone.md
index de8187f9..70e96b8a 100644
--- a/pages/DSNP/Types/Tombstone.md
+++ b/pages/DSNP/Types/Tombstone.md
@@ -34,6 +34,9 @@ It is NOT possible to revert a tombstone.
|------ | ---- |
| 2 | [Broadcast](../Types/Broadcast.md) |
| 3 | [Reply](../Types/Reply.md) |
+| 8 | [User Attribute Set](../Types/UserAttributeSet.md) |
+| 9 | [DSNP Content Attribute Set](../Types/DSNPContentAttributeSet.md) |
+| 10 | [External Content Attribute Set](../Types/ExternalContentAttributeSet.md) |
### targetContentHash
diff --git a/pages/DSNP/Types/UserAttributeSet.md b/pages/DSNP/Types/UserAttributeSet.md
new file mode 100644
index 00000000..58bd9117
--- /dev/null
+++ b/pages/DSNP/Types/UserAttributeSet.md
@@ -0,0 +1,55 @@
+# User Attribute Set Announcement
+
+A User Attribute Set Announcement is a way to create an authenticated (and, optionally, attested) attribute set for a DSNP User.
+
+## Fields
+
+| Field | Description | Data Type | Serialization | Parquet Type | Bloom Filter |
+| ----- | ----------- | --------- | ------------- | ------------ | ------------ |
+| announcementType | Announcement Type Enum (`8`) | enum | [decimal](../Serializations.md#decimal) | `INT32` | no |
+| fromId | id of the user creating the Announcement | 64 bit unsigned integer | [decimal](../Serializations.md#decimal) | `UINT_64` | YES |
+| subject | DSNP User Id of the attribute set subject | 64 bit unsigned integer | decimal | `UINT_64` | YES |
+| url | URL for the Verifiable Credential Document (optional) | `UTF-8` | `UTF-8` | `UTF8` | no |
+| contentHash | multihash-encoded hash of content stored at URL | variable length byte array | [hexadecimal](../Serializations.md#hexadecimal) | `BYTE_ARRAY` | YES |
+| attributeSetType | Canonical name of attribute set type | `UTF-8` | `UTF-8` | `UTF8` | YES |
+| issuer | URI of issuer | `UTF-8` | `UTF-8` | `UTF8` | YES |
+
+## Field Requirements
+
+### announcementType
+
+- MUST be fixed to `8`
+
+### fromId
+
+- MUST be a [DSNP User Id](../Identifiers.md#dsnp-user-id)
+- MUST have authorized the creation of the Announcement, either directly or via a transparent chain of delegation
+
+### subject
+
+- MUST be a [DSNP User Id](../Identifiers.md#dsnp-user-id)
+
+### url
+
+- MUST NOT refer to localhost or any reserved IP addresses as defined in [RFC6890](https://datatracker.ietf.org/doc/html/rfc6890)
+- Resource MUST be a Verifiable Credential Document
+- MUST use one of the supported URL Schemes
+
+#### Supported URL Schemes
+
+| Scheme | Description | Reference | DSNP Version Added |
+| ------ |------------ | --------- | ------------------ |
+| HTTPS | Hypertext Transfer Protocol Secure | [RFC2818](https://datatracker.ietf.org/doc/html/rfc2818) | 1.3 |
+
+### contentHash
+
+- MUST be a [DSNP Content Hash](../Identifiers.md#dsnp-content-hash)
+
+### attributeSetType
+
+- MUST be a valid [Attribute Set Type canonical name](../Identifiers.md#attribute-set-type-canonical-name)
+
+### issuer
+
+- MUST be a valid URI
+- MUST match the `issuer` value from the credential document retrieved from `url`
diff --git a/pages/SUMMARY.md b/pages/SUMMARY.md
index db8a0f1f..a4ab22e6 100644
--- a/pages/SUMMARY.md
+++ b/pages/SUMMARY.md
@@ -9,6 +9,7 @@
- [Graph Edge](DSNP/Types/GraphEdge.md)
- [PRId](DSNP/Types/PRId.md)
- [Batch Publications](DSNP/BatchPublications.md)
+ - [Attribute Sets](DSNP/AttributeSets.md)
- [Announcements](DSNP/Announcements.md)
- [Tombstone](DSNP/Types/Tombstone.md)
- [Broadcast](DSNP/Types/Broadcast.md)
@@ -17,6 +18,9 @@
- [Profile](DSNP/Types/Profile.md)
- [Update](DSNP/Types/Update.md)
- [Public Key](DSNP/Types/PublicKey.md)
+ - [User Attribute Set](DSNP/Types/UserAttributeSet.md)
+ - [DSNP Content Attribute Set](DSNP/Types/DSNPContentAttributeSet.md)
+ - [External Content Attribute Set](DSNP/Types/ExternalContentAttributeSet.md)
- [Migrated Announcements](DSNP/Migrated.md)
- [Graph Change](DSNP/Types/GraphChange.md)
- [Operations](DSNP/Operations.md)
@@ -38,4 +42,8 @@
- [Location](ActivityContent/Associated/Location.md)
- [Tag](ActivityContent/Associated/Tag.md)
- [Attachments](ActivityContent/Associated/Attachments.md)
+- [Verifiable Credentials](VerifiableCredentials/Overview.md)
+ - [Verifiable Credential](VerifiableCredentials/Types/VerifiableCredential.md)
+ - [Verifiable Credential Schema](VerifiableCredentials/Types/VerifiableCredentialSchema.md)
+ - [DID](VerifiableCredentials/Types/DID.md)
- [Glossary](Reference/Glossary.md)
diff --git a/pages/VerifiableCredentials/Overview.md b/pages/VerifiableCredentials/Overview.md
new file mode 100644
index 00000000..d35d898a
--- /dev/null
+++ b/pages/VerifiableCredentials/Overview.md
@@ -0,0 +1,75 @@
+# Verifiable Credentials Specification
+__Version pre-1.3.0__
+
+[Attribute Sets](../DSNP/AttributeSets.md) and [Interaction](../ActivityContent/Associated/Tag.md#interaction) tags shared via DSNP reference data documents containing Verifiable Credentials and related objects.
+For DSNP purposes, certain restrictions and extensions are applied to the base World Wide Web Consortium (W3C) specification documents noted below.
+When there are DSNP extensions, they are guaranteed to use non-colliding terms.
+
+It is anticipated that these W3C specifications will evolve, and applications interacting with Verifiable Credentials, Schemas, and DIDs via DSNP are encouraged to be as flexible as possible in their syntax support as new versions and supporting software libraries become available.
+Therefore, compatibility with the following versions and specifications should be construed as the minimal level of support required to ensure interoperability between DSNP applications.
+
+## Compatibility
+
+Current usage with DSNP relies on the following specifications:
+
+| Specification | Version/Status | Relevant JSON-LD `@context` Values |
+| --- | --- | --- |
+ | Verifiable Credentials Data Model | [1.1 (W3C Recommendation)](https://www.w3.org/TR/vc-data-model-1.1) | `https://www.w3.org/2018/credentials/v1` |
+ | Verifiable Credential Data Integrity | [1.0 (W3C Candidate Recommendation Draft 15 March 2024)](https://www.w3.org/TR/2024/CRD-vc-data-integrity-20240315/) | `https://w3id.org/security/data-integrity/v2` |
+ | Verifiable Credentials JSON Schema | [(W3C Candidate Recommendation Draft 18 December 2023)](https://www.w3.org/TR/2023/CRD-vc-json-schema-20231218/) | |
+ | Decentralized Identifiers (DIDs) | [1.0 (W3C Recommendation 19 July 2022)](https://www.w3.org/TR/2022/REC-did-core-20220719/) | `https://www.w3.org/ns/did/v1` |
+
+### Cryptography
+
+The Data Integrity specification provides a generic format for expressing cryptographic proofs, where the detailed representation of each data item is defined in individual cryptosuites.
+DSNP compliant applications MUST support the following cryptosuites, which correspond to the allowed algorithms for `assertionMethod` [Public Keys](../DSNP/Types/PublicKey.md):
+
+| Specification | Version/Status | Multikey codec |
+| --- | --- | --- |
+| Data Integrity EdDSA Cryptosuites | [1.0 (W3C Candidate Recommendation Draft 03 March 2024)](https://www.w3.org/TR/2024/CRD-vc-di-eddsa-20240303/) | `ed25519-pub` |
+
+
+## DSNP Usage Details
+
+DSNP incorporates the following W3C JSON-LD types.
+See the individual pages for details of restrictions to and extensions on each type.
+
+| Name | Description |
+| --- | --- |
+ | [Verifiable Credential](./Types/VerifiableCredential.md) | [Verifiable Credentials Data Model 1.1 (W3C Recommendation)](https://www.w3.org/TR/vc-data-model-1.1)
[Verifiable Credential Data Integrity 1.0 (W3C Candidate Recommendation Draft 15 March 2024)](https://www.w3.org/TR/2024/CRD-vc-data-integrity-20240315/) |
+ | [Verifiable Credential Schema](./Types/VerifiableCredentialSchema.md) | [Verifiable Credentials JSON Schema (W3C Candidate Recommendation Draft 18 December 2023)](https://www.w3.org/TR/2023/CRD-vc-json-schema-20231218/) |
+ | [DID](./Types/DID.md) | [Decentralized Identifiers (DIDs) v1.0 (W3C Recommendation 19 July 2022)](https://www.w3.org/TR/2022/REC-did-core-20220719/) |
+
+## Libraries
+
+| Name | Language(s) |
+| --- | --- |
+| [LibertyDSNP/dsnp-verifiable-credentials](https://github.com/LibertyDSNP/dsnp-verifiable-credentials) | JavaScript/TypeScript |
+| [LibertyDSNP/dsnp-did-resolver](https://github.com/LibertyDSNP/dsnp-did-resolver) | JavaScript/TypeScript |
+
+
+## Prerelease Changelog
+
+- [DIP-257](https://github.com/LibertyDSNP/spec/issues/257) Attribute Sets and Attestation
+
+
+
+## Non-Normative
+
+## Additional Fields
+
+Implementers may choose to support more of the relevant JSON-LD vocabularies from the specifications above as long as it does not conflict with this specification, but should note that other implementations may not recognize those additions.
+Implementers who extend their support for Verifiable Credentials objects beyond the subset defined here do so at their own risk.
+
+## Verifiable Presentations
+
+[Verifiable Presentations](https://www.w3.org/TR/vc-data-model-1.1/#presentations-0) combine one or more Verifiable Credentials in a single document.
+These might be existing Verifiable Credentials, whether or not previously published, or new Verifiable Credentials derived from non-public source credentials using methods like zero-knowledge proofs.
+At this time, Verifiable Presentations are not directly tied to DSNP content or announcements.
+However, application and service providers may be interested in implementing functionality using Verifiable Presentations with DSNP Verifiable Credentials.
+Applications are encouraged to follow the verification guidelines for DSNP Verifiable Credentials even when encountering those credentials as part of a Verifiable Presentation.
diff --git a/pages/VerifiableCredentials/Types/DID.md b/pages/VerifiableCredentials/Types/DID.md
new file mode 100644
index 00000000..d37cb6ca
--- /dev/null
+++ b/pages/VerifiableCredentials/Types/DID.md
@@ -0,0 +1,68 @@
+# DIDs
+
+DSNP Users are referenced in Verifiable Credentials documents in compliance with the [Decentralized Identifiers v1.0](https://www.w3.org/TR/did-core/) specification.
+
+Applications that make use of Verifiable Credentials issued by DSNP Users MUST be able to resolve DSNP User DIDs to DID documents in order to verify that signatures were created with keys controlled by that user.
+A DSNP DID document is effectively a document aggregating DSNP User Data.
+Compliant DSNP systems are encouraged to provide their own DID resolver libraries.
+
+## DID Method Syntax
+
+A DSNP DID uses `dsnp` (lowercase) as the method name and the DSNP User Id as the method-specific identifier, as the following example illustrates:
+
+`did:dsnp:123456`
+
+This DID identifies the DSNP User with User Id 123456.
+In this format, the DSNP User Id is represented in decimal form.
+
+References to identifiers within a DID document are formed by appending URL fragments to a DID.
+For example, a Verifiable Credential might reference the public key to be used to verify a document's signature as `did:dsnp:123456#key1`, assuming the document included a `verificationMethod` with `"id": "key1"`.
+
+## DID Document
+
+A DSNP DID document is a JSON-LD document representing key material associated with a DSNP User.
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `@context` | YES | Array of strings | JSON-LD @context | MUST include `"https://www.w3.org/ns/did/v1"` |
+| `id` | YES | String | The DID described by this document | MUST be of the form `did:dsnp:{userId}` |
+| `verificationMethod` | NO | Array of Verification Method objects | Set of public keys that may be referenced from `assertionMethod` and `keyAgreement` arrays |
+| `assertionMethod` | NO | Array | Set of public keys used to generate digital signatures | MUST include or reference all relevant keys present in DSNP User Data |
+| `keyAgreement` | NO | Array | Set of public keys used to generate shared secrets | MUST include or reference all relevant keys present in DSNP User Data |
+
+### Public Key Representation
+
+As per the DID specification, each element of the `assertionMethod` and `keyAgreement` arrays may be a string reference to the object with a matching `id` field in the `verificationMethod` array, or the Verification Method object itself.
+Each Verification Method describes a public key.
+These keys MUST be taken from the DSNP User Data associated with the user referenced by the DID.
+
+DSNP DID resolvers MUST serialize keys in the Multikey format, defined in [Verifiable Credential Data Integrity 1.0](https://www.w3.org/TR/vc-data-integrity/).
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `@context` | YES | String | JSON-LD @context | MUST be `https://w3id.org/security/multikey/v1` |
+| `id` | YES | String | The full URI of this key | MUST be of the form `did:dsnp:{userId}#{identifier}`; MUST be unique within the document |
+| `type` | YES | String | The type of this verification method | MUST be `Multikey` |
+| `controller` | YES | String | The controller of this key | MUST be the DID of the enclosing document |
+| `publicKeyMultibase` | YES | String | The public key | MUST be a valid multicodec-prefixed public key in `base58btc` encoding |
+
+## Example
+
+```json
+{
+ "@context": [
+ "https://www.w3.org/ns/did/v1"
+ ],
+ "id": "did:dsnp:13972",
+ "assertionMethod": [
+ {
+ "@context": "https://w3id.org/security/multikey/v1",
+ "id": "did:dsnp:13972#z6MkuzE4hBVHTmwFff37ZuPQs9sbkdJo8jifN9sZ1jXbgyMp",
+ "type": "Multikey",
+ "controller": "did:dsnp:13972",
+ "publicKeyMultibase": "z6MkuzE4hBVHTmwFff37ZuPQs9sbkdJo8jifN9sZ1jXbgyMp"
+ }
+ ],
+ "keyAgreement": []
+}
+```
diff --git a/pages/VerifiableCredentials/Types/VerifiableCredential.md b/pages/VerifiableCredentials/Types/VerifiableCredential.md
new file mode 100644
index 00000000..cd6a149b
--- /dev/null
+++ b/pages/VerifiableCredentials/Types/VerifiableCredential.md
@@ -0,0 +1,133 @@
+# Verifiable Credential
+
+Credentials should conform to the [Verifiable Credentials Data Model 1.1](https://www.w3.org/TR/vc-data-model-1.1/), expressed as JSON-LD.
+The fields noted below consist only of those with requirements or semantics that differ from the underlying specification.
+
+## JSON-LD Contexts
+
+The following JSON-LD context values are valid for use with DSNP:
+
+| Object | `@context` |
+| --- | --- |
+| Verifiable Credential | `https://www.w3.org/2018/credentials/v1` |
+
+## Verifiable Credential Document
+
+A DSNP Verifiable Credential JSON document specializes the following fields:
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `@context` | YES | Array of strings | JSON-LD @context | MUST include `"https://www.w3.org/2018/credentials/v1"` |
+| `type` | YES | Array of strings | Type of credential | MUST contain `"VerifiableCredential"` per specification; if a `credentialSchema` is present, MUST also contain a string matching the referenced JSON Schema's `title`. |
+| `issuer` | YES | String or Object | DID or object identifying credential issuer | See below |
+|`credentialSubject` | YES | Object | Object identifying subject and claim | See below |
+| `credentialSchema` | no | Object | Reference to schema for this credential | See below |
+| `proof` | no | Object | Cryptographic proof of authorship by `issuer` | See below |
+
+### Issuer
+
+The `issuer` field is required, even for credentials that do not include a `proof`.
+Unsigned documents should still use the document creator's DID.
+
+The `issuer` field may be a string that is the issuer's DID, or an object with the issuer's DID as the `id` property.
+
+In the object form, the issuer may optionally include references to its own credentials, which may be used by a verifier processing the DSNP [trust extension](./VerifiableCredentialSchema.md#trust-extension).
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `id` | YES | String | DID of issuer | Must be a [DSNP DID](./DID.md) |
+| `authority` | no | Array | List of relevant credentials with issuer as subject | See below |
+
+Objects in the `authority` array MUST have the following properties:
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `id` | YES | String | URL of Verifiable Credential | MUST be a DSNP Verifiable Credential |
+| `rel` | YES | String | The linked credential's attribute set type | MUST be a DSNP [Attribute Set Type](../../DSNP/AttributeSets.md#attribute-set-type) corresponding to the referenced credential document |
+| `hash` | YES | Array | Array of hashes for linked content validation | MUST include at least one [supported hash](../../ActivityContent/Associated/Hash.md#supported-algorithms) |
+
+Examples:
+
+```
+"issuer": "did:dsnp:86420"
+```
+
+```
+"issuer": {
+ "id": "did:dsnp:86420",
+ "authority": [
+ {
+ "id": "https://mydsnpcreds.net/86420-fp",
+ "rel": "did:dsnp:123456$FairTradeProducer",
+ "hash": [
+ "QmQrGdv6Ky5sJhaVdw27y4aod5pdfihDkBTxiBkRaSGJJ7"
+ ]
+ },
+ {
+ "id": "https://mydsnpcreds.net/86420-ap",
+ "rel": "did:dsnp:123456$AppleProducer",
+ "hash": [
+ "2Drjgb4a8eC4XheBKCBcbAcaVdEWcKjMbCSZ2L2c9CQs4x98jf"
+ ]
+ }
+ ]
+}
+```
+
+### Credential Subject
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `id` | YES | String | Subject of the claim data | If describing a DSNP User, MUST be a [DSNP User URI](../../DSNP/Identifiers.md#dsnp-user-uri); if describing DSNP content, MUST be a [DSNP Content URI](../../DSNP/Identifiers.md#dsnp-content-uri) |
+
+The remainder of the contents of the `credentialSubject` value MUST conform to the JSON schema found via the `credentialSchema` object.
+
+### Credential Schema
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `id` | YES | String | URL of schema document | MUST reference a [DSNP Verifiable Credential Schema](./VerifiableCredentialSchema.md) |
+
+### Proof
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `type` | YES | String | Proof type | MUST be `DataIntegrityProof` |
+| `verificationMethod` | YES | String | URI of public key | MUST reference a public key within a [DSNP DID](./DID.md) document |
+| `cryptosuite` | YES | String | Cryptographic algorithm identifier | MUST be `eddsa-rdfc-2022` |
+| `proofPurpose` | YES | String | Context for assessing proof | MUST be `assertionMethod` |
+| `proofValue` | YES | String | Digital signature proof | MUST be a multibase-encoded signature using `base58btc` encoding |
+
+## Example
+
+```json
+{
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2"
+ ],
+ "type": [
+ "VehicleOwner",
+ "VerifiableCredential"
+ ],
+ "issuer": "did:dsnp:654321",
+ "issuanceDate": "2024-02-12T03:09:40.497Z",
+ "credentialSchema": {
+ "type": "JsonSchemaCredential",
+ "id": "https://dsnp.org/schema/examples/vehicle_owner.json"
+ },
+ "credentialSubject": {
+ "id": "did:dsnp:999999",
+ "make": "DeLorean",
+ "model": "DMC-12",
+ "year": 1981
+ },
+ "proof": {
+ "type": "DataIntegrityProof",
+ "created": "2024-02-12T03:09:44Z",
+ "verificationMethod": "did:dsnp:654321#z6Mkumvf8FpJybzi9byLX7qAhTPuKpqH7d5rWyqcrKJ9Mies",
+ "cryptosuite": "eddsa-rdfc-2022",
+ "proofPurpose": "assertionMethod",
+ "proofValue": "z2YLydotgaGsbRGRxPzmoscd7dH5CgGHydXLKXJXefcT2SJGExtxmkJxGfUGoe81Vm62JGEYrwcS6ht1ixEvuZF9c"
+ }
+}
+```
diff --git a/pages/VerifiableCredentials/Types/VerifiableCredentialSchema.md b/pages/VerifiableCredentials/Types/VerifiableCredentialSchema.md
new file mode 100644
index 00000000..f0b47f74
--- /dev/null
+++ b/pages/VerifiableCredentials/Types/VerifiableCredentialSchema.md
@@ -0,0 +1,182 @@
+# Verifiable Credential Schema
+
+The schema for a DSNP Verifiable Credential MAY be defined using the format described in the [Verifiable Credentials JSON Schema](https://www.w3.org/TR/vc-json-schema/) W3C Candidate Recommendation Draft.
+This format provides a credential wrapper around a JSON schema document.
+
+Empty schemas (Verifiable Credential Schema Documents with `"jsonSchema": {}`) are allowed; however, schemaless credentials may be preferred in this situation.
+Empty schemas are useful in situations where no attribute data fields are relevant but the schema author wishes to assert authorship.
+
+## Verifiable Credential Schema Document
+
+A Verifiable Credential Schema document is a JSON-LD document that is itself a [Verifiable Credential](./VerifiableCredential.md) with a claim that includes the schema and (optionally) the DSNP extension described below.
+A schema credential specializes the meaning of the following fields:
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `type` | YES | Array of strings | Type of credential | MUST contain the strings `"VerifiableCredential"` and `"JsonSchemaCredential"` |
+|`credentialSubject` | YES | Object | Object containing JSON schema and DSNP extensions | See below |
+| `credentialSchema` | YES | Object | Metaschema defining JSON Schema types | See below for required contents |
+
+### Credential Schema
+The required `credentialSchema` object MUST follow the specification and contain:
+
+```
+{
+ "id": "https://www.w3.org/2022/credentials/v2/json-schema-credential-schema.json",
+ "type": "JsonSchema",
+ "digestSRI": "sha384-S57yQDg1MTzF56Oi9DbSQ14u7jBy0RDdx0YbeV7shwhCS88G8SCXeFq82PafhCrW"
+}
+```
+
+### Credential Subject
+
+A DSNP Verifiable Credential Schema document's `credentialSubject` object uses the following keys:
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `type` | YES | String | Type of subject matter | MUST be `JsonSchema` |
+| `jsonSchema` | YES | Object | Embedded JSON Schema object | See below |
+| `dsnp` | NO | Object | DSNP extension object | See below |
+
+#### JSON Schema
+
+The JSON Schema object is formed as follows:
+
+| Property | Required | JSON Type | Description | Restrictions |
+| --- | --- | --- | --- | --- |
+| `$schema` | YES | String | JSON Schema version identifier | MUST be a valid DSNP JSON Schema version |
+| `title` | YES | String | Title of the schema | MUST match a string within the referencing credential's `type` array |
+
+The remainder of the schema object should be interpreted as per the relevant JSON schema specification.
+
+##### Valid DSNP JSON Schema versions
+
+DSNP applications MUST support the following JSON Schema versions:
+
+| `$schema` value | Specification |
+| --- | --- |
+| `https://json-schema.org/draft/2020-12/schema` | [JSON Schema 2020-12 Update](https://json-schema.org/draft/2020-12/release-notes) |
+
+Other JSON Schema versions MAY be supported, but creators should be aware that not all DSNP applications will be able to correctly validate credentials against schema definitions that are not universally supported.
+
+#### DSNP Extensions
+
+An optional `dsnp` object within the `credentialSubject` provides additional semantics for DSNP applications and users interacting with the schema.
+
+##### Display Extension
+
+The optional `display` key within the `dsnp` extension object MUST contain a `label` key that has an object value where the object is a map of one or more language tags to human-readable string values.
+Language tags should follow [BCP-47/RFC-5646](https://www.rfc-editor.org/rfc/rfc5646.html) (as used in the HTTP `Content-Language` header).
+A content language key of `"*"` indicates a wildcard or default value, as in HTTP.
+
+Example:
+```json
+"display": {
+ "label": {
+ "en-US": "Verified User",
+ "de-DE": "Verifizierter Benutzer"
+ }
+}
+```
+
+A DSNP application MAY use the indicated values as a hint when displaying information about the subject of a Verifiable Credential utilizing this schema.
+
+##### Trust Extension
+
+The optional `trust` key within the `dsnp` extension object enables the author of a schema to describe the types of Verifiable Credentials that an issuer of credentials with this schema must have to be considered an accredited source and therefore trusted by an application.
+These accreditations MUST be included by the issuer using the `authority` key under `issuer` in each relevant [Verifiable Credential](./VerifiableCredential.md#issuer) document they create.
+
+The `trust` object contains one or both of the `oneOf` or `allOf` keys, each containing an array of strings.
+Each string MUST be a valid DSNP Attribute Set Type.
+
+See [Attribute Sets](../../DSNP/AttributeSets.md) for a detailed discussion of Attribute Set Types and their derivation.
+
+A `trust` object containing both `oneOf` and `allOf` sections should be construed as requiring any of the `oneOf` constraints as well as all of the `allOf` constraints.
+
+Example:
+```json
+"trust": {
+ "oneOf": [
+ "did:dsnp:123456$AppleProducer",
+ "did:dsnp:123456$OrangeProducer"
+ ],
+ "allOf": [
+ "did:dsnp:999999$FairTradeProducer"
+ ]
+}
+```
+
+The above example might be translated as "A credential conforming to this schema should only be trusted if its issuer is accredited as a `FairTradeProducer` and is also either an `AppleProducer` or an `OrangeProducer`."
+
+## Example
+
+```json
+{
+ "@context": [
+ "https://www.w3.org/ns/credentials/v2"
+ ],
+ "id": "https://dsnp.org/schema/examples/vehicle_owner.json",
+ "type": [
+ "VerifiableCredential",
+ "JsonSchemaCredential"
+ ],
+ "issuer": "did:dsnp:123456",
+ "issuanceDate": "2024-02-12T03:09:40.497Z",
+ "expirationDate": "2099-01-01T00:00:00.000Z",
+ "credentialSchema": {
+ "id": "https://www.w3.org/2022/credentials/v2/json-schema-credential-schema.json",
+ "type": "JsonSchema",
+ "digestSRI": "sha384-S57yQDg1MTzF56Oi9DbSQ14u7jBy0RDdx0YbeV7shwhCS88G8SCXeFq82PafhCrW"
+ },
+ "credentialSubject": {
+ "type": "JsonSchema",
+ "jsonSchema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "title": "VehicleOwner",
+ "type": "object",
+ "properties": {
+ "credentialSubject": {
+ "type": "object",
+ "properties": {
+ "make": {
+ "type": "string"
+ },
+ "model": {
+ "type": "string"
+ },
+ "year": {
+ "type": "number"
+ }
+ },
+ "required": [
+ "make",
+ "model",
+ "year"
+ ]
+ }
+ }
+ },
+ "dsnp": {
+ "display": {
+ "label": {
+ "en-US": "Vehicle Owner"
+ }
+ },
+ "trust": {
+ "oneOf": [
+ "did:dsnp:123456$CarDealership",
+ "did:dsnp:123456$TaxOffice"
+ ]
+ }
+ }
+ },
+ "proof": {
+ "type": "DataIntegrityProof",
+ "created": "2024-02-12T03:09:44Z",
+ "verificationMethod": "did:dsnp:123456#z6MkhFqFV1UD6GYbQ1V4HSF3pnGprovQceXbgwbLKrhxnbny",
+ "cryptosuite": "eddsa-rdfc-2022",
+ "proofPurpose": "assertionMethod",
+ "proofValue": "z3ENMBo7UyKvZkJSBMqvGFDB1uvGChP1QTEgiCsNzt23ciq4RTffk2xxz2noXxxHL6wPmN1Bp2fSvTuMnvHQFP9tp"
+ }
+}
+```
diff --git a/pages/index.md b/pages/index.md
index f12377fd..2b5089a3 100644
--- a/pages/index.md
+++ b/pages/index.md
@@ -11,12 +11,13 @@ Through the DSNP, we hope to mitigate and ideally solve these challenges in the
## How to Read This Specification
-There are three core specifications currently.
+There are three core specifications and one system specification currently.
| Name | Version | Description |
| --- | --- | --- |
-| [DSNP](DSNP/Overview.md) | 1.2.0 | The system-agnostic DSNP specification |
-| [Activity Content](ActivityContent/Overview.md) | 1.2.0 | A specification for DSNP-referenced content (subset of W3C Activity Streams) |
+| [DSNP](DSNP/Overview.md) | pre-1.3.0 | The system-agnostic DSNP specification |
+| [Activity Content](ActivityContent/Overview.md) | pre-1.3.0 | A specification for DSNP-referenced content (subset of W3C Activity Streams) |
+| [Verifiable Credentials](VerifiableCredentials/Overview.md) | pre-1.3.0 | Use of W3C Verifiable Credentials and DIDs with DSNP |
| [DSNP Over Frequency](Frequency/Overview.md) | - | DSNP Over Frequency specification |
Each specification is divided into several modules.