Working with Anonymous Credentials (AnonCreds)
TODO: Not tested at all; everything could be wrong
Introduction
In this tutorial, we will explore how to use Veramo to issue and verify Anonymous Credentials (AnonCreds), which are often used in privacy-preserving identity systems. AnonCreds are typically associated with Hyperledger Indy, and they allow users to prove certain attributes about themselves without revealing their full identity.
This extends the previous "Formats" tutorial to show how Veramo extensions can be used to support other important standards.
Steps
Prerequisites
Before you begin, follow the prerequisites for installation and configuration instructions.
You will also need to have access to a Hyperledger Indy network, such as the Sovrin network, and the appropriate SDKs installed.
1. Initialize a DID for the Issuer
First, we will create a DID for a sample organization (issuer) using the did:indy method.
veramo did create
Select the following options:
? Select identifier provider did:indy
? Select key management system local
? Enter alias sample_issuer
Expected output:
┌──────────┬─────────────────┬───────────────────────────────────────────────────────────────────────────────┐
│ provider │ alias │ did │
├──────────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────┤
│ did:indy │ sample_issuer │ did:indy:sovrin:WRfXPg8dantKVubE3HX8pw │
└──────────┴─────────────────┴───────────────────────────────────────────────────────────────────────────────┘
2. Initialize a DID for the Holder
Next, we will create a DID for a sample individual (holder) using the did:indy method.
veramo did create
Select the following options:
? Select identifier provider did:indy
? Select key management system local
? Enter alias sample_holder
Expected output:
┌──────────┬─────────────────┬────────── ─────────────────────────────────────────────────────────────────────┐
│ provider │ alias │ did │
├──────────┼─────────────────┼───────────────────────────────────────────────────────────────────────────────┤
│ did:indy │ sample_holder │ did:indy:sovrin:Fu4nD6uM2YnHHwPY7nB6eK │
└──────────┴─────────────────┴───────────────────────────────────────────────────────────────────────────────┘
3. Create an AnonCred Schema
AnonCreds require a schema that defines the attributes included in the credentials. Create a schema using the Hyperledger Indy SDK.
const indy = require("indy-sdk");
async function createSchema() {
const schemaName = "EmployeeCredential";
const schemaVersion = "1.0";
const schemaAttributes = [
"firstName",
"lastName",
"employeeId",
"department",
];
const [schemaId, schema] = await indy.issuerCreateSchema(
issuerDid,
schemaName,
schemaVersion,
schemaAttributes
);
return { schemaId, schema };
}
4. Create a Credential Definition
Create a credential definition for the schema using the Hyperledger Indy SDK.
async function createCredentialDefinition(schema) {
const tag = "employee_cred_def";
const [credDefId, credDef] = await indy.issuerCreateAndStoreCredentialDef(
issuerWallet,
issuerDid,
schema,
tag,
"CL",
{ support_revocation: false }
);
return { credDefId, credDef };
}
5. Issue an AnonCred
Issue an anonymous credential to the holder using the credential definition.
async function issueAnonCred() {
const credOffer = await indy.issuerCreateCredentialOffer(
issuerWallet,
credDefId
);
const masterSecretId = await indy.proverCreateMasterSecret(
holderWallet,
null
);
const [credRequest, credRequestMetadata] =
await indy.proverCreateCredentialReq(
holderWallet,
holderDid,
credOffer,
credDef,
masterSecretId
);
const credValues = {
firstName: {
raw: "John",
encoded: "1139481716457488690172217916278103335",
},
lastName: { raw: "Doe", encoded: "5321642780241790123587902456789123452" },
employeeId: { raw: "12345", encoded: "12345" },
department: { raw: "Engineering", encoded: "67890" },
};
const [credential] = await indy.issuerCreateCredential(
issuerWallet,
credOffer,
credRequest,
credValues,
null,
-1
);
await indy.proverStoreCredential(
holderWallet,
null,
credRequestMetadata,
credential,
credDef,
null
);
}
6. Verify an AnonCred
Verify the anonymous credential using the Veramo framework.
async function verifyAnonCred() {
const proofRequest = {
nonce: "123432421212",
name: "Proof of Employment",
version: "1.0",
requested_attributes: {
attr1_referent: {
name: "firstName",
restrictions: [{ cred_def_id: credDefId }],
},
attr2_referent: {
name: "lastName",
restrictions: [{ cred_def_id: credDefId }],
},
attr3_referent: {
name: "employeeId",
restrictions: [{ cred_def_id: credDefId }],
},
attr4_referent: {
name: "department",
restrictions: [{ cred_def_id: credDefId }],
},
},
requested_predicates: {},
};
const credsForProof = await indy.proverGetCredentialsForProofReq(
holderWallet,
proofRequest
);
const requestedCredentials = {
self_attested_attributes: {},
requested_attributes: {
attr1_referent: {
cred_id:
credsForProof["attrs"]["attr1_referent"][0]["cred_info"]["referent"],
revealed: true,
},
attr2_referent: {
cred_id:
credsForProof["attrs"]["attr2_referent"][0]["cred_info"]["referent"],
revealed: true,
},
attr3_referent: {
cred_id:
credsForProof["attrs"]["attr3_referent"][0]["cred_info"]["referent"],
revealed: true,
},
attr4_referent: {
cred_id:
credsForProof["attrs"]["attr4_referent"][0]["cred_info"]["referent"],
revealed: true,
},
},
requested_predicates: {},
};
const proof = await indy.proverCreateProof(
holderWallet,
proofRequest,
requestedCredentials,
masterSecretId,
schemas,
credDefs,
revStates
);
const verified = await indy.verifierVerifyProof(
proofRequest,
proof,
schemas,
credDefs,
revRegDefs,
revRegs
);
return verified;
}
Conclusion
In this tutorial, we demonstrated how to use Veramo to issue and verify Anonymous Credentials (AnonCreds) using the Hyperledger Indy network. AnonCreds provide a powerful way to ensure privacy-preserving identity solutions, allowing users to prove specific attributes about themselves without revealing their full identity. Veramo's flexibility and support for various DID methods and proof formats make it an excellent choice for implementing decentralized identity solutions.