# 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.