# AttestedResources and the `did:webvh` AnonCreds Method
## The `attestedResource`
This is a defined type of resource stored on the server. The structure of the JSON object is defined (below), formalizing where an arbitrary resource is placed (`<resource>`). A proof (an attestation, hence the `attestedResource` name) is attached. The ID for the resource is derived from hashing the `<resource>`.
The key properties defined are:
- `id`
- A DID URI value resolving to the attested resource. The right most path components of the URI MUST be the digestMultibase value of the `content` object.
- `content`
- An arbitrairy json object containing the subject of the attested resource, the `<resource>`.
- `metadata`
- An object borrowing attributes from the [DID linked resource metadata](https://w3c-ccg.github.io/DID-Linked-Resources/#examples). These should be used for dereferencing.
- `links`
- An array of relate links objects. These object should contain an `id`, a `type` and optionally a `digestMultibase`.
### Data Model
```json
{
"@context": [
"https://example.com/attested-resource/v1",
"https://w3id.org/security/data-integrity/v2"
],
"type": ["AttestedResource"],
"id": "did:webvh:{SCID}:example.com/<path>/<to>/<resource>/{digestMultibase}",
"content": {<resource>},
"metadata": {
"resourceId": "{digestMultibase}",
"resourceType": "",
"resourceName": ""
},
"links": [
{
"type": "RelatedLink",
"id": "https://example.com",
"digestMultibase": "{digestMultibase}"
}
],
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"verificationMethod": "did:webvh:{SCID}:example.com#key-01"
}
}
```
## Creation and Publishing
* Create the resource object according to the spec.
* Calculate the `digestMultibase` value of the resource.
* `multibase(multihash(jcs(<resource>), 'sha2-256'), 'b58btc')`
* Construct the `id` by appending `{digestMultibase}` to the DID URL specified by the DID Controller (resource publisher). Here are a few examples of valid `id`.
* `did:webvh:{SCID}:example.com/` + `{digestMultibase}`
* `did:webvh:{SCID}:example.com/path/to/resource/` + `{digestMultibase}`
* `did:webvh:{SCID}:example.com:namespace:identifier/resources/` + `{digestMultibase}`
* Sign the full object (everything above other than the proof) with a valid `verificationMethod` from the issuer.
* Using `DataIntegrityProof` + `eddsa-jcs-2022`
* Upload to the server.
* This step will depend on the server implementation.
## Resolving
* Resolve the DID and validate the logs.
* Do a DID url transformation on the resource id.
* `did:webvh:{SCID}:example.com/{digestMultibase}`
* `https://example.com/{digestMultibase}`
* Fetch the resource, ensure it has a proof attached and verify it.
* Collect the `digestMultibase` from the url and compare with the `content` object's digest.
* Validate the `resourceType` with the expected resource type string.
* Process the `content` as the expected object type.
### Context
Example context file for an attested-resource object.
```json
{
"@context": {
"@protected": true,
"id": "@id",
"type": "@type",
"undefined": "https://www.w3.org/ns/credentials/undefined-term#",
"digestMultibase": {
"@id": "https://w3id.org/security#digestMultibase",
"@type": "https://w3id.org/security#multibase"
},
"mirrorLink": {
"@id": "undefined:mirrorLink",
"@type": "https://schema.org/URL"
},
"AttestedResource": {
"@id": "undefined:AttestedResource",
"@protected": true,
"@context": {
"content": {
"@id": "undefined:content",
"@type": "@id",
"@vocab": "undefined"
},
"metadata": {
"@id": "undefined:metadata",
"@type": "@id",
"@vocab": "undefined"
},
"links": {
"@id": "undefined:links",
"@type": "@id"
}
}
}
}
}
```
## `did:webvh` AnonCreds Method
The following describes how the `did:webvh` AnonCreds Method makes use of `attestedResources`.
1. Schemas and CredDefs are `attestedResources`. Their IDs are the DID URLs calculated during generation and shared to other parties (e.g. `schemaID` is in the CredDef, `credDefId` is in the issued Credential).
1. Does/can the resource name include the components of the object -- e.g. `schemaName`, `schemaVersion`, `tag`? Presumably, the controller can make that part of the DID URLs. Should we consider formalizing it? E.g. `<did>/anoncreds/schema/ver/<schemaname>/<schemaver>/<attestedresouce>`
2. Is there a way to get a list of all attestedResources, including their identifying metadata? What if the metadata is not part of the DID URLs? Ideally, it would not be all `attestedResources` as we don't care about RevRegEntrys in such a list (at least not without a timestamp).
4. Should did:webvh formalize that a folder can be resolved with a list of contents returned (e.g. `<did>/anoncreds/schema/ver/` returns a list of `<schemaNames>`).
2. RevRegDef is also an `attestedResource`, with its `revRegid` generated during creation, and shared from the Issuer to the Holder in the issued Credential, and in turn the Holder shares the `revRegid` with the Verifer in the Presentation.
3. The RevRegDef contains a current list (index) of its RevRegEntry `attestedResource`s. When a new RevRegEntry is created and published, the index is updated with the `timestamp` and `attestedResource` identifier, and the RevRegDef resource is republished.
1. The index is _outside_ of the resource that is attested. As such, the updates **do not** change the `attestedResource` name of the RevReg. The proof on the attested resource **DOES** get updated to include the index.
2. The `<resource>` **MUST NOT** change when a new RevRegEntry index entry is added, or the Multibase hash will not verify.
4. A client needing a RevRegEntry for an arbitrary or specific timestamp, must:
1. Retrieve the known associated `revRegDefId` `attestedResource`.
2. Scan the timestamps in the list (index) for the one of interest:
1. Holder finds the RevRegEntry active at a given timestamp (or from/to period) from the verifier.
2. Verifier gets the RevRegEntry at the specific timestamp in the Presentation from the Holder.
3. Use the `attestedResource` ID (DID URL) to get the RevRegEntry of interest.
1. The RevRegEntry contains the full state of the RevReg at the given `timestamp`.
2. The `did:webvh` AnonCreds method will not use deltas (as does Indy), but will use full state, as does Cheqd.