Saltar al contenido principal

Identidad y Credenciales

Resumen​

ULedgerNET implementa una capa de identidad conforme a estándares sobre su sistema de billeteras y entities:

  • Identificadores Descentralizados (DIDs): identificadores del estándar W3C DID Core para billeteras y entities.
  • Credenciales Verificables (VCs): afirmaciones firmadas, según el W3C Verifiable Credential Data Model 2.0, sobre sujetos DID.

Estos estándares permiten que las identidades de ULedgerNET interoperen con infraestructura de identidad externa, cumplan con W3C y con las regulaciones emergentes, y sirvan como base para atestaciones verificables y legibles por máquina sobre agentes, entities y sus permisos.


Identificadores Descentralizados (DIDs)​

Formato​

Toda billetera y entity en ULedgerNET tiene un DID:

did:ulnet:<chainId>:<address>

Ejemplos:

did:ulnet:ca930ce44643b66ae33d54351cc0557d1d904b85ec9256fb7ee34fe5e3c318b4:8e620db359101eb28bf9db4f08c2677349f7747d1c59528774f2193318b8c1c7

did:ulnet:ca930ce44643b66ae33d54351cc0557d1d904b85ec9256fb7ee34fe5e3c318b4:<entity-address>
  • ulnet: el método DID de ULedgerNET.
  • <chainId>: el ID del blockchain (hash hexadecimal) que identifica la chain específica.
  • <address>: la dirección de la billetera (SHA256 de la clave pública) o la dirección de la entity (ID de la transaction de creación).

Documento DID​

Un documento DID es la descripción legible por máquina de un sujeto DID. Contiene métodos de verificación (claves públicas) y las relaciones de capability entre el sujeto y otros DIDs.

{
"@context": ["https://www.w3.org/ns/did/v1"],
"id": "did:ulnet:<chainId>:<walletAddress>",
"verificationMethod": [
{
"id": "did:ulnet:<chainId>:<walletAddress>#key-1",
"type": "EcdsaSecp256k1VerificationKey2019",
"controller": "did:ulnet:<chainId>:<walletAddress>",
"publicKeyJwk": { ... }
}
],
"authentication": ["did:ulnet:<chainId>:<walletAddress>#key-1"],
"assertionMethod": ["did:ulnet:<chainId>:<walletAddress>#key-1"],
"capabilityDelegation": ["did:ulnet:<chainId>:<parentWalletAddress>"]
}

Para claves post-cuánticas (ML-DSA-87), el método de verificación usa publicKeyMultibase en lugar de publicKeyJwk.

Metadata del Documento DID​

La información específica de la entity se incluye en didDocumentMetadata, no en el documento en sí:

{
"didDocumentMetadata": {
"entityType": "AGENT",
"name": "alice-research-agent",
"capabilities": [...],
"created": "<block-height>",
"enabled": true
}
}

Esta separación mantiene el documento DID en sí conforme a W3C, a la vez que expone las extensiones específicas de ULedgerNET mediante metadata.

Algoritmos de Clave en Documentos DID​

Tipo de ClaveRepresentación DIDAlgoritmo JWS
secp256k1publicKeyJwk (EC, crv: secp256k1)ES256K
ed25519publicKeyJwk (OKP, crv: Ed25519)EdDSA
mldsa87publicKeyMultibaseML-DSA-87 (borrador)
bls12377(rechazada para la emisión de credenciales)N/A

Credenciales Verificables (VCs)​

Qué Son​

Una Credencial Verificable es una afirmación firmada criptográficamente sobre un sujeto DID. En el contexto de ULedgerNET, las credenciales sirven como atestaciones legibles por máquina sobre:

  • A qué entity pertenece una billetera de agente.
  • Qué rol y permisos tiene una billetera.
  • Qué capabilities está autorizada a ejercer la billetera.
  • Que una transaction específica ocurrió en un bloque específico (credenciales de autenticación).

Tipos de Credencial​

1. Credencial de Identidad (ULedgerIdentityCredential)​

Atestigua la identidad y el rol organizacional de una billetera:

{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiableCredential", "ULedgerIdentityCredential"],
"issuer": "did:ulnet:<chainId>:<issuerAddress>",
"validFrom": "<ISO-8601>",
"credentialSubject": {
"id": "did:ulnet:<chainId>:<walletAddress>",
"entityType": "AGENT",
"role": "admin",
"capabilities": [
{
"action": "contract:invoke",
"resource": "<contract-address>",
"notAfter": 100000
}
],
"validUntilBlock": 100000
}
}

Casos de uso:

  • Presentar las credenciales de un agente a un sistema externo que necesita verificar su alcance.
  • Documentación de cumplimiento: prueba de que un agente estaba autorizado a actuar en un momento dado.
  • Incorporación (onboarding): credencial legible por máquina que un nuevo agente presenta a un contract para auto-registrarse.

2. Credencial de Autenticación (ULedgerAuthenticationCredential)​

Atestigua que una billetera específica firmó una transaction específica:

{
"@context": ["https://www.w3.org/ns/credentials/v2"],
"type": ["VerifiableCredential", "ULedgerAuthenticationCredential"],
"issuer": "did:ulnet:<chainId>:<nodeAddress>",
"credentialSubject": {
"id": "did:ulnet:<chainId>:<walletAddress>",
"transactionId": "<txId>",
"blockHash": "<blockHash>",
"audience": "<targetDID>"
}
}

Casos de uso:

  • Demostrar a un servicio externo que una billetera firmó una acción específica.
  • Autenticación entre sistemas: una billetera en ULedgerNET se autentica ante una API externa presentando una credencial firmada por el node.

Formato JWT/JWS​

Las credenciales se codifican como JWTs:

Header: { "alg": "ES256K", "typ": "vc+jwt" }
Payload: { ...credential claims... }
Signature: signed by issuer's private key

El encabezado typ: "vc+jwt" es requerido por la especificación W3C VC 2.0.

Emisión​

Las credenciales se emiten mediante el endpoint de credenciales del node:

POST /credentials/{chainId}/issue
  • Con límite de tasa por IP.
  • Requiere que la billetera solicitante esté registrada y habilitada en la chain.
  • Devuelve una credencial JWT firmada.

Revocación​

La revocación utiliza la especificación W3C Bitstring Status List. Una entrada de estado de revocación se incrusta en la credencial y apunta a una lista de estado mantenida por el node emisor. Verificar el estado de revocación requiere obtener la lista de estado del node.

Estado Local del Node​

Crítico: El registro de credenciales es local al node. No se replica en el council. Cada node emite y rastrea de forma independiente sus propias credenciales. La operación Load durante la reconciliación del node excluye deliberadamente el registro de credenciales para evitar que el estado de un peer sobrescriba los registros de credenciales locales de un node.

Implicaciones:

  • Una credencial emitida por el Node 1 es rastreada por el registro del Node 1, no por el del Node 2.
  • El estado de revocación debe verificarse contra el node emisor.
  • Para la portabilidad de credenciales entre nodes, el JWT de la credencial (que es autocontenido) es el artefacto portable, no la entrada del registro.

Ciclo de Vida de la Identidad (SDK de Go)​

El runner cmd/identity del SDK de Go cubre el ciclo de vida completo de la identidad:

go run ./cmd/identity --config identities.json

Pasos realizados:

  1. Creación de DID: registrar billeteras, creando su DID on-chain.
  2. Creación de entity: crear la entity AGENT vinculada a la billetera propietaria.
  3. Creación de entity hija: crear una entity hija (p. ej., un sub-agente).
  4. Alteración de metadata: actualizar la metadata de la entity mediante ALTER_ENTITY.
  5. Configuración de recuperación: establecer las billeteras de recuperación y el umbral.
  6. Gestión de la lista de acceso: agregar contrapartes de confianza o entradas de lista negra.
  7. Transferencia de propiedad: transferir la entity a una nueva billetera propietaria.
  8. Emisión de credenciales: emitir una ULedgerIdentityCredential para el agente.
  9. Ejecución de recuperación: simular la pérdida de claves; ejecutar la recuperación mediante aprobación por umbral.

El runner informa aprobado/fallido por cada paso y guarda un reporte JSON con marca de tiempo.

Configuración de Identidad (identities.json)​

{
"nodeEndpoints": [...],
"blockchainId": "ca930ce4...",
"chainKeyType": "mldsa87",
"wallets": {
"owner": "./wallets-uis-mldsa/<hash>.ukey",
"admin": "./wallets-uis-mldsa/<hash>.ukey",
"newOwner": "./wallets-uis-mldsa/<hash>.ukey",
"agent": "./wallets-uis-mldsa/<hash>.ukey",
"recovery": [
"./wallets-uis-mldsa/<hash1>.ukey",
"./wallets-uis-mldsa/<hash2>.ukey",
"./wallets-uis-mldsa/<hash3>.ukey"
]
},
"entity": {
"name": "merchant-entity",
"type": "ORGANIZATION",
"metadata": { "description": "Demo merchant organization" }
},
"child": {
"name": "alice-agent",
"type": "AGENT",
"metadata": { "description": "Shopper agent" }
},
"recovery": { "threshold": 2 },
"credentials": {
"enabled": true,
"operatorPassword": "...",
"operatorSalt": "..."
}
}