diff --git a/.spellcheckerdict.txt b/.spellcheckerdict.txt
index 9e00df04..20d3b397 100644
--- a/.spellcheckerdict.txt
+++ b/.spellcheckerdict.txt
@@ -1,8 +1,12 @@
-Alexa
+accreditations
announcementType
+attributeSetType
+attributeSetTypeName
+attributeSetTypeNamespace
Avro
base32
Base58
+BCP-47
BLAKE3
Brötli
CalVer
@@ -13,21 +17,25 @@ changeType
[Cc]odec('s)?
contentAddress
contentHash
-cryptographic
+[Cc]ryptographic
cryptographically
+[Cc]ryptosuites
CtxSharedSecretA
CtxSharedSecretB
CtxSharedSecretBob
Curve25519
decrypt(ed)?
Delegator
-[Dd]eserialize(d)?
+[Dd]eserialize(d?)
+DIDs
Diffie-Hellman
discoverability
[Dd]iscoverable
DSNP
DSNP-compatible
+dsnp-did-resolver
DSNP-referenced
+dsnp-verifiable-credentials
ECIES
EdDSA
[Ee]num(s)?
@@ -36,6 +44,7 @@ Ethereum
Extrinsics
fromId
GraphEdge
+hashcode
H265
HBASE
HTTPS
@@ -53,32 +62,42 @@ LibertyDSNP
libsodium
little-endian
localhost
+localizable
+lookups
Mainnet
mdBook
MDX
+Metaschema
MP[34]
MSA
[Mm]ultibase
+[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
Prepending
-Prerelease
+[Pp]rerelease
PRId([ABs])?
ProfileResource
+pseudonymously
[Pp]ublicKey
repo
+resolvers
RFC[1-9][0-9]*
Ristretto
RPC
@@ -91,7 +110,9 @@ SHA-256
SHA-512
Stateful
stringified
-subkey
+subjectContentHash
+subkey(s?)
+substring
SVG
targetAnnouncementType
targetContentHash
@@ -103,6 +124,7 @@ UINT_8
uncompress
unencrypted
[Uu]nfollow(ed)?
+unhashed
URI
url
userId
@@ -110,10 +132,13 @@ UTF-8
v[0-9]+(\.[0-9]+)*
vanishingly
varint
+[Vv]erifier(s?)
+verifiability
W3C
WebM
WebP
websocket
[Ww]hitepaper
+whitespace
X25519
XSalsa20
diff --git a/STYLEGUIDE.md b/STYLEGUIDE.md
index bf508811..78f9002f 100644
--- a/STYLEGUIDE.md
+++ b/STYLEGUIDE.md
@@ -4,50 +4,100 @@ 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)
+
+## Activity Content
+Uppercase A and C
+
+## 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 +105,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 +131,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 +149,70 @@ 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
+Uppercase V and C. Singular for one document/credential; plural when referring to the specification.
+If followed by "document", that should be lowercase.
+
+## Verifiable Credential Schema
+Uppercase V, C, S.
+If followed by "document", that should be lowercase.
+
## 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
+
+## YES and no
+When describing required items, use an all caps "YES", otherwise a lowercase "no".
diff --git a/book.toml b/book.toml
index 02905339..f9684958 100644
--- a/book.toml
+++ b/book.toml
@@ -17,7 +17,7 @@ preferred-dark-theme = "coal"
[output.linkcheck]
follow-web-links = true
traverse-parent-directories = false
-exclude = ['en\.bitcoin\.it', 'github\.com/LibertyDSNP/spec']
+exclude = ['en\.bitcoin\.it', 'github\.com/LibertyDSNP/spec', 'w3\.org']
[output.html.fold]
enable = true
diff --git a/pages/ActivityContent/Associated/Attachments.md b/pages/ActivityContent/Associated/Attachments.md
index 39118ca9..493a0b30 100644
--- a/pages/ActivityContent/Associated/Attachments.md
+++ b/pages/ActivityContent/Associated/Attachments.md
@@ -208,3 +208,57 @@
"published": "1970-01-01T00:00:00+00:00"
}
```
+
+## Attestations
+
+Attestation attachments are DSNP extensions to the Activity Content model that allow users to attach Verifiable Credentials corresponding to an Attribute Set Type with their DSNP profile or a social media post.
+
+The Verifiable Credential found at the indicated URL must include the user's [DSNP User URI](../../DSNP/Identifiers.md#dsnp-user-uri) 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 | |
+
+### Verifiable Credential Link
+
+Attestation attachments must contain a link to a 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`](https://www.w3.org/TR/vc-data-model-2.0/#vc-ld-media-type) |
+| `hash` | [DSNP extension](Hash.md) | YES | Array of hashes for linked content validation | MUST include at least one [supported hash](Hash.md#supported-algorithms) |
+
+#### 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$AcmeMedicalAssociationPhysician",
+ "href": "https://acmemedicalassn.org/credentials/degree-123.json",
+ "mediaType": "application/vc",
+ "hash": [
+ "bciqdnu347gcfmxzbkhgoubiobphm6readngitfywktdtbdocgogop2q"
+ ]
+ }
+ ]
+ }
+ ],
+ "published": "1970-01-01T00:00:00+00:00"
+}
+```
diff --git a/pages/ActivityContent/Overview.md b/pages/ActivityContent/Overview.md
index 564f3472..a4ac2f2d 100644
--- a/pages/ActivityContent/Overview.md
+++ b/pages/ActivityContent/Overview.md
@@ -45,10 +45,11 @@ 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-273 Content Addressing
+- [DIP-257](https://github.com/LibertyDSNP/spec/issues/257) Attribute Sets and Attestation
+- [DIP-273](https://github.com/LibertyDSNP/spec/issues/273) Content Addressing
## Releases
diff --git a/pages/DSNP/Announcements.md b/pages/DSNP/Announcements.md
index a45157d5..0017fdce 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)~~c | ~~a profile~~ | ~~YES~~ | ~~no~~ |
| 6 | [Update](Types/Update.md) | an update to content| YES | no |
| 7 | ~~[Public Key](Types/PublicKey.md)~~b | ~~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..9ee37a4a
--- /dev/null
+++ b/pages/DSNP/AttributeSets.md
@@ -0,0 +1,167 @@
+# 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 that encodes 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 Verifiable Credential document.
+* If _attributeSetTypeNamespace_ is a DID, it MUST match the issuer of the Verifiable Credential Schema document referenced from the credential document, and the schema document MUST include a proof that can be verified using the issuer'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: `bciqoatksnf4szlitvzfpsdgzegmkmz74i4mpsmb76q7pro42c6fvpzq$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 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.
+
+### 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 expiration date (the `expirationDate` or `validUntil` field), 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 schema document from the URL specified in the `credentialSchema.id` field.
+* For schema of type `JsonSchemaCredential`, validate the schema document against the generic JSON schema for Verifiable Credential Schema, and validate the credential document against the JSON schema found in the Verifiable Credential Schema document's `credentialSubject.jsonSchema` property.
+* For schema of type `JsonSchema`, validate that the schema document is a well formed JSON schema, then validate the credential document against the schema document.
+* Construct the `attributeSetType` for the credential document by following the rules for schemaless, unsigned, or 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 on the credential document, 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.
+When utilizing Verifiable Credential Schema documents, the originator of a DSNP Attribute Set Type can encode its requirements for trusted agents within a DSNP extension field.
+
+To do so, 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, or further embedded `oneOf` or `allOf` groupings.
+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, including Acme Ocean Certification Lab, 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, which is then published online.
+Worldwide Whale Foundation then includes the `did:dsnp:123456$AuthorizedWhaleBiologistCertifier` Attribute Set Type in the `credentialSubject.dsnp.trust.allOf` array of the `CertifiedWhaleBiologist` Verifiable Credential Schema (in this example, using `oneOf` would be equivalent), generates and attaches the signature proof, and publishes the schema document.
+When Acme Ocean Certification Lab wants to issue `did:dsnp:123456$CertifiedWhaleBiologist` credentials to users, it should include the URL, attribute set type, and content hash of its accreditation credential in the `issuer.authority` array of each credential issued.
+A consumer of the credential can retrieve and verify that Acme Ocean Certification Lab is an accredited issuer.
+
+### 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 0e05980d..455cd72c 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 9c72a340..2f4afb08 100644
--- a/pages/DSNP/Overview.md
+++ b/pages/DSNP/Overview.md
@@ -32,9 +32,10 @@ A compliant specification MUST specify a mapping from its system-specific state
## Prerelease Changelog
-- DIP-263 User Data for Public Keys
-- DIP-267 User Data for Profile Resources
-- DIP-273 Content Addressing
+- [DIP-257](https://github.com/LibertyDSNP/spec/issues/257) Attribute Sets and Attestation
+- [DIP-263](https://github.com/LibertyDSNP/spec/issues/263) User Data for Public Keys
+- [DIP-267](https://github.com/LibertyDSNP/spec/issues/267) User Data for Profile Resources
+- [DIP-273](https://github.com/LibertyDSNP/spec/issues/273) Content Addressing
## Releases
diff --git a/pages/DSNP/Types/DSNPContentAttributeSet.md b/pages/DSNP/Types/DSNPContentAttributeSet.md
new file mode 100644
index 00000000..a9e41554
--- /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 | [DSNP Content Hash](../Identifiers.md#dsnp-content-hash) of content | UTF-8 | [base32 multibase](../Serializations.md#base32-multibase) | `UTF8` | 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 valid [DSNP Content Hash](../Identifiers.md#dsnp-content-hash)
+
+### attributeSetType
+
+- MUST be a valid [Attribute Set Type canonical name](../AttributeSets.md#canonical-naming)
+
+### 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..2f27d854
--- /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 | [DSNP Content Hash](../Identifiers.md#dsnp-content-hash) of content at `subject` | UTF-8 | [base32 multibase](../Serializations.md#base32-multibase) | `UTF8` | YES |
+| url | URL for the Verifiable Credential document | `UTF-8` | `UTF-8` | `UTF8` | YES |
+| contentHash | [DSNP Content Hash](../Identifiers.md#dsnp-content-hash) of content at `url` | UTF-8 | [base32 multibase](../Serializations.md#base32-multibase) | `UTF8` | 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 valid [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 valid [DSNP Content Hash](../Identifiers.md#dsnp-content-hash)
+
+### attributeSetType
+
+- MUST be a valid [Attribute Set Type canonical name](../AttributeSets.md#canonical-naming)
+
+### 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 ccce52fe..26e044bf 100644
--- a/pages/DSNP/Types/PublicKey.md
+++ b/pages/DSNP/Types/PublicKey.md
@@ -35,6 +35,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 d09cd0dc..ee471c3d 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..80067af5
--- /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 | `UTF-8` | `UTF-8` | `UTF8` | no |
+| contentHash | [DSNP Content Hash](../Identifiers.md#dsnp-content-hash) of content | UTF-8 | [base32 multibase](../Serializations.md#base32-multibase) | `UTF8` | 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 valid [DSNP Content Hash](../Identifiers.md#dsnp-content-hash)
+
+### attributeSetType
+
+- MUST be a valid [Attribute Set Type canonical name](../AttributeSets.md#canonical-naming)
+
+### 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 14a8f282..6e7dc09d 100644
--- a/pages/SUMMARY.md
+++ b/pages/SUMMARY.md
@@ -11,12 +11,16 @@
- [Public Key](DSNP/Types/PublicKeyUserData.md)
- [ProfileResource](DSNP/Types/ProfileResource.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)
- [Reply](DSNP/Types/Reply.md)
- [Reaction](DSNP/Types/Reaction.md)
- [Update](DSNP/Types/Update.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)
- [Public Key](DSNP/Types/PublicKey.md)
@@ -40,4 +44,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..4db3c859
--- /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 [Attestation](../ActivityContent/Associated/Attachments.md#attestation) attachments 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)
[2.0 (W3C Candidate Recommendation Draft 15 September 2024)](https://www.w3.org/TR/2024/CRD-vc-data-model-2.0-20240915/) | `https://www.w3.org/2018/credentials/v1`
`https://www.w3.org/ns/credentials/v2` |
+ | Verifiable Credential Data Integrity | [1.0 (W3C Candidate Recommendation Draft 16 September 2024)](https://www.w3.org/TR/2024/CRD-vc-data-integrity-20240916/) | `https://w3id.org/security/data-integrity/v2`
`https://w3id.org/security/multikey/v1` |
+ | Verifiable Credentials JSON Schema | [(W3C Candidate Recommendation Draft 12 September 2024)](https://www.w3.org/TR/2023/CRD-vc-json-schema-20240912/) | |
+ | 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 16 September 2024)](https://www.w3.org/TR/2024/CRD-vc-di-eddsa-20240924/) | `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 | Since DSNP Version |
+| --- | --- |
+ | [Verifiable Credential](./Types/VerifiableCredential.md) | 1.3 |
+ | [Verifiable Credential Schema](./Types/VerifiableCredentialSchema.md) | 1.3 |
+ | [DID](./Types/DID.md) | 1.3 |
+
+## 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
+
+DSNP application developers may choose to support more of the relevant JSON-LD vocabularies from the specifications above as long as doing so does not conflict with this specification, but should note that other conforming applications 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/2024/CRD-vc-data-model-2.0-20240823/#verifiable-presentations) 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..f94e5e7d
--- /dev/null
+++ b/pages/VerifiableCredentials/Types/DID.md
@@ -0,0 +1,80 @@
+# DIDs
+
+DSNP Users are referenced in Verifiable Credentials documents via DIDs compliant 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 serialized in decimal form with no additional punctuation.
+
+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`, `authentication`, 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 `assertionMethodPublicKeys` |
+| `authentication` | no | Array | Set of public keys used as DSNP control keys | MAY include or reference any keys used as control keys |
+| `keyAgreement` | no | Array | Set of public keys used to generate shared secrets | MUST include or reference all relevant keys present in DSNP User Data `keyAgreementPublicKeys` |
+
+Additional properties defined in the DID specification MAY be present.
+
+### 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:645313",
+ "authentication": [
+ {
+ "@context": "https://w3id.org/security/multikey/v1",
+ "id": "did:dsnp:645313#z6QP1gZa1xAGCtsPzZSc5mdTDtrGsWUyf12TmU6pSu15SXUr",
+ "type": "Multikey",
+ "controller": "did:dsnp:645313",
+ "publicKeyMultibase": "z6QP1gZa1xAGCtsPzZSc5mdTDtrGsWUyf12TmU6pSu15SXUr"
+ }
+ ],
+ "assertionMethod": [],
+ "keyAgreement": [
+ {
+ "@context": "https://w3id.org/security/multikey/v1",
+ "id": "did:dsnp:645313#z6LSoYFtPRBEizFQ2zYXEXBPP96t9gNFWjZVJTfXWqzMhw9e",
+ "type": "Multikey",
+ "controller": "did:dsnp:645313",
+ "publicKeyMultibase": "z6LSoYFtPRBEizFQ2zYXEXBPP96t9gNFWjZVJTfXWqzMhw9e"
+ }
+ ]
+}
+```
diff --git a/pages/VerifiableCredentials/Types/VerifiableCredential.md b/pages/VerifiableCredentials/Types/VerifiableCredential.md
new file mode 100644
index 00000000..335765ea
--- /dev/null
+++ b/pages/VerifiableCredentials/Types/VerifiableCredential.md
@@ -0,0 +1,135 @@
+# Verifiable Credential
+
+Credentials should conform to the [Verifiable Credentials Data Model 1.1](https://www.w3.org/TR/vc-data-model-1.1/) or [Verifiable Credentials Data Model 2.0](https://www.w3.org/TR/vc-data-model-2.0/), expressed as [JSON-LD](https://json-ld.org/).
+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`
`https://www.w3.org/ns/credentials/v2` |
+
+## 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"` or `"https://www.w3.org/ns/credentials/v2"` |
+| `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 [Issuer](#issuer) |
+|`credentialSubject` | YES | Object | Object identifying subject and claim | See [Credential Subject](#credential-subject) |
+| `credentialSchema` | no | Object | Reference to schema for this credential | See [Credential Schema](#credential-schema) |
+| `proof` | no | Object | Cryptographic proof of authorship by `issuer` | See [Proof](#proof) |
+
+### 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 [Authority](#authority) |
+
+#### Authority
+
+Objects in the `issuer.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 |
+| `digestMultibase` | 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",
+ "digestMultibase": [
+ "bciqdnu347gcfmxzbkhgoubiobphm6readngitfywktdtbdocgogop2q"
+ ]
+ },
+ {
+ "id": "https://mydsnpcreds.net/86420-ap",
+ "rel": "did:dsnp:123456$AppleProducer",
+ "digestMultibase": [
+ "bdyqhwoxp2mc6oyaqpqyd2fvaxralslk32ggazv6nxpp342iec6652tq"
+ ]
+ }
+ ]
+}
+```
+
+### 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 | If `type` is `JsonSchemaCredential`, 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": "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..984cb976
--- /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 [Credential Subject](#credential-subject) |
+| `credentialSchema` | YES | Object | Metaschema defining JSON Schema types | See [Credential Schema](#credential-schema) |
+
+### 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 [JSON Schema](#json-schema) |
+| `dsnp` | no | Object | DSNP extension object | See [DSNP Extensions](#dsnp-extensions) |
+
+#### 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$AuthorizedCarDealership",
+ "did:dsnp:123456$OfficialTaxOffice"
+ ]
+ }
+ }
+ },
+ "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 16fac045..276d24df 100644
--- a/pages/index.md
+++ b/pages/index.md
@@ -7,20 +7,27 @@ Here you can find the detailed specification documentation for DSNP, official DS
Free communication among users on the Internet faces a variety of problems in the modern day.
These challenges include censorship by state and corporate actors, the amplification of misinformation through viral content, and an ever-shrinking collection of near monopolies with absolute power over social interaction in the twenty-first century.
-Through the DSNP, we hope to mitigate and ideally solve these challenges in the way social interaction operates online.
+Through DSNP, we hope to mitigate and ideally solve these challenges in the way social interaction operates online.
## How to Read This Specification
-There are three core specifications currently.
+There are three core specifications and one system specification currently.
+Each specification is divided into several modules.
+Each module describes a mostly self-contained aspect of the specification.
+
+### Core Specifications
| Name | Version | Description |
| --- | --- | --- |
| [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) |
-| [DSNP Over Frequency](Frequency/Overview.md) | - | DSNP Over Frequency specification |
+| [Verifiable Credentials](VerifiableCredentials/Overview.md) | pre-1.3.0 | Use of W3C Verifiable Credentials and DIDs with DSNP |
-Each specification is divided into several modules.
-Each module describes a mostly self-contained aspect of the specification.
+### System Specifications
+
+| Consensus System | DSNP System Specification |
+| --- | --- |
+| [Frequency](https://frequency.xyz) | [DSNP Over Frequency](Frequency/Overview.md) |
## Versioning
@@ -33,4 +40,4 @@ All interactions must follow the [Code of Conduct](https://github.com/LibertyDSN
## Learning More
-In addition to this document, more resources regarding the project can be found at [DSNP.org](https://www.dsnp.org), including the blog, forum, code repository, and SDK.
+In addition to this document, more resources regarding the project can be found at [DSNP.org](https://www.dsnp.org), including the blog, forum, code repositories, and other supporting software libraries and examples.