From 92cc0ee26f36926d8527d0aa88d0ca4e5ed124ad Mon Sep 17 00:00:00 2001 From: applesnort Date: Tue, 30 Jun 2026 18:27:35 -0400 Subject: [PATCH 1/3] feat: add utopia-agency-employee-badge IdentificationDocument credential Simple employee badge using the identification vocab (v1rc1): givenName + familyName from the Person type, agency as an inline schema.org/memberOf term. Issued by Utopia DMV for demo purposes; ports to CHP and other CA agencies in follow-up work (DB-181). Depends on DB-724 (identification-vocab context registration in vc-playground) before this credential can be issued via the playground. --- .../credential.json | 26 +++++++++++++++++++ .../utopia-agency-employee-badge/queries.json | 19 ++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 credentials/utopia-agency-employee-badge/credential.json create mode 100644 credentials/utopia-agency-employee-badge/queries.json diff --git a/credentials/utopia-agency-employee-badge/credential.json b/credentials/utopia-agency-employee-badge/credential.json new file mode 100644 index 0000000..95e5bc4 --- /dev/null +++ b/credentials/utopia-agency-employee-badge/credential.json @@ -0,0 +1,26 @@ +{ + "@context": [ + "https://www.w3.org/ns/credentials/v2", + "https://w3id.org/identification/v1rc1", + { + "agency": "https://schema.org/memberOf" + } + ], + "id": "urn:uuid:b3d7c2e1-4f5a-6b7c-8d9e-0a1b2c3d4e5f", + "type": ["VerifiableCredential", "IdentificationDocumentCredential"], + "name": "Utopia Agency Employee Badge", + "issuer": { + "id": "https://www.utopia-dmv.example", + "type": ["Profile"], + "name": "Utopia Department of Motor Vehicles" + }, + "validFrom": "2026-01-15T00:00:00Z", + "validUntil": "2028-01-14T23:59:59Z", + "credentialSubject": { + "id": "urn:uuid:d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a", + "type": "Person", + "givenName": "Jordan", + "familyName": "Casey", + "agency": "Utopia Highway Patrol" + } +} diff --git a/credentials/utopia-agency-employee-badge/queries.json b/credentials/utopia-agency-employee-badge/queries.json new file mode 100644 index 0000000..006a33d --- /dev/null +++ b/credentials/utopia-agency-employee-badge/queries.json @@ -0,0 +1,19 @@ +{ + "web": { + "VerifiablePresentation": { + "query": [{ + "type": "QueryByExample", + "credentialQuery": [{ + "reason": "An Agency Employee Badge is required.", + "example": { + "@context": [ + "https://www.w3.org/ns/credentials/v2", + "https://w3id.org/identification/v1rc1" + ], + "type": "IdentificationDocumentCredential" + } + }] + }] + } + } +} From f60ce6027afeb222dd044ae2b84764a99811fbb6 Mon Sep 17 00:00:00 2001 From: Joel Mangin Date: Tue, 21 Jul 2026 11:51:20 -0400 Subject: [PATCH 2/3] Make the agency employee badge example fully generic, drop invalid issuer.type. Was still CA/CHP-flavored despite the "Utopia" swap: issuer named "Utopia Department of Motor Vehicles" issuing a badge for "Utopia Highway Patrol" is just DMV/CHP with a fictional prefix. Replaced with a clearly generic central-issuer + arbitrary-department pattern (Utopia Central Records Office / Utopia Department of Parks and Recreation) that preserves the same field structure (a central authority issuing badges on behalf of a named agency, demonstrating the `agency`/`memberOf` mapping) without evoking any specific real-world agency. Also drops issuer.type: ["Profile"] -- fails safe-mode JSON-LD validation under the identification-vocab context (which, unlike OBv3, doesn't define Profile as a term), and VCDM 2.0 doesn't require issuer.type at all. Verified via `node test/safe-mode-check.js`. --- credentials/utopia-agency-employee-badge/credential.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/credentials/utopia-agency-employee-badge/credential.json b/credentials/utopia-agency-employee-badge/credential.json index 95e5bc4..7dbf109 100644 --- a/credentials/utopia-agency-employee-badge/credential.json +++ b/credentials/utopia-agency-employee-badge/credential.json @@ -10,9 +10,8 @@ "type": ["VerifiableCredential", "IdentificationDocumentCredential"], "name": "Utopia Agency Employee Badge", "issuer": { - "id": "https://www.utopia-dmv.example", - "type": ["Profile"], - "name": "Utopia Department of Motor Vehicles" + "id": "https://www.utopia-records.example", + "name": "Utopia Central Records Office" }, "validFrom": "2026-01-15T00:00:00Z", "validUntil": "2028-01-14T23:59:59Z", @@ -21,6 +20,6 @@ "type": "Person", "givenName": "Jordan", "familyName": "Casey", - "agency": "Utopia Highway Patrol" + "agency": "Utopia Department of Parks and Recreation" } } From c19a72a73bc4c2fa4fe51f77f80ad2db4fe8931a Mon Sep 17 00:00:00 2001 From: Joel Mangin Date: Tue, 21 Jul 2026 14:48:23 -0400 Subject: [PATCH 3/3] Address review feedback: use worksFor instead of ad-hoc agency term. Per Manu Sporny's review: replaces the inline-context `agency` term (mapped to schema.org/memberOf) with `worksFor` (an Organization-typed object with id + name) -- avoids inlining context values in a long-lived example, and models the relationship correctly per schema.org. Also drops the credential and credentialSubject unique identifiers (tracking vector for a person, not needed for this example) and renames the issuer to reflect it's specifically an employment-badge issuer, not a general records office. Restructures queries.json to match the repo's existing convention (top-level "default" key, acceptedCryptosuites list) per Parth Bhatt's review, and adds a worksFor filter to the query example so it specifically requests a badge for this agency. Depends on a companion identification-vocab PR adding worksFor to the Person context -- this repo's safe-mode-check fetches that context live, so it will show a failing check until that PR merges. --- .../credential.json | 16 ++++--- .../utopia-agency-employee-badge/queries.json | 42 ++++++++++++------- 2 files changed, 34 insertions(+), 24 deletions(-) diff --git a/credentials/utopia-agency-employee-badge/credential.json b/credentials/utopia-agency-employee-badge/credential.json index 7dbf109..e5bfc5c 100644 --- a/credentials/utopia-agency-employee-badge/credential.json +++ b/credentials/utopia-agency-employee-badge/credential.json @@ -1,25 +1,23 @@ { "@context": [ "https://www.w3.org/ns/credentials/v2", - "https://w3id.org/identification/v1rc1", - { - "agency": "https://schema.org/memberOf" - } + "https://w3id.org/identification/v1rc1" ], - "id": "urn:uuid:b3d7c2e1-4f5a-6b7c-8d9e-0a1b2c3d4e5f", "type": ["VerifiableCredential", "IdentificationDocumentCredential"], "name": "Utopia Agency Employee Badge", "issuer": { - "id": "https://www.utopia-records.example", - "name": "Utopia Central Records Office" + "id": "https://employment.utopia.example", + "name": "Utopia Employment Agency" }, "validFrom": "2026-01-15T00:00:00Z", "validUntil": "2028-01-14T23:59:59Z", "credentialSubject": { - "id": "urn:uuid:d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a", "type": "Person", "givenName": "Jordan", "familyName": "Casey", - "agency": "Utopia Department of Parks and Recreation" + "worksFor": { + "id": "https://parks.utopia.example/", + "name": "Utopia Department of Parks and Recreation" + } } } diff --git a/credentials/utopia-agency-employee-badge/queries.json b/credentials/utopia-agency-employee-badge/queries.json index 006a33d..a958d16 100644 --- a/credentials/utopia-agency-employee-badge/queries.json +++ b/credentials/utopia-agency-employee-badge/queries.json @@ -1,19 +1,31 @@ { - "web": { - "VerifiablePresentation": { - "query": [{ - "type": "QueryByExample", - "credentialQuery": [{ - "reason": "An Agency Employee Badge is required.", - "example": { - "@context": [ - "https://www.w3.org/ns/credentials/v2", - "https://w3id.org/identification/v1rc1" - ], - "type": "IdentificationDocumentCredential" + "default": { + "type": "QueryByExample", + "credentialQuery": [ + { + "reason": "Please present your IdentificationDocumentCredential Verifiable Credential(s) to complete the verification process.", + "example": { + "@context": [ + "https://www.w3.org/ns/credentials/v2", + "https://w3id.org/identification/v1rc1" + ], + "type": [ + "IdentificationDocumentCredential" + ], + "credentialSubject": { + "worksFor": { + "id": "https://parks.utopia.example/" + } } - }] - }] - } + }, + "acceptedCryptosuites": [ + "Ed25519Signature2020", + "eddsa-rdfc-2022", + "ecdsa-rdfc-2019", + "bbs-2023", + "ecdsa-sd-2023" + ] + } + ] } }