1.0.x
1.0.0
Compare: https://github.com/walt-id/waltid-identity-enterprise/compare/v0.23.1...v1.0.0Release date: 2026-08-24 (UTC)
Mobile wallet SDK and mobile-app changes are omitted.
Highlights
- Introduced product licensing: Enterprise requires a walt.id license to run. Online or offline activation, heartbeat, remote disable, feature allow-lists, usage reporting, Docker Compose wiring, and a dedicated development binary.
- Disabled legacy Issuer, Verifier, and Wallet v1 protocol routes by default. Wallet2 and Verifier2 protocol APIs live under
/v2. - Replaced Wallet
init-walletwith composable/resource-api/services/init. Wallet2 receive/present request and response shapes changed. - Made Verifier2 session bodies consistent (
core_flow, DC API flow types), auto-generatedredirect_uriclient IDs, and added per-service transaction-data profile CRUD. - Cut KMS, credential-status signing, X.509/VICAL, and protocol crypto over to Crypto2. Refactored the X.509 certificate store API.
- Cut over data ejection for issuer1/verifier1 sessions and OAuth artefacts; removed the Data Retention service.
Features
Licensing
- Production deployments activate with a license credential (OpenID credential offer, raw SD-JWT VC, or an offline
.waltlicensebundle plus installation key). - After first activation, the bound credential and installation key are stored encrypted in MongoDB (
LICENSE_STATE_ENCRYPTION_KEYmust be shared across replicas and backed up). Later restarts reuse that state; an online offer is never redeemed twice. - The stack heartbeats to the walt.id license server. walt.id can remotely disable a license or surgically disable individual features via the license VC (
featuresallow-list anddisabledFeaturesoverride). - Feature flags in
_features.confstill apply, but a feature also has to be allowed by the active license. - Super-admin endpoints:
GET /license/status,GET /license/usage,GET /license/usage-report(signed SD-JWT),POST /license/usage-report/export(offline bundle). - Split artifacts:
waltid-enterprise-api(production, compiled-in issuer trust) andwaltid-enterprise-api-development(local issuer). Production cannot be pointed at a customer-controlled license issuer. - Cluster-aware pod slot leases so replica count cannot exceed the licensed fleet size.
- Offline / air-gapped mode: mount the
.waltlicensebundle and installation key; export signed usage reports when the license server cannot be reached. - Docker Compose and Kubernetes examples ship with license secret wiring (
waltid-enterprise-license).
Wallet2 as the default wallet
- Migrated Enterprise UI and protocol routes to Wallet2 under
/v2/{target}/wallet-service-api/.... - Added isolated presentation steps (preview claims, reject, then build/submit).
- Added
urn:eudi:sca:payment:1andpayment_cardtransaction-data support, authorized mdoc data types, and per-service transaction-data profile CRUD (GETwith present/create-session permissions;POST/PUT/DELETErequireUPDATE_SERVICE_CONFIGURATION). - Wallet-initiated OID4VCI can read the issuer's linked credential-status configuration on the public authorize/callback path.
Verifier2
- Aligned verification-session create bodies across flow types, including Digital Credentials API.
- Applied the shared rate-limit config to verifier protocol endpoints.
- When
clientIdis omitted or blank on unsigned cross-device sessions, generateredirect_uri:<response_uri>. - Updated Portal2 Digital Credentials API examples.
- Locked session callback event sequences for live W3C, SD-JWT, and mdoc presentations.
Issuer2
- Published stage and failure events across the OpenID4VCI issuance flow on session SSE/webhooks and a per-issuer SSE stream.
- Added EdDSA to default
proofSigningAlgValuesSupported. - Removed leftover
c_noncecompatibility paths. - OpenAPI examples use purpose-specific AT test leaves: mDL uses a Document Signer leaf with the ISO mdoc DS EKU; SD-JWT VC uses a separate leaf without that EKU.
x5Chainstays leaf-only. - Client-attestation
key-referenceverification works on anonymous OID4VCI token/PAR requests. - Added stopwatch marks around session init and the OID4VCI callback.
Platform
- Added an endpoint to list all supported permissions.
- Superadmin registration now uses a typed request object.
- Cut remaining issuer1/verifier1 sessions and OAuth tokens (PAR, pre-auth codes, auth codes, refresh tokens) over to data ejection / TTL.
- Stored API key tokens as Argon2id hashes (existing keys are migrated).
- Made the durable eIDAS hash-chain audit log an optional
eidas-auditfeature (default off). Audit HTTP routes are registered only when it is enabled. - Extended eIDAS audit fields:
loaAchieved,identityProofingRefId,revocationStatusEvidence,verifierTrustEvidence, andpairwiseSubjectId. - Deprecated feature flags emit WARN and continue startup instead of failing the process.
- Restored the public tenant-scoped DID document shortcut
GET /{tenant}/{id}/did.json.
Operations / repository
- Removed in-repo Keycloak and Ory demo trees, the Enterprise demo app, the in-tree Enterprise Gateway copy, load-testing CLI, and leftover local secrets/scripts. Use the published docs and quickstart repositories for those workflows.
- Tightened the Azure Key Vault access-policy target used in cloud CI.
- Updated issuer certificates used by tests and examples.
- Added SBOM generation and patched a HIGH
nanoidCVE in the UI dependency tree.
Crypto / KMS / X.509
- Cut KMS, credential-status signing (CWT/JWT/W3C), client attestation, and Issuer2/Verifier2/Wallet2 crypto over to Crypto2.
- Stored local v1 JWK keys are migrated automatically; remote KMS keys stay attached through the Enterprise KMS adapter.
- PKCS#11 / HSM and cloud KMS paths run on the Crypto2 backends. X.509 (IACA, document signer, CSR, generic certificates) and VICAL sign through Crypto2 using
capabilities.signer. - Published JWT/JAR/JWKS/DID
kidvalues for external KMS keys are JWK thumbprints or DID URLs, not cloud-KMS locator URLs. - Added X.509 certificate helpers (CSR and certificate create/sign). ISO mDL document-signer onboarding requires the IACA root CA PEM.
- Refactored the X.509 certificate store: no store-side certificate validation; stored records include issuer/subject DN and validity attributes; create/update return the certificate. VICAL data lives on
metadata(complementaryMetadatais deprecated).
Fixes and improvements
- Fixed eIDAS audit coverage for credential-status updates (hex and index-based revoke now produce
REVOKEDlifecycle events). Serialized chain-verification results for verify-chain audit. - Scoped
VIEW_AUDIT_LOGto the bodytarget, and reject audit queries whoseorganizationIddoes not match the host. - Mapped Wallet2 token-exchange failures to the upstream OAuth status (or
502) instead of a generic500. - Friendlier 400 messages when request bodies fail to decode.
- Covered retained KMS keys on verifier
request_uriPOST re-sign. - Corrected the CWT status-list content-type label (label 16).
- Stopped API key loading from running as the system user (permission-escalation fix).
- Upgraded kotlinx.serialization CBOR via the walt.id fork.
Breaking changes
Review these before upgrading. Legacy v1 protocol routes can still be turned on with feature flags where noted.
License required to run
- The Enterprise API does not serve traffic without an active license. Unlicensed or restricted nodes return
503on all routes except/livez, login/logout,GET /license/status, and usage-report export. - First startup needs
license.conf(seedCredential,seedCredentialFile, or an online offer) plusLICENSE_STATE_ENCRYPTION_KEYon every replica. Changing that key without re-encrypting stored state makes the installation unreadable. _features.confis no longer sufficient: features must also be allowed by the license VC. walt.id can remotely disable features or the whole license.- Production images trust only the compiled-in walt.id license issuer. Local development uses the separate
waltid-enterprise-api-developmentartifact. - Replica count cannot exceed the licensed fleet size (pod slot leases).
Legacy services disabled by default
- Issuer v1, Verifier v1, and Wallet v1 protocol routes are off unless the corresponding feature flag is enabled (
wallet-draft-routesfor Wallet1). - New deployments should use Issuer2, Verifier2, and Wallet2.
Wallet
init-wallet removed
- Old:
POST /v1/{org}.{tenant}/wallet-service-api/init-wallet - New:
POST /v1/{org}.{tenant}/resource-api/services/initwith a composablewalletpayload (optional KMS, DID store/service, credential store). - Response is a
walletresult object. The service type iswallet2, notwallet.
Protocol routes moved to /v2
- Wallet2 receive, present, client attestation, and dependency routes are
/v2/{target}/wallet-service-api/..., not/v1. - Examples:
.../credentials/receive/pre-authorized,.../credentials/present,.../client-attestation/obtain.
Receive body and response
useClientAttestationandrunPoliciesare no longer request fields. Client attestation is used automatically when the issuer advertises it and the wallet has a linked client attester.- Provide
offerUrl(orofferJson) and optionalkeyReference/did. - Response is an object
{ "credentialIds": [...], "deferredTransactionIds": {} }, not an array of stored credentials.
Present body
didReferenceis nowdid(inline DID string or DID-store reference).- The full-flow present endpoint no longer accepts a
credentialsarray; it DCQL-matches from the wallet credential store. - To present inline credentials, use
POST /v2/{wallet}/wallet-service-api/credentials/present/isolated.
Verifier2
Protocol routes moved to /v2/.../verifier-service-api
- Old:
/v1/{target}/verifier2-service-api/{endpoint} - New:
/v2/{target}/verifier-service-api/{endpoint} - Service create is unchanged:
POST /v1/{target}/resource-api/services/createwith"type": "verifier2".
DC API session body
flow_type: "dc_api"is removed. Use"dc_api_openid4vp"or"dc_api_18013_7".- Nested config field is
core_flow, notcore. expectedOriginsmust be HTTPS secure-context origins (no trailing slash). HTTP local origins are rejected.
Client ID
- Omitting
clientIdon unsigned cross-device sessions now setsredirect_uri:<response_uri>. Signed requests must supply a realclientId.
DID service
- Create DID fields
keyId/keyIdSetare nowkeyReference/keyReferenceSet. - You may pass an inline
key(JWK) instead of a stored-key reference. - URLs unchanged (
POST /v1/{did-service}/did-service-api/dids/create/key|jwk|web).
Superadmin registration
- The registration token is no longer a raw string. Send:
{
"token": "superadmin-token"
}
Service dependencies
POST .../dependencies/addno longer accepts a raw path string. Send:
{
"dependency": "org.tenant.kms"
}
Dev setup
POST /v1/admin/initial-setupis gone. UsePOST /v1/dev/initial-setup(requires thedev-modefeature).
Data Retention service removed
- Session and OAuth artefact expiry is handled by data ejection / TTLs. Remove Data Retention service configuration and calls.
External KMS key IDs
- Published
kidvalues in JWT, JAR, JWKS, and DID documents are thumbprints or DID URLs, not vault/KMS locator URLs.
ISO mDL document-signer onboarding
iacaSignerrequires the IACA root CA PEM.
X.509 certificate store
PUT /v1/{target}/x509-store-api/certificatesinserts or updates and returns the certificate.POST /v1/{target}/x509-store-api/certificatesinserts only and fails if the certificate id already exists.- The store no longer validates the certificate.
typeis ignored. Usemetadatainstead of deprecatedcomplementaryMetadatafor VICAL entries.
eIDAS audit
- The durable eIDAS audit log is off unless the
eidas-auditfeature is enabled. Audit HTTP routes are absent when the feature is off.
Certificates
- mdoc and SD-JWT issuance examples/profiles no longer share one end-entity certificate. mdoc uses a Document Signer leaf; SD-JWT uses a separate leaf. IACA stays a verifier trust anchor, not part of
x5Chain.
Last updated on August 24, 2026
