Public profile - Machine-readable, cryptographially-verifiable imprint linked to a DID

Motivation

Organizations, i.e. legal entities, play a vital role in an SSI ecosystem. In most cases organizations will take the role of an issuer and verifier of credentials, but will also hold credentials themselves. We assume that in almost all cases organizations want to have a public identity. Although an organization might need private, context-specific identities (personas) as well.

In the following we want to discuss a simple mechanism to provide public information concerning an entity by advertising a public profile service in the DID document of a public DID. A good analogy for this public identity information would be a machine-readable and cryptographically-verifiable imprint.

Description

Since we assume that organizations require a public identity, we assume that the organization has a public DID and may be registered on a public ledger.
Given a public DID an interested party is able to resolve the DID to a DID document. We suggest introducing a new service type profile that returns a (static) JSON-LD Verifiable Presentation (VP) consisting of self-attested and third-party Verifiable Credentials (VCs) that provide basic information about the entity. Ideal candidates for VCs included in the public profile would be VCs as published in commerical registers like the OrgBook or a GLEIF's vLEI.

Example of a profile service included in a DID document
{
    "service":
    [{
        "type":"profile",
        "serviceEndpoint":"https://alice.iil.network/profile.jsonld"
    }]
}

The retourned ressource is a JSON-lD VP signed by an authentication method from the DID document.

Use Cases

Get information about an issuer

Assume the following scenario. An employee of Org A gets issued an employee credential from Org A. Now, the employee presents her credential to Org B. Org B does not have an existing trust relationship with Org A, i.e. does not have the did:orgA in its trust store. Org B can resolve the DID Document from did:orgA and retrieve the profile, thereby getting more information about the issuer and a baseline to estimate the trustworthyness of the credential.

Trust before connect

The profile endpoint allows to retrieve basic information about another party before initiating a DIDcomm connection.

Indexing Organizations

The profile endpoint allows to index public organizations on a Verifiable Data Registry which allows to build search engines or catalogues that can return DIDs based on profile information advertised in the profile service. A simple example would be a ledger explorer that could show information based on the public profile.

Public profile in ACA-Py

ACA-Py allows to publish and retrieve aprofile endpoint on an Indy ledger. ACA-Py is also able to sign and verify JSON-LD VPs using the JSON-LD plugin.
Hence, ACA-Py provides (in principle) all the tools for a controller to issue and verify public profiles. This is what we did in the Business Partner Agent project. However, if there is interest in this mechanism it might make sense to include an admin API to manage a public profile and retrieve and verify a public profile of a DID.

Workaround for AnonCreds

Currently, we have a workaround to include Indy Credentials (AnonCreds) in the public profile. BBS+ JSON-LD VCs, on the other hand, could be included directly if the credential subject is the public DID.

Notifications

A further useful mechanism would be a mechanism to notify connections about an update of the public profile. In principle you could send a proof proposal to every connection. However, this seems not to be a scalable approach, since there might be a large number of connections for an organization. I wonder if a generic notification RFC makes sense that could be used here.

Example of the public profile implementation in the Business Partner Agent

Documents or credentials in the wallet can be made public. If they are public they will be included in the public profile and presentation requests concerning these credentials are automatically fullfilled.

If we add a new business partner, we fetch the public profile from the ledger ask for a DIDcomm connection in the second step. The same would be possible if we could get a connection request based on the public DID.

Comparison with other approaches

The straight forward alternative approach would be to standardize a profile presentation definition and use a (connection-less) proof request to get the profile information. The here presented approach has the following advantages

  • The profile VP can be pre-computed once and published on a CDN instead of requiring direct interaction with the agent and access to the wallet
  • The profile VP can be used and verified by other participants of the SSI ecosystem independent of Aries and DIDcomm

Disclaimer: The individual VCs in the VP can only be verified directly in the case of JSON-LD VCs. If AnonCreds are wrapped in the VP, then an Aries proof request has to be performed. More information about this in the link concerning AnonCreds implementation.

Outlook

We assume that the profile service might be superseded by a more flexible service such as an Identity Hub or a general Verifiable Credential Service.

Technical Details

{
  "@context": [
    "..."
  ],
  "id": "http://example.com/selfdescription.json",
  "type": [
    "VerifiablePresentation"
  ],
  "verifiableCredential": [
    // ...
  ],
  "proof": {
    "type": "...",
    "proofPurpose": "authentication",
    "challenge": "http://example.com/selfdescription.json?timestamp=1621425974",
    "created": "...",
    "jws": "..."
  }
}

The public profile (or self-description) is based on a few minor conventions.

First, to find out, where to get the latest version of the document, the id is used to point to the URL where to get the latest version from.

Second, the "authentication" proofPurpose that is being used in a typical Verifiable Presentation doesn't fully fit the idea of a public profile. There is no direct "authentication" in a protocol between the holder and the verifier. Thus, a challenge to prevent replay attacks doesn't make sense here either. The challenge in this case is the URL where the document is published + a unix timestamp as a timestamp query param.

A separate proofPurpose for the public profile was considered, too. It seems to be out of scope because of 2 main reasons:

  • most tools expect a Verifiable Presentation to use authentication proofPurpose
  • it would require changes in the DID document because the new proofPurpose would need to link to the singing key as part of the DID document. Example:
"public_profile_signing": [ // <-- potential new proofPurpose
    "<link to the public key>"
  ],

Select a repo