W3C Verifiable Credentials Data Model 2.0
El W3C Verifiable Credentials Data Model 2.0 es la recomendación oficial del W3C que define la estructura de datos de una credencial verificable: qué campos lleva, cómo se serializan, cómo se prueba criptográficamente. Es la base de toda la stack VC.
A diferencia de la versión 1.1, la 2.0 desacopla el modelo de datos de los mecanismos de firma, permitiendo combinar el formato canónico con distintos esquemas criptográficos (JWT, COSE, Data Integrity Proofs, SD-JWT). Eso lo hace mucho más flexible y adoptable por implementaciones existentes.
Estado y mantenimiento
Maduración
Recomendación final: mayo 2025. Mantenida por el W3C Verifiable Credentials Working Group. Reemplaza a la VC Data Model 1.1 (publicada en 2019).
Adopción
Implementada en EUDI Wallet (Unión Europea), proyectos gov de US/Canadá/UK, frameworks como Spruce, Mattr, Trinsic, QuarkID. Es la lingua franca de la industria SSI.
Spec oficial: https://www.w3.org/TR/vc-data-model-2.0/
Qué cambia respecto de 1.1
| Aspecto | 1.1 | 2.0 |
|---|---|---|
| Contextos JSON-LD | Obligatorio entender JSON-LD para procesamiento básico | JSON-LD opcional para procesamiento básico |
| Securing mechanism | Acoplado al modelo (Linked Data Proofs) | Desacoplado: vc-jose-cose, vc-di-eddsa, etc. |
| Renderable templates | No | Sí (renderMethod) |
| Refresh service | Confuso, mal especificado | Refinado, bien tipado |
| Status mechanism | StatusList2021 | BitstringStatusList (canonical) |
| Validity period | issuanceDate / expirationDate | validFrom / validUntil (más estricto) |
| Identifier requirements | id obligatorio para algunos casos | Más permisivo |
La separación entre modelo y firma es el cambio más profundo. En 1.1 si querías una VC tenías que envolverla en una prueba criptográfica específica. En 2.0 podés definir la VC abstracta y firmarla con el mecanismo que prefieras —JWT para entornos OAuth, COSE para mDoc, SD-JWT para selective disclosure, Data Integrity para JSON-LD nativo.
Estructura mínima de una VC 2.0
{
"@context": [
"https://www.w3.org/ns/credentials/v2"
],
"id": "https://salta.gob.ar/credentials/3732",
"type": ["VerifiableCredential", "ConstanciaDomicilio"],
"issuer": "did:web:salta.gob.ar",
"validFrom": "2026-05-17T00:00:00Z",
"validUntil": "2027-05-17T00:00:00Z",
"credentialSubject": {
"id": "did:quarkid:sovra:EiAB...",
"nombre": "Juan Pérez",
"domicilio": {
"calle": "Av. Belgrano 1234",
"localidad": "Salta Capital",
"provincia": "Salta"
}
},
"credentialStatus": {
"id": "https://salta.gob.ar/credentials/status/3#94567",
"type": "BitstringStatusListEntry",
"statusPurpose": "revocation",
"statusListIndex": "94567",
"statusListCredential": "https://salta.gob.ar/credentials/status/3"
}
}
Esa VC pasa a tener una securing layer (firma) aparte, que puede ser:
vc-jose-cose
VC envuelta como JWT firmado. Formato dominante en gov: reutiliza la infraestructura OAuth y es trivialmente verificable con bibliotecas estándar de JWT.
vc-di-eddsa
Data Integrity Proof con Ed25519 embebido en el JSON. Mantiene el JSON-LD legible; preferido cuando se trabaja con grafos semánticos.
SD-JWT VC
Formato derivado, optimizado para divulgación selectiva. Permite ocultar atributos individuales sin romper la firma. Canónico para wallets que priorizan privacidad.
Campos obligatorios
| Campo | Tipo | Significado |
|---|---|---|
@context | array | Define vocabulario semántico (al menos https://www.w3.org/ns/credentials/v2) |
type | array | Tipo principal (VerifiableCredential) + subtipos específicos del dominio |
issuer | URI u objeto | Quién emite (típicamente un DID) |
credentialSubject | objeto | Qué se afirma y sobre quién |
validFrom | xsd:dateTime | Desde cuándo es válida |
Opcionales pero típicos: id, validUntil, credentialStatus, credentialSchema, evidence, termsOfUse, refreshService.
El campo type
El array type siempre incluye VerifiableCredential como primer elemento. Los elementos siguientes definen el tipo específico de credencial: ConstanciaDomicilio, LicenciaConducir, MatriculaProfesional, etc.
Para que distintas implementaciones reconozcan el mismo tipo, conviene registrar los esquemas en un repositorio común. La práctica habitual: cada emisor publica el JSON Schema de su credencial en una URL accesible y lo referencia desde el campo credentialSchema.
credentialSubject: el corazón de la credencial
El bloque credentialSubject lleva los datos que se están certificando. Puede ser un objeto único o un array de objetos. El campo id dentro de subject —típicamente un DID— identifica al titular.
Buenas prácticas para credentialSubject:
- Granularidad atómica: estructurá los campos pensando en selective disclosure. Un campo
nombremejor que un solo string"Juan Pérez, DNI 12345678, Domicilio X". - Tipos primitivos: usar
string,number,boolean,datecuando se pueda; evitar objetos anidados profundos. - Sin datos derivados: si un dato se puede calcular a partir de otro (mayoría de edad a partir de fecha de nacimiento), elegir uno solo según el caso de uso. Mayoría de edad da más privacidad.
Recomendaciones de implementación
Para emisores que arrancan hoy:
- Formato canónico: SD-JWT VC. Hereda la estructura de VC 2.0 y le suma divulgación selectiva nativa. Es el default en la mayoría de stacks open-source.
- Status mechanism: BitstringStatusList. La 2.0 lo establece como canónico; StatusList2021 quedó como legacy.
- Issuer DID:
did:webpara organizaciones,did:quarkidodid:keypara wallets de holders. - Versioning del schema: incluir versión del schema en el
credentialSchemay mantener compatibilidad hacia atrás durante el periodo de validez de credenciales viejas.
Implementación rápida (TypeScript)
import { createSDJWTCredential } from "@sovrahq/agent";
const vc = await createSDJWTCredential({
issuer: "did:web:salta.gob.ar",
subject: holderDid,
type: ["VerifiableCredential", "ConstanciaDomicilio"],
claims: {
nombre: "Juan Pérez",
localidad: "Salta Capital",
provincia: "Salta",
},
validUntil: "2027-05-17T00:00:00Z",
credentialStatus: {
type: "BitstringStatusListEntry",
statusPurpose: "revocation",
statusListIndex: assignNextIndex(),
statusListCredential: "https://salta.gob.ar/credentials/status/3",
},
});
Referencias
- W3C VC Data Model 2.0 — Recommendation
- W3C VC JOSE COSE 1.0
- W3C BitstringStatusList
- SD-JWT VC Draft (IETF)
Relacionados
- Cómo emite credenciales un sistema con OID4VCI — protocolo de emisión
- Revocar credenciales sin perder privacidad — mecanismo de revocación canonical
- ¿Qué es una credencial verificable? — la base conceptual

