The goal of this document is to define a minimal viable product (production-ready functionality) that satisfies our ecosystem's requirements, with an awareness of potential future improvements and alignment with the ToIP trust registry protocol (or any other trust registry protocol we find interesting). The goal is not to define or implement a protocol. An essential part of this effort is defining how the service will be developed, deployed, and operated.
In our case, we currently need to implement only the following two parts from ToIP v1 protocol specification:
The governance framework is not part of this document. We assume a governance framework will describe the rules to answer the questions above. The trust registry is just a technical implementation of such rules.
As an Issuer/Verifier, I want to request Governing Authority for addition to the trust registry with my identifier and information about my entity, so that I can participate in the ecosystem as an Issuer/Verifier.
As a Governing Authority, I want to be able to add an issuer or verifier, so that I'm the only one who controls the data and I can fulfill my obligation to keep the validity and authenticity of the registry.
As a Holder, I want to know who are authorized issuers for specific credentials, so that I’m not misled that I have a correct credential but later verification would fail because the credential was issued by an illegitimate issuer.
As a Verifier, I want to know who are authorized issuers of a particular credential type, so that I can request presentation with restrictions for such credential types from defined issuers.
As a Holder, I want to know who are authorized verifiers for a any credential type, so that I can answer a presentation request only to those verifiers and don't share my personal data with a fraudulent entity. We intentionaly don't want to specify authorized verifiers for specific credential type. We assume that all authorized verifiers inside the registry are known and have been vetted by Governing Authority.
As an Issuer/Verifier, I want to be able to update information about my entity (by myself?), so that I can change the information and keep them updated in the registry (without asking Governing Authority). This is not needed in the first iteration.
did:sov
. We can eventually allow did:web
for verifiers, therefore, they don't need to write did to the ledger. What other types should we consider?The API is inspired by APIs from DIDx didx-registry.json, Absa absa-registry.json and ToIP Trust Registry v1 Open API. I separated out the list of credential types from an entity as it was in DIDx API. If I understood it correctly, it would allow issuers only to verify the same credential type as they're issuing. This might be fine for the first iteration of the trust registry service but quite limiting later. On the other hand, if we keep this information separate, the issuer will likely have duplicated definitions in both the issuer and verifier list of credential types.
GET /issuers/did:sov:Enmy7mgJopSsELLXd9G91d
List of credential types that an issuer identified by DID is authorized to issue. We can return not only the list of such credential types but also all issuer attributes.
{
"id": "8fa665b6-7fc5-4b0b-baee-6221b1844ec8",
"name": "Yoma123",
"did": "did:sov:Enmy7mgJopSsELLXd9G91d",
"logo_url": "https://yoma.africa/images/sample.png1",
"domain": "www.abc.xyz12",
"registered_at": "2023-05-24T18:14:24",
"updated_at": "2023-05-24T18:41:08",
"role": "issuer",
"credentials": [
"test_schema4:Enmy7mgJopSsELLXd9G91d:3:CL:24:default",
"test_schema5:Enmy7mgJopSsELLXd9G91d:3:CL:27:default",
"Proof of Person:Enmy7mgJopSsELLXd9G91d:3:CL:30:default"
]
}
GET /verifiers/did:sov:DZFXtbRTEud9YLKN7bBmDb
List of credential types that a verifier identified by DID is authorized to request. We can return not only the list of such credential types but also all verifier attributes.
{
"id": "fb38e13f-63e0-4cb6-980c-8c2fc04cbfae",
"name": "Yoma",
"did": "did:sov:DZFXtbRTEud9YLKN7bBmDb",
"logo_url": "https://yoma.africa/images/sample.pngkhjjkh",
"domain": "www.abc.xyz67868869",
"registered_at": "2023-05-24T21:39:52",
"updated_at": "2023-05-24T21:40:50",
"role": "verifier",
"verifications": [
"FICA",
"RICA"
]
}
GET /schemas
List of schemas that issuers can be authorized to issue and verifiers to request.
[
"Mnj3wB4tgrww6RETzZVx64:2:test_schema:0.3.0",
"Mnj3wB4tgrww6RETzZVx64:2:test_schema1:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema1:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema2:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema3:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema4:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema5:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:Proof of Person:0.3.0",
"Cmj9d7pwxEj2fYrKpNmtGx:2:test_schema:0.3.0"
]
GET /verification_policies
- latest versions
GET /verification_policies?policy_id=x?history=true?version=1.0.1
- provide historical versions of verification policies to proof that governance was adhered to at a point back in time
List of verification policies for specific industry verification such as FICA, RICA that verifiers can use to verify requests.
[
{
"FICA": {
"proof_request": {
"requested_attributes": {
"additionalProp1": {
"name": "string",
"names": [
"string"
],
"non_revoked": {
"from": 0,
"to": 0
},
"restrictions": [
{
"additionalProp1": "did:absa, did:fnb, did:sbsa",
"additionalProp2": "did:municipality, did:bank",
"additionalProp3": "string"
}
]
},
"additionalProp2": {
"name": "string",
"names": [
"string"
],
"non_revoked": {
"from": 0,
"to": 0
},
"restrictions": [
{
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
]
},
"additionalProp3": {
"name": "string",
"names": [
"string"
],
"non_revoked": {
"from": 0,
"to": 0
},
"restrictions": [
{
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
]
}
},
"requested_predicates": {
"additionalProp1": {
"name": "string",
"p_type": "<",
"p_value": 0,
"non_revoked": {
"from": 0,
"to": 0
},
"restrictions": [
{
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
]
},
"additionalProp2": {
"name": "string",
"p_type": "<",
"p_value": 0,
"non_revoked": {
"from": 0,
"to": 0
},
"restrictions": [
{
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
]
},
"additionalProp3": {
"name": "date_of_birth",
"p_type": ">",
"p_value": 18,
"non_revoked": {
"from": 0,
"to": 0
},
"restrictions": [
{
"additionalProp1": "string",
"additionalProp2": "string",
"additionalProp3": "string"
}
]
}
},
"name": "string",
"non_revoked": {
"from": 0,
"to": 0
},
"nonce": "random(uuid)",
"version": "1.0.1"
},
"comment": "FICA",
"protocol_version": "v1"
}
}
]
GET /registry
The whole content of the registry. The idea is that a holder's edge agent can download it and cache it on a device where it runs. The data are normilzed, entities are identified by IDs and credential types are defined in separate arrays. Thefore we don't duplicate information about entities as I mentioned above.
{
"entities": [
{
"id": "bd368051-0843-4efe-b7e3-24ed6c5fdd9f",
"name": "Yoma10",
"did": "did:sov:9yyYk3D6mmk9NtzEG1QZkK",
"logo_url": "https://yoma.africa/images/sample.png3",
"domain": "www.3.xyz",
"registered_at": "2023-05-24T17:58:31",
"updated_at": "2023-05-24T17:58:31"
},
{
"id": "8fa665b6-7fc5-4b0b-baee-6221b1844ec8",
"name": "Yoma123",
"did": "did:sov:Enmy7mgJopSsELLXd9G91d",
"logo_url": "https://yoma.africa/images/sample.png1",
"domain": "www.abc.xyz12",
"registered_at": "2023-05-24T18:14:24",
"updated_at": "2023-05-24T18:41:08"
},
{
"id": "eb3ac961-5fd3-45fa-acfe-1ea296e3fff5",
"name": "Yom123123a",
"did": "did:sov:EuKgs98XkUSELo1ioqUh3U",
"logo_url": "https://yoma.africa/images/sample.png123123",
"domain": "www.abc.xyz123123",
"registered_at": "2023-05-24T20:19:44",
"updated_at": "2023-05-24T20:19:44"
},
{
"id": "fb38e13f-63e0-4cb6-980c-8c2fc04cbfae",
"name": "Yoma",
"did": "did:sov:DZFXtbRTEud9YLKN7bBmDb",
"logo_url": "https://yoma.africa/images/sample.pngkhjjkh",
"domain": "www.abc.xyz67868869",
"registered_at": "2023-05-24T21:39:52",
"updated_at": "2023-05-24T21:40:50".
"credentials": [],
"verifications": []
}
],
"issuers": [
{
"id": "8fa665b6-7fc5-4b0b-baee-6221b1844ec8",
"credentials": [
"test_schema4:Enmy7mgJopSsELLXd9G91d:3:CL:24:default",
"test_schema5:Enmy7mgJopSsELLXd9G91d:3:CL:27:default",
"Proof of Person:Enmy7mgJopSsELLXd9G91d:3:CL:30:default"
]
}
],
"verifiers": [
{
"id": "fb38e13f-63e0-4cb6-980c-8c2fc04cbfae",
"credentials": ["test_schema:DZFXtbRTEud9YLKN7bBmDb:3:CL:12:default"]
}
],
"schemas": [
"Mnj3wB4tgrww6RETzZVx64:2:test_schema:0.3.0",
"Mnj3wB4tgrww6RETzZVx64:2:test_schema1:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema1:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema2:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema3:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema4:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema5:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:Proof of Person:0.3.0",
"Cmj9d7pwxEj2fYrKpNmtGx:2:test_schema:0.3.0"
],
"verification policies": [
"Mnj3wB4tgrww6RETzZVx64:2:test_schema:0.3.0",
"Mnj3wB4tgrww6RETzZVx64:2:test_schema1:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema1:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema2:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema3:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema4:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:test_schema5:0.3.0",
"BrAQHowoF4rxmr92T8mjWB:2:Proof of Person:0.3.0",
"Cmj9d7pwxEj2fYrKpNmtGx:2:test_schema:0.3.0"
]
}
The service will be provided as Docker image, deployed and operated by Governing Authority (Bankserve). Regarding the development, DIDx company has already implemented trust registry as part of their bigger SSI solution. One option is to extract that and continue the development there. It's written in Python. At Absa, we can provide some resources or lead the development, but we use mainly Node.js.
Could be the solution distributed for reading? That would mean that other participant can keep their own version cached and just getting notification about changes. (Lohan: Is this what you meant by more distributed system?)
Only the Govenring Authority will have rights to add/remove entities and assign credential types to them. Any given entity could eventually do updates about itself, signed by its DID. This might require that supporting functionality for singing is implemented on the issuer/verifier side.
https://wiki.trustoverip.org/display/HOME/ToIP+Trust+Registry+Protocol+Specification
https://wiki.trustoverip.org/display/HOME/Trust+Registry+Protocol+v2±+Loose+Capture
https://github.com/trustoverip/tswg-trust-registry-tf/blob/main/v1/api/toip.trustregistry.api.yaml
[OLD] Web 7.0 Trust Registry Framework: Trust Registration Documents 1.3
https://northernblock.io/leveraging-dns-in-digital-trust-credential-exchanges-and-trust-registries/
See https://identity.foundation/trust-establishment/.
The structure of the list of trusted issuers:
{
"$id": "https://example.com/trusted-issuers-for-credential.schema.json",
"$schema": "https://json-schema.org/draft/2019-09/schema",
"title": "Trusted Issuers for Credential",
"type": "object",
"properties": {
"credential": {
"type": "array",
"items": {
"type": "string"
},
"minItems": 1
}
},
"required": ["credential"],
"additionalProperties": false
}
The list of trusted issuers itself:
{
"id": "32f54163-7166-48f1-93d8-ff217bdb0653",
"author": "did:example:alice",
"created": "2010-01-01T19:23:24Z",
"validFrom": "2010-01-01T19:23:24Z",
"version": "0.0.1",
"entries": {
"https://example.com/trusted-issuers-for-credential.schema.json": {
"did:example:bob": {
"credentials": ["example.com/dank-meme.schema.json", "example.com/danker-meme.schema.json"]
},
"did:example:carol": {
"credentials": ["example.com/dankest-meme.schema.json", "example.com/dankest-meme.schema.json.ld"]
}
}
}
}
See What Is a Trust Registry? (Demo of Trinsic's Trust Registry Service).
Link to trust registry from issuer
field in JSON-LD credential
{
"IssuerIsSigner": {
"is_valid": true,
"messages": []
},
"TrustRegistryMembership": {
"is_valid": true,
"messages": []
}
}