feat: add utopia-agency-employee-badge IdentificationDocument credential#144
feat: add utopia-agency-employee-badge IdentificationDocument credential#144applesnort wants to merge 3 commits into
Conversation
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.
…suer.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`.
| @@ -0,0 +1,19 @@ | |||
| { | |||
There was a problem hiding this comment.
@applesnort cc: @BigBlueHat @jameseaster
I would suggest to follow the structure for queries.json file from existing examples in the repo
an example:
{
"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"
]
},
"acceptedCryptosuites": [
"Ed25519Signature2020",
"eddsa-rdfc-2022",
"ecdsa-rdfc-2019",
"bbs-2023",
"ecdsa-sd-2023"
]
}
]
}
}
There was a problem hiding this comment.
Add this, because you're looking for a very specific type of identification badge that specifies that the individual works for a particular agency.
"worksFor": {
"id": "https://parks.utopia.example/"
}
| "type": "Person", | ||
| "givenName": "Jordan", | ||
| "familyName": "Casey", | ||
| "agency": "Utopia Department of Parks and Recreation" |
There was a problem hiding this comment.
| "agency": "Utopia Department of Parks and Recreation" | |
| "worksFor": { | |
| "id": "https://parks.utopia.example/", | |
| "name": "Utopia Department of Parks and Recreation" | |
| } |
| { | ||
| "agency": "https://schema.org/memberOf" | ||
| } |
There was a problem hiding this comment.
We should not be inlining context values in long-lived examples.
| "validFrom": "2026-01-15T00:00:00Z", | ||
| "validUntil": "2028-01-14T23:59:59Z", | ||
| "credentialSubject": { | ||
| "id": "urn:uuid:d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a", |
There was a problem hiding this comment.
| "id": "urn:uuid:d4e5f6a7-b8c9-0d1e-2f3a-4b5c6d7e8f9a", |
Don't use unique identifiers for people unless absolutely necessary, it creates a tracking vector for the person.
| "agency": "https://schema.org/memberOf" | ||
| } | ||
| ], | ||
| "id": "urn:uuid:b3d7c2e1-4f5a-6b7c-8d9e-0a1b2c3d4e5f", |
There was a problem hiding this comment.
| "id": "urn:uuid:b3d7c2e1-4f5a-6b7c-8d9e-0a1b2c3d4e5f", |
Not needed, either.
| "type": ["VerifiableCredential", "IdentificationDocumentCredential"], | ||
| "name": "Utopia Agency Employee Badge", | ||
| "issuer": { | ||
| "id": "https://www.utopia-records.example", |
There was a problem hiding this comment.
| "id": "https://www.utopia-records.example", | |
| "id": "https://employment.utopia.example", |
| "name": "Utopia Agency Employee Badge", | ||
| "issuer": { | ||
| "id": "https://www.utopia-records.example", | ||
| "name": "Utopia Central Records Office" |
There was a problem hiding this comment.
| "name": "Utopia Central Records Office" | |
| "name": "Utopia Employment Agency" |
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.
|
@bparth24 @msporny pushed a commit addressing both sets of feedback:
Companion PR adding |
Summary
Adds a Utopia Agency Employee Badge credential — a generic example of an identification document issued to a government agency's own employee.
IdentificationDocumentCredentialfrom the Identification Document vocabularygivenName+familyName(vocabPersontype), plusagencyas an inlineschema.org/memberOftermOpen questions for reviewers
schema.org/memberOfthe right mapping foragency, or should we useschema.org/worksForwith anOrganizationobject?renderMethodnow or defer to a follow-up?Test plan
IdentificationDocumentCredentialcard designnode test/safe-mode-check.jspasses (previously failed onissuer.type: ["Profile"], now removed — identification-vocab doesn't defineProfileas a term, and VCDM 2.0 doesn't requireissuer.type)