Skip to content

feat: add utopia-agency-employee-badge IdentificationDocument credential#144

Open
applesnort wants to merge 3 commits into
credential-handler:mainfrom
applesnort:feat/utopia-agency-employee-badge
Open

feat: add utopia-agency-employee-badge IdentificationDocument credential#144
applesnort wants to merge 3 commits into
credential-handler:mainfrom
applesnort:feat/utopia-agency-employee-badge

Conversation

@applesnort

@applesnort applesnort commented Jun 30, 2026

Copy link
Copy Markdown

Summary

Adds a Utopia Agency Employee Badge credential — a generic example of an identification document issued to a government agency's own employee.

  • Type: IdentificationDocumentCredential from the Identification Document vocabulary
  • Fields: givenName + familyName (vocab Person type), plus agency as an inline schema.org/memberOf term
  • Issuer: Utopia Central Records Office (a central authority issuing badges on behalf of named agencies)
  • Subject: Jordan Casey, Utopia Department of Parks and Recreation — deliberately a mundane, arbitrary department to keep the example generic rather than modeled on any specific real-world agency

Open questions for reviewers

  1. Is schema.org/memberOf the right mapping for agency, or should we use schema.org/worksFor with an Organization object?
  2. Should we add a renderMethod now or defer to a follow-up?

Test plan

  • Issue this credential from vc-playground
  • Verify it renders in Veres Wallet via the generic IdentificationDocumentCredential card design
  • node test/safe-mode-check.js passes (previously failed on issuer.type: ["Profile"], now removed — identification-vocab doesn't define Profile as a term, and VCDM 2.0 doesn't require issuer.type)

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 @@
{

@bparth24 bparth24 Jul 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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"
        ]
      }
    ]
  }
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"agency": "Utopia Department of Parks and Recreation"
"worksFor": {
"id": "https://parks.utopia.example/",
"name": "Utopia Department of Parks and Recreation"
}

Comment on lines +5 to +7
{
"agency": "https://schema.org/memberOf"
}

@msporny msporny Jul 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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",

@msporny msporny Jul 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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",

@msporny msporny Jul 21, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"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.
@applesnort

Copy link
Copy Markdown
Author

@bparth24 @msporny pushed a commit addressing both sets of feedback:

  • worksFor (Organization-typed, id+name) replacing the ad-hoc inline-context agency term
  • Dropped the credential + credentialSubject ids (tracking vector, not needed)
  • Issuer renamed to reflect it's specifically an employment-badge issuer
  • queries.json restructured to match the repo's existing convention (default key, acceptedCryptosuites), plus a worksFor filter on the query itself

Companion PR adding worksFor to identification-vocab's Person context: digitalbazaar/identification-vocab#1 — this repo's safe-mode check fetches that context live, so it'll show red here until that one merges. Requesting review there too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants