AnonCreds Support¶
The DID WebVH Server supports publishing and resolving AnonCreds objects as Attested Resources. This enables issuers to publish AnonCreds schemas, credential definitions, revocation registry definitions, and revocation registry states using the DID WebVH method.
Overview¶
AnonCreds is a privacy-preserving credential system that provides: - Selective Disclosure: Reveal only specific attributes from a credential - Unlinkability: Multiple presentations cannot be correlated to the same credential - Predicate Proofs: Prove relationships (e.g., age ≥ 18) without revealing exact values - Privacy-Preserving Revocation: Check revocation status without correlation - Multi-Credential Presentations: Combine proofs from multiple credentials
The DID WebVH Server stores AnonCreds objects as AttestedResource objects, which are cryptographically signed and linked to the issuer's DID.
AnonCreds Object Types¶
Four types of AnonCreds objects can be published on the server:
- Schema: Defines the structure and attributes of a credential type
- Credential Definition: Contains the issuer's public keys for a specific schema
- Revocation Registry Definition: Defines a revocation registry for revocable credentials
- Revocation Registry State: Contains the current state of a revocation registry
Each object is namespaced to the issuer's DID and can be resolved using the DID WebVH resolution protocol.
Prerequisites¶
Before publishing AnonCreds objects, you need:
- An Issuer DID: A DID created on the server with a valid
verificationMethodof typeMultikey - Witness Connection (if
WEBVH_ENDORSEMENT=true): Connection to a witness service for endorsement - Signing Capability: Ability to create
DataIntegrityProofsignatures using theeddsa-jcs-2022cryptosuite
Creating an AttestedResource¶
An AnonCreds object is published as an AttestedResource with the following structure:
{
"@context": ["https://w3id.org/security/data-integrity/v2"],
"id": "did:webvh:{SCID}:example.com:issuer:my-did/resources/{digestMultibase}",
"content": {
// AnonCreds object (Schema, Credential Definition, etc.)
},
"metadata": {
"resourceId": "{digestMultibase}",
"resourceType": "AnonCredsSchema",
"resourceName": "Example Schema"
},
"links": [],
"proof": {
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:webvh:{SCID}:example.com:issuer:my-did#key-1",
"proofValue": "..."
}
}
Step-by-Step Process¶
- Initialize the AttestedResource
- Create an empty object
-
Set
@contextto["https://w3id.org/security/data-integrity/v2"] -
Set the Content
-
Set the
contentproperty to your AnonCreds object (Schema, Credential Definition, etc.) -
Generate the Resource ID
- Calculate the
digestMultibaseof thecontentproperty - Construct the resource ID:
{issuer_did}/resources/{digestMultibase} -
Example:
did:webvh:abc123:example.com:issuer:my-did/resources/zM6mH... -
Add Metadata (Optional but Recommended)
-
Add Links (Optional)
- Add related resource links if the AnonCreds object references other resources
-
Each link should have an
id,type, and optionallydigestMultibaseortimestamp -
Sign the Resource
- Create a
DataIntegrityProofusingeddsa-jcs-2022cryptosuite - Use a
verificationMethodfrom your issuer DID document -
Set
proofPurposeto"assertionMethod" -
Obtain Witness Endorsement (if
WEBVH_ENDORSEMENT=true) - Request witness signature for the resource
-
Include witness proof alongside your proof in the
proofarray -
Upload to Server
- POST
/{namespace}/{alias}/resources - Include both controller proof and witness proof (if required)
Uploading AnonCreds Objects¶
Example: Uploading a Schema¶
# 1. Create the AttestedResource
{
"@context": ["https://w3id.org/security/data-integrity/v2"],
"id": "did:webvh:abc123:example.com:issuer:my-did/resources/zM6mH...",
"content": {
"name": "Example Schema",
"version": "1.0",
"attrNames": ["name", "age", "email"]
},
"metadata": {
"resourceId": "zM6mH...",
"resourceType": "AnonCredsSchema",
"resourceName": "Example Schema"
},
"proof": [
{
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:webvh:abc123:example.com:issuer:my-did#key-1",
"proofValue": "..."
},
{
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"proofPurpose": "assertionMethod",
"verificationMethod": "did:key:z6Mk...#witness",
"proofValue": "..."
}
]
}
# 2. Upload to server
curl -X POST "https://did.example.org/issuer/my-did/resources" \
-H "Content-Type: application/json" \
-d '{
"attestedResource": { ... }
}'
Example: Uploading a Credential Definition¶
{
"@context": ["https://w3id.org/security/data-integrity/v2"],
"id": "did:webvh:abc123:example.com:issuer:my-did/resources/zM6mH...",
"content": {
"schemaId": "did:webvh:abc123:example.com:issuer:my-did/resources/zM6mH...",
"tag": "default",
"type": "CL",
"value": {
"primary": { ... },
"revocation": { ... }
}
},
"metadata": {
"resourceId": "zM6mH...",
"resourceType": "AnonCredsCredentialDefinition",
"resourceName": "Example Credential Definition"
},
"proof": [ ... ]
}
Resolving AnonCreds Objects¶
AnonCreds objects can be resolved using the DID WebVH resolution protocol:
- Get the Resource ID
-
Example:
did:webvh:abc123:example.com:issuer:my-did/resources/zM6mH... -
Transform DID to HTTPS URL
- Extract the DID components:
did:webvh:{SCID}:{domain}:{namespace}:{alias} - Transform to:
https://{domain}/{namespace}/{alias} -
Example:
https://example.com/issuer/my-did -
Append Resource Path
- Add
/resources/{digestMultibase}to the URL -
Example:
https://example.com/issuer/my-did/resources/zM6mH... -
Make GET Request
-
Verify the Resource
- Verify the
DataIntegrityProofsignature - Calculate
digestMultibaseofcontentand compare with resource ID - Verify the
metadata.resourceIdmatches (if present) - Check that
metadata.resourceTypematches expected type
Updating AttestedResources¶
You can update the metadata or links of an existing resource:
- Retrieve the Original Resource
-
GET the resource from the server
-
Modify Metadata or Links
- Update
metadataproperties (e.g.,resourceName) - Add or remove items from
linksarray -
Note: The
contentproperty is immutable -
Create New Proof
- Generate a new
DataIntegrityProofwith updated timestamp -
Obtain witness endorsement if required
-
Update on Server
- PUT
/{namespace}/{alias}/resources/{resource_id} - Include the updated resource with new proof
curl -X PUT "https://did.example.org/issuer/my-did/resources/zM6mH..." \
-H "Content-Type: application/json" \
-d '{
"attestedResource": {
... // Updated metadata/links with new proof
}
}'
Endorsement Requirements¶
If WEBVH_ENDORSEMENT=true (default), resources must be endorsed by a witness:
- Controller Signs Resource
-
Create
DataIntegrityProofwith controller's verification method -
Request Witness Endorsement
- Send resource to witness service via DIDComm
-
Witness verifies and signs the resource
-
Include Both Proofs
- Controller proof:
verificationMethodstarts withdid:webvh: - Witness proof:
verificationMethodstarts withdid:key: -
Both proofs must be in the
proofarray -
Server Validation
- Server verifies both proofs
- Server checks witness is in known witness registry
- Server validates witness key matches registered DID
Best Practices¶
- Use Descriptive Metadata
- Set
resourceTypeto clearly identify the AnonCreds object type -
Use
resourceNamefor human-readable identification -
Link Related Resources
- Use
linksto connect schemas, credential definitions, and revocation registries -
This enables discovery of related AnonCreds objects
-
Maintain Resource Immutability
- Never modify the
contentproperty after initial publication -
Use updates only for metadata and links
-
Verify Before Use
- Always verify
DataIntegrityProofsignatures - Check
digestMultibasematches resource ID -
Validate witness endorsement if required
-
Monitor Revocation Registry States
- Regularly update revocation registry states
- Use links to connect states to registry definitions
API Endpoints¶
Upload Resource¶
- POST
/{namespace}/{alias}/resources - Uploads a new AnonCreds object as an AttestedResource
Update Resource¶
- PUT
/{namespace}/{alias}/resources/{resource_id} - Updates metadata or links of an existing resource
Get Resource¶
- GET
/{namespace}/{alias}/resources/{resource_id} - Retrieves a specific resource
List Resources¶
- GET
/{namespace}/{alias}/resources - Lists all resources for a DID