Skip to content

Credential Service

The Credential Service exposes functionality for issuance, proof generation, verification, and revocation of Verifiable Credentials.

Signature Format

The Credential service currently supports BBS+ Signatures , which enable selective disclosure of credential fields during proof generation.

Credentials are signed, and proofs are created, using a key pair unique to the signing / holding wallet. This key pair is created and managed by Trinsic upon account creation.


Issue Credential

Issues a credential from a valid JSON-LD document. Issued credentials are not automatically stored in any wallet.

trinsic vc issue --document <JSONLD_FILE> --out <OUTPUT_FILE>
const issueResponse = await trinsic
    .credential()
    .issue(IssueRequest.fromPartial({ documentJson: credentialJSON }));
var credential = await trinsic.Credential.IssueAsync(new() { DocumentJson = credentialJson });
issue_response = await trinsic_service.credential.issue(
    request=IssueRequest(document_json=credential_json)
)
issueResponse, err := trinsic.Credential().Issue(context.Background(),
    &credential.IssueRequest{
        DocumentJson: unsignedCredential,
    })
var issueResult =
    trinsic
        .credential()
        .issue(IssueRequest.newBuilder().setDocumentJson(unsignedCredential).build())
        .get();

var signedCredentialJson = issueResult.getSignedDocumentJson();

Request to sign a JSON-LD Credential using public key tied to caller
document_json
string
Valid JSON-LD Credential document to be signed, in string form

Response to IssueRequest
signed_document_json
string
Verifiable Credential document, signed with public key tied to caller of IssueRequest

Warning

IssueCredential requires a valid JSON-LD document to be provided. Do not confuse this operation with Issue Credential From Template.

When provided a valid credential, this endpoint creates and appends the proof object, using a key pair tied to the issuing Trinsic account.

You can learn more about how to create these documents, and about VC data models in general, from W3C: VC Data Model v1.1.


Issue Credential from Template

Issues a credential from a previously-defined template.

trinsic vc issue-from-template [OPTIONS] --template-id <ID>

# OPTIONS
# --out <OUTPUT_FILE>     (Optional) Output file to store the issued credential
# --values-data <JSON>    The JSON values of the credential subject
# --values-file <FILE>    The file with JSON values of the credential subject
let request = IssueFromTemplateRequest.fromPartial({
    templateId: templateResponse?.data?.id ?? "",
    valuesJson: JSON.stringify({
        name: "Alice",
        numberOfBags: 2,
        dateOfBirth: new Date("1/1/2000").toISOString(),
        vaccinated: true,
    }),
});

let response = await trinsic.credential().issueFromTemplate(request);
var credentialJson = await trinsic.Credential.IssueFromTemplateAsync(new() {
    TemplateId = templateId,
    ValuesJson = values
});
values = json.dumps({"firstName": "Jane", "lastName": "Doe", "age": "42"})
issue_response = await trinsic_service.credential.issue_from_template(
    request=IssueFromTemplateRequest(
        template_id=template.data.id, values_json=values
    )
)
issueTemplateResponse, err := trinsic.Credential().IssueFromTemplate(context.Background(),
    &credential.IssueFromTemplateRequest{
        ValuesJson: valuesJson,
        TemplateId: templateId,
    })
var valuesMap = new HashMap<String, Object>();
valuesMap.put("firstName", "Jane");
valuesMap.put("lastName", "Doe");
valuesMap.put("age", 42);
var valuesJson = new Gson().toJson(valuesMap);
var issueResponse =
    trinsic
        .credential()
        .issueFromTemplate(
            IssueFromTemplateRequest.newBuilder()
                .setTemplateId(template.getData().getId())
                .setValuesJson(valuesJson)
                .build())
        .get();

Request to create and sign a JSON-LD Verifiable Credential from a template using public key tied to caller
template_id
string
ID of template to use
values_json
string
JSON document string with keys corresponding to the fields of the template referenced by template_id
framework_id
optional string
Governance framework ID to use with issuance of this credential. If specified, the issued credential will contain extended issuer metadata with membership info for the given ecosystem governance framework (EGF)

Response to IssueFromTemplateRequest
document_json
string
Verifiable Credential document, in JSON-LD form, constructed from the specified template and values; signed with public key tied to caller of IssueFromTemplateRequest


Check Revocation Status

Checks a credential's revocation status by its credential_status_id.

A credential_status_id can be found in a credential's credentialStatus.id field, if present.

trinsic vc get-status --credential-status-id <ID>
let checkStatusResponse = await trinsic
    .credential()
    .checkStatus(CheckStatusRequest.fromPartial({}));
var checkResponse = await trinsic.Credential.CheckStatusAsync(new() { CredentialStatusId = "" });
#     check_response = await trinsic_service.credential.check_status(
#         request=CheckStatusRequest(credential_status_id="")
#     )
status, err := trinsic.Credential().CheckStatus(context.Background(), &credential.CheckStatusRequest{CredentialStatusId: ""})
var checkStatusResponse =
    trinsic.credential().checkStatus(CheckStatusRequest.newBuilder().build()).get();

Request to check a credential's revocation status
credential_status_id
string
Credential Status ID to check. This is not the same as the credential's ID.

Response to CheckStatusRequest
revoked
bool
The credential's revocation status


Update Revocation Status

Updates the revocation status of a credential (revoke or unrevoke).

A credential_status_id can be found in a credential's credentialStatus.id field, if present.

# Revoke a credential
trinsic vc update-status --revoked --credential-status-id <ID>

# Unrevoke a credential
trinsic vc update-status --unrevoked --credential-status-id <ID>
let updateStatusResponse = await trinsic
    .credential()
    .updateStatus(UpdateStatusRequest.fromPartial({}));
await trinsic.Credential.UpdateStatusAsync(new() { CredentialStatusId = "", Revoked = true });
#     update_response = await trinsic_service.credential.update_status(
#         request=UpdateStatusRequest(credential_status_id="", revoked=True)
#     )
updateResponse, err := trinsic.Credential().UpdateStatus(context.Background(), &credential.UpdateStatusRequest{CredentialStatusId: "", Revoked: true})
trinsic.credential().updateStatus(UpdateStatusRequest.newBuilder().build());

Request to update a credential's revocation status
credential_status_id
string
Credential Status ID to update. This is not the same as the credential's ID.
revoked
bool
New revocation status of credential

Response to UpdateStatusRequest
This message has no fields


Create Proof

Creates and signs a proof for a valid JSON-LD credential, using the BBS+ Signature Suite.

If the credential is stored in a Trinsic cloud wallet, pass its item_id; otherwise, pass the raw JSON-LD credential via document_json.

If reveal_document_json is passed, a proof will be generated for only the fields specified.

trinsic vc create-proof --document-id <STRING> --out <OUTPUT_FILE> --reveal-document <JSONLD_FRAME_FILE>
let proof = await trinsic.credential().createProof(
    CreateProofRequest.fromPartial({
        itemId: insertItemResponse.itemId,
        revealDocumentJson: getVaccineCertFrameJSON(),
    })
);
var proof = await trinsic.Credential.CreateProofAsync(new() {
    DocumentJson = credentialJson.DocumentJson,
    RevealDocumentJson = frame.ToString(Formatting.None)
});
proof_response = await trinsic_service.credential.create_proof(
    request=CreateProofRequest(
        reveal_document_json=proof_request_json, document_json=credential_json
    )
)
request := &credential.CreateProofRequest{
    Proof: &credential.CreateProofRequest_DocumentJson{
        DocumentJson: credentialJson,
    },
}

proofResponse, err := trinsic.Credential().CreateProof(context.Background(), request)
var createProofResponse =
    trinsic
        .credential()
        .createProof(
            CreateProofRequest.newBuilder()
                .setDocumentJson(signedCredentialJson)
                .setRevealDocumentJson(proofRequestJson)
                .build())
        .get();

var credentialProof = createProofResponse.getProofDocumentJson();

Request to create a proof for a Verifiable Credential using public key tied to caller. Either item_id or document_json may be provided, not both.
reveal_document_json
string
A valid JSON-LD frame describing which fields should be revealed in the generated proof. If unspecified, all fields in the document will be revealed
item_id
string
ID of wallet item stored in a Trinsic cloud wallet
document_json
string
A valid JSON-LD Verifiable Credential document string with an unbound signature. The proof will be derived from this document directly. The document will not be stored in the wallet.
nonce
optional bytes
Nonce value used to derive the proof. If not specified, a random nonce will be generated. This value may be represented in base64 format in the proof model.

Response to CreateProofRequest
proof_document_json
string
Valid JSON-LD proof for the specified credential

Selective Disclosure

BBS+ Signatures support the ability to generate a proof for a subset of a credential's fields, instead of every field.

This enables increased user privacy: fields which aren't included in reveal_document_json will not be present in the generated proof.

We are working on documentation for the expected structure of reveal_document_json and will make it available soon.


Verify Proof

Verifies a proof for validity and authenticity. Only supports BBS+ Signatures at present.

# The JSONLD_FILE refers to the proof document obtained from a CreateProofResponse
trinsic vc issuer verify-proof --proof-document <JSONLD_FILE>
let verifyResponse = await trinsic.credential().verifyProof({
    proofDocumentJson: proof.proofDocumentJson,
});
var valid = await trinsic.Credential.VerifyProofAsync(new() { ProofDocumentJson = proof.ProofDocumentJson });
verify_result = await trinsic_service.credential.verify_proof(
    request=VerifyProofRequest(proof_document_json=credential_proof)
)
verifyResponse, err := trinsic.Credential().VerifyProof(context.Background(), &credential.VerifyProofRequest{
    ProofDocumentJson: proofJson,
})
var verifyProofResponse =
    trinsic
        .credential()
        .verifyProof(
            VerifyProofRequest.newBuilder().setProofDocumentJson(credentialProof).build())
        .get();

boolean isValid = verifyProofResponse.getIsValid();

Request to verify a proof
proof_document_json
string
JSON-LD proof document string to verify

Response to VerifyProofRequest
is_valid
bool
Whether all validations in validation_results passed
validation_messages
string[]
Use validation_results instead
validation_results
map(string -> ValidationMessage)
Results of each validation check performed, such as schema conformance, revocation status, signature, etc. Detailed results are provided for failed validations.
Show child attributes

Validation Results

The verification process performs a number of validations, each of which may fail independently of the others.

For example, a credential may be expired or revoked, but otherwise perfectly valid.

validation_results contains an entry for each of the following verification steps:

Name Description
SignatureVerification Cryptographic signature validity of proof
CredentialStatus (if supported by credential) Checks if credential has been revoked
SchemaConformance Ensures credential conforms with its schema
TrustRegistryMembership (if relevant) Verifies that credential issuer is an authorized member of the credential's governing Trust Registry
IssuerIsSigner Document issuer is same DID as document signer. If false, it is not safe to assume that the claimed issuer actually issued the credential.

Exchange Credentials

Send via Email

Sends a credential to a user via email.

The specified email address must be tied to an existing account in the same ecosystem.

trinsic vc send --email <EMAIL_ADDRESS> --item <FILE>
await credentialService.send(document, "[email protected]");
var sendResponse = await trinsic.Credential.SendAsync(new() { Email = "[email protected]" });
send_response = await trinsic_service.credential.send(
    request=SendRequest(
        document_json=credential_json, email="[email protected]"
    )
)
sendResponse, err := trinsic.Credential().Send(context.Background(), &credential.SendRequest{
    DeliveryMethod: &credential.SendRequest_Email{
        Email: "[email protected]",
    },
    DocumentJson: credentialJson,
})
trinsic
    .credential()
    .send(
        SendRequest.newBuilder()
            .setDocumentJson(signedCredentialJson)
            .setEmail(recipientEmail)
            .build());

Request to send a document to another user's wallet
email
string
Email address of user to send item to
did_uri
string
DID of recipient (presently unsupported)
didcomm_invitation_json
string
DIDComm out-of-band invitation JSON (presently unsupported)
send_notification
bool
Send email notification that credential has been sent to a wallet
document_json
string
JSON document to send to recipient

Response to SendRequest
This message has no fields

Alternative Exchange Protocols

Credentials may only be sent to a wallet via email address or with the InsertItem call.

There are a number of ongoing industry efforts to standardize exchange protocols, such as:

We aim to provide support for these methods as they mature.