@eudiplo/cli 9.1.0-main.8be8b4e → 9.1.0-main.8e6a2ad

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -22105,6 +22105,58 @@ function findUnsupportedClaimPatterns(fields, path2 = "") {
22105
22105
  return problems;
22106
22106
  }
22107
22107
 
22108
+ // ../../packages/eudiplo-config-format/dist/display-entries.js
22109
+ var NUMBER = String.raw`[+-]?(?:\d+(?:\.\d+)?|\.\d+)`;
22110
+ var INTEGER = String.raw`[+-]?\d+`;
22111
+ var PERCENTAGE = `${NUMBER}%`;
22112
+ function colorFunction(name, args) {
22113
+ return String.raw`${name}\( *${args.join(" *, *")} *\)`;
22114
+ }
22115
+ var DISPLAY_COLOR_PATTERN = `^(?:${[
22116
+ "#(?:[0-9a-fA-F]{3}){1,2}",
22117
+ colorFunction("rgb", [INTEGER, INTEGER, INTEGER]),
22118
+ colorFunction("rgb", [PERCENTAGE, PERCENTAGE, PERCENTAGE]),
22119
+ colorFunction("rgba", [INTEGER, INTEGER, INTEGER, NUMBER]),
22120
+ colorFunction("rgba", [PERCENTAGE, PERCENTAGE, PERCENTAGE, NUMBER]),
22121
+ colorFunction("hsl", [NUMBER, PERCENTAGE, PERCENTAGE]),
22122
+ colorFunction("hsla", [NUMBER, PERCENTAGE, PERCENTAGE, NUMBER]),
22123
+ "transparent"
22124
+ ].join("|")})$`;
22125
+ var DISPLAY_COLOR = new RegExp(DISPLAY_COLOR_PATTERN);
22126
+ var DISPLAY_COLOR_MESSAGE = "Use a CSS Color Level 3 numerical value: #rgb, #rrggbb, transparent, or lowercase rgb(), rgba(), hsl() or hsla() with comma-separated values, for example rgb(18, 16, 124).";
22127
+ function isDisplayColor(value) {
22128
+ return DISPLAY_COLOR.test(value);
22129
+ }
22130
+ var DISPLAY_COLOR_KEYS = ["background_color", "text_color"];
22131
+ function readableDisplayColor(value) {
22132
+ if (typeof value !== "string")
22133
+ return void 0;
22134
+ const color = value.trim();
22135
+ if (isDisplayColor(color))
22136
+ return color;
22137
+ const lowercase = color.toLowerCase();
22138
+ return isDisplayColor(lowercase) ? lowercase : void 0;
22139
+ }
22140
+ function findDuplicateDisplayLocales(display) {
22141
+ const first = /* @__PURE__ */ new Map();
22142
+ const duplicates = [];
22143
+ display.forEach((entry, index) => {
22144
+ const locale = typeof entry === "object" && entry !== null ? entry.locale : void 0;
22145
+ if (typeof locale !== "string" || locale === "")
22146
+ return;
22147
+ const key = locale.toLowerCase();
22148
+ const firstIndex = first.get(key);
22149
+ if (firstIndex === void 0)
22150
+ first.set(key, index);
22151
+ else
22152
+ duplicates.push({ index, firstIndex, locale });
22153
+ });
22154
+ return duplicates;
22155
+ }
22156
+ function duplicateDisplayLocaleMessage(duplicate) {
22157
+ return `Locale ${duplicate.locale} is already used by display entry ${duplicate.firstIndex + 1}. OID4VCI allows one display entry per language.`;
22158
+ }
22159
+
22108
22160
  // ../../packages/eudiplo-config-format/dist/config-format.js
22109
22161
  var CONFIG_FORMATS = {
22110
22162
  Tenant: { slug: "tenant", file: "TenantConfigFile", version: 4 },
@@ -22129,7 +22181,7 @@ var CONFIG_FORMATS = {
22129
22181
  CredentialConfig: {
22130
22182
  slug: "credential-config",
22131
22183
  file: "CredentialConfigFile",
22132
- version: 3
22184
+ version: 4
22133
22185
  },
22134
22186
  PresentationConfig: {
22135
22187
  slug: "presentation-config",
@@ -22367,6 +22419,60 @@ var credentialConfigV2ToV3 = {
22367
22419
  };
22368
22420
  }
22369
22421
  };
22422
+ var credentialConfigV3ToV4 = {
22423
+ id: "credential-config-v4-display-colors-locales",
22424
+ kind: "CredentialConfig",
22425
+ from: 3,
22426
+ to: 4,
22427
+ migrate(spec) {
22428
+ const config = spec.config;
22429
+ if (typeof config !== "object" || config === null || !Array.isArray(config.display))
22430
+ return { spec };
22431
+ const issues = [];
22432
+ let changed = false;
22433
+ const display = config.display.map((entry, index) => {
22434
+ if (typeof entry !== "object" || entry === null)
22435
+ return entry;
22436
+ const next = { ...entry };
22437
+ for (const key of DISPLAY_COLOR_KEYS) {
22438
+ const value = next[key];
22439
+ if (value === void 0)
22440
+ continue;
22441
+ const color = readableDisplayColor(value);
22442
+ if (color === value)
22443
+ continue;
22444
+ changed = true;
22445
+ if (color !== void 0) {
22446
+ next[key] = color;
22447
+ continue;
22448
+ }
22449
+ delete next[key];
22450
+ if (typeof value === "string" && value.trim() === "")
22451
+ continue;
22452
+ issues.push({
22453
+ severity: "warning",
22454
+ code: "DISPLAY_COLOR_REMOVED",
22455
+ path: `/spec/config/display/${index}/${key}`,
22456
+ message: `Removed ${JSON.stringify(value)}, so wallets use their own color. ${DISPLAY_COLOR_MESSAGE}`
22457
+ });
22458
+ }
22459
+ return next;
22460
+ });
22461
+ for (const duplicate of findDuplicateDisplayLocales(display))
22462
+ issues.push({
22463
+ severity: "required-input",
22464
+ code: "DISPLAY_LOCALE_DUPLICATE",
22465
+ path: `/spec/config/display/${duplicate.index}/locale`,
22466
+ message: duplicateDisplayLocaleMessage(duplicate)
22467
+ });
22468
+ if (!changed && issues.length === 0)
22469
+ return { spec };
22470
+ return {
22471
+ spec: changed ? { ...spec, config: { ...config, display } } : spec,
22472
+ issues
22473
+ };
22474
+ }
22475
+ };
22370
22476
  var CONFIG_MIGRATIONS = [
22371
22477
  {
22372
22478
  id: "issuance-config-v2-offer-lifetime",
@@ -22505,6 +22611,7 @@ var CONFIG_MIGRATIONS = [
22505
22611
  migrate: (spec) => ({ spec })
22506
22612
  },
22507
22613
  credentialConfigV2ToV3,
22614
+ credentialConfigV3ToV4,
22508
22615
  presentationConfigV1ToV2,
22509
22616
  {
22510
22617
  id: "presentation-config-v3-typed-claim-values",
@@ -34969,13 +35076,13 @@ var CONFIG_SCHEMAS = [
34969
35076
  },
34970
35077
  {
34971
35078
  "$schema": "https://json-schema.org/draft/2020-12/schema",
34972
- "$id": "https://eudiplo.dev/schemas/v4/IssuanceConfigFile.schema.json",
34973
- "title": "IssuanceConfigFile",
35079
+ "$id": "https://eudiplo.dev/schemas/v4/CredentialConfigFile.schema.json",
35080
+ "title": "CredentialConfigFile",
34974
35081
  "type": "object",
34975
35082
  "properties": {
34976
35083
  "$schema": {
34977
35084
  "type": "string",
34978
- "const": "https://eudiplo.dev/schemas/v4/IssuanceConfigFile.schema.json"
35085
+ "const": "https://eudiplo.dev/schemas/v4/CredentialConfigFile.schema.json"
34979
35086
  },
34980
35087
  "metadata": {
34981
35088
  "type": "object",
@@ -34997,7 +35104,23 @@ var CONFIG_SCHEMAS = [
34997
35104
  "additionalProperties": false
34998
35105
  },
34999
35106
  "spec": {
35000
- "$ref": "#/$defs/IssuanceConfig"
35107
+ "allOf": [
35108
+ {
35109
+ "$ref": "#/$defs/CredentialConfigCreate"
35110
+ },
35111
+ {
35112
+ "type": "object",
35113
+ "required": [
35114
+ "id"
35115
+ ],
35116
+ "properties": {
35117
+ "id": {
35118
+ "type": "string",
35119
+ "minLength": 1
35120
+ }
35121
+ }
35122
+ }
35123
+ ]
35001
35124
  }
35002
35125
  },
35003
35126
  "required": [
@@ -35006,192 +35129,1204 @@ var CONFIG_SCHEMAS = [
35006
35129
  ],
35007
35130
  "additionalProperties": false,
35008
35131
  "$defs": {
35009
- "IssuanceConfig": {
35132
+ "CredentialConfigCreate": {
35010
35133
  "type": "object",
35011
35134
  "properties": {
35012
- "batchSize": {
35013
- "description": "Optional issuance batch size.",
35014
- "type": "integer",
35015
- "minimum": 1,
35016
- "maximum": 9007199254740991
35017
- },
35018
- "dPopRequired": {
35019
- "description": "Require DPoP proofs for issuance endpoints.",
35020
- "type": "boolean"
35021
- },
35022
- "walletAttestationRequired": {
35023
- "description": "Default wallet attestation requirement for managed authorization servers.",
35024
- "type": "boolean"
35135
+ "id": {
35136
+ "type": "string",
35137
+ "minLength": 1,
35138
+ "description": "Credential configuration identifier."
35025
35139
  },
35026
- "walletProviderTrustLists": {
35027
- "description": "Shared wallet provider trust lists for key attestations and default authorization server wallet authentication.",
35028
- "type": "array",
35029
- "items": {
35030
- "type": "object",
35031
- "properties": {
35032
- "trustListId": {
35033
- "type": "string",
35034
- "minLength": 1
35035
- },
35036
- "url": {
35037
- "description": "URL of the wallet provider trust list.",
35038
- "type": "string",
35039
- "format": "uri"
35040
- },
35041
- "verifierKey": {
35042
- "description": "Optional verifier key material used for trust list verification.",
35043
- "type": "object",
35044
- "propertyNames": {
35045
- "type": "string"
35046
- },
35047
- "additionalProperties": {}
35048
- },
35049
- "verifierKeyPem": {
35050
- "description": "Optional verifier public key in SPKI PEM form (-----BEGIN PUBLIC KEY-----).",
35051
- "type": "string",
35052
- "pattern": "^\\s*-----BEGIN PUBLIC KEY-----[A-Za-z0-9+/=\\s]+-----END PUBLIC KEY-----\\s*$"
35053
- },
35054
- "verifierX509Der": {
35055
- "description": "Optional verifier certificate in DER/base64 form.",
35056
- "type": "string"
35057
- }
35058
- },
35059
- "additionalProperties": false
35060
- }
35140
+ "description": {
35141
+ "description": "Optional description for operators and tooling.",
35142
+ "type": [
35143
+ "string",
35144
+ "null"
35145
+ ]
35061
35146
  },
35062
- "walletAttestationStatusCheckMode": {
35063
- "description": "Default status check mode for wallet attestations at managed authorization servers: strict, best_effort (default) or disabled.",
35064
- "anyOf": [
35065
- {
35147
+ "config": {
35148
+ "type": "object",
35149
+ "properties": {
35150
+ "format": {
35066
35151
  "type": "string",
35067
35152
  "enum": [
35068
- "strict",
35069
- "best_effort",
35070
- "disabled"
35071
- ]
35153
+ "mso_mdoc",
35154
+ "dc+sd-jwt"
35155
+ ],
35156
+ "description": "Credential format emitted by this configuration."
35072
35157
  },
35073
- {
35074
- "type": "null"
35075
- }
35076
- ]
35077
- },
35078
- "signingKeyId": {
35079
- "description": "Default signing key chain id for credential issuance.",
35080
- "type": "string",
35081
- "minLength": 1
35082
- },
35083
- "authorizationServers": {
35084
- "minItems": 1,
35085
- "type": "array",
35086
- "items": {
35087
- "oneOf": [
35088
- {
35158
+ "display": {
35159
+ "type": "array",
35160
+ "items": {
35089
35161
  "type": "object",
35090
35162
  "properties": {
35091
- "type": {
35163
+ "locale": {
35092
35164
  "type": "string",
35093
- "const": "external",
35094
- "description": "Use an externally managed authorization server."
35165
+ "minLength": 1,
35166
+ "description": "Language tag of this entry, for example en-US. Each locale may appear once."
35095
35167
  },
35096
- "id": {
35168
+ "name": {
35097
35169
  "type": "string",
35098
35170
  "minLength": 1,
35099
- "description": "Authorization server identifier."
35171
+ "description": "Credential name shown by wallets."
35100
35172
  },
35101
- "issuer": {
35173
+ "description": {
35174
+ "description": "Optional description of the credential for this locale.",
35175
+ "type": "string"
35176
+ },
35177
+ "background_color": {
35178
+ "description": "Optional background color for card-style rendering, as a CSS Color Level 3 numerical value: #rgb, #rrggbb, transparent, or lowercase rgb(), rgba(), hsl() or hsla() with comma-separated values. Without it, wallets use their own.",
35102
35179
  "type": "string",
35103
- "format": "uri",
35104
- "description": "Issuer URL for the external authorization server."
35180
+ "pattern": "^(?:#(?:[0-9a-fA-F]{3}){1,2}|rgb\\( *[+-]?\\d+ *, *[+-]?\\d+ *, *[+-]?\\d+ *\\)|rgb\\( *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *\\)|rgba\\( *[+-]?\\d+ *, *[+-]?\\d+ *, *[+-]?\\d+ *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *\\)|rgba\\( *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *\\)|hsl\\( *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *\\)|hsla\\( *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *\\)|transparent)$"
35105
35181
  },
35106
- "sessionBinding": {
35107
- "description": "Explicit mapping from an external access-token claim to an existing issuance session.",
35182
+ "text_color": {
35183
+ "description": "Optional text color for card-style rendering, as a CSS Color Level 3 numerical value: #rgb, #rrggbb, transparent, or lowercase rgb(), rgba(), hsl() or hsla() with comma-separated values. Without it, wallets use their own.",
35184
+ "type": "string",
35185
+ "pattern": "^(?:#(?:[0-9a-fA-F]{3}){1,2}|rgb\\( *[+-]?\\d+ *, *[+-]?\\d+ *, *[+-]?\\d+ *\\)|rgb\\( *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *\\)|rgba\\( *[+-]?\\d+ *, *[+-]?\\d+ *, *[+-]?\\d+ *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *\\)|rgba\\( *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *\\)|hsl\\( *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *\\)|hsla\\( *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+)% *, *[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+) *\\)|transparent)$"
35186
+ },
35187
+ "background_image": {
35188
+ "description": "Optional background image.",
35108
35189
  "type": "object",
35109
35190
  "properties": {
35110
- "method": {
35111
- "type": "string",
35112
- "const": "access_token_claim",
35113
- "description": "Read the correlation value from a configured access-token claim."
35114
- },
35115
- "claim": {
35191
+ "uri": {
35116
35192
  "type": "string",
35117
35193
  "minLength": 1,
35118
- "description": "Claim name that contains the issuance-session correlation value."
35194
+ "description": "Image URI."
35119
35195
  }
35120
35196
  },
35121
35197
  "required": [
35122
- "method",
35123
- "claim"
35198
+ "uri"
35124
35199
  ],
35125
35200
  "additionalProperties": false
35126
35201
  },
35127
- "label": {
35128
- "description": "Optional display label for UI selection.",
35129
- "type": "string"
35130
- },
35131
- "enabled": {
35132
- "description": "Whether this authorization server entry is enabled.",
35133
- "type": "boolean"
35134
- }
35135
- },
35136
- "required": [
35137
- "type",
35138
- "id",
35139
- "issuer"
35140
- ],
35141
- "additionalProperties": false
35142
- },
35143
- {
35144
- "type": "object",
35145
- "properties": {
35146
- "type": {
35147
- "type": "string",
35148
- "const": "oid4vp",
35149
- "description": "Use OID4VP-based authorization server chaining."
35150
- },
35151
- "id": {
35152
- "type": "string",
35153
- "minLength": 1,
35154
- "description": "Authorization server identifier."
35155
- },
35156
- "presentationConfigId": {
35157
- "type": "string",
35158
- "minLength": 1,
35159
- "description": "Presentation configuration id used during authorization."
35160
- },
35161
- "immediateWalletRedirect": {
35162
- "description": "Redirect wallets immediately after authorization response creation.",
35163
- "type": "boolean"
35164
- },
35165
- "token": {
35166
- "description": "Optional token issuance settings.",
35202
+ "logo": {
35203
+ "description": "Optional logo image.",
35167
35204
  "type": "object",
35168
35205
  "properties": {
35169
- "lifetimeSeconds": {
35170
- "description": "Access token lifetime in seconds.",
35171
- "type": "number",
35172
- "minimum": 60
35173
- },
35174
- "signingKeyId": {
35175
- "description": "Optional key chain id used to sign issued tokens.",
35206
+ "uri": {
35176
35207
  "type": "string",
35177
- "minLength": 1
35178
- },
35179
- "refreshTokenEnabled": {
35180
- "description": "Enable issuing refresh tokens.",
35181
- "type": "boolean"
35182
- },
35183
- "refreshTokenExpiresInSeconds": {
35184
- "description": "Refresh token lifetime in seconds.",
35185
- "type": "number",
35186
- "minimum": 60
35208
+ "minLength": 1,
35209
+ "description": "Image URI."
35187
35210
  }
35188
35211
  },
35212
+ "required": [
35213
+ "uri"
35214
+ ],
35189
35215
  "additionalProperties": false
35190
- },
35191
- "requireDPoP": {
35192
- "description": "Require DPoP proofs for token/credential requests.",
35193
- "type": "boolean"
35194
- },
35216
+ }
35217
+ },
35218
+ "required": [
35219
+ "locale",
35220
+ "name"
35221
+ ],
35222
+ "additionalProperties": false
35223
+ },
35224
+ "description": "Display metadata shown by wallets, one entry per locale."
35225
+ },
35226
+ "scope": {
35227
+ "description": "Optional OAuth scope associated with this credential type.",
35228
+ "type": "string"
35229
+ },
35230
+ "docType": {
35231
+ "description": "Optional mDoc document type.",
35232
+ "type": "string"
35233
+ },
35234
+ "keyAttestationsRequired": {
35235
+ "description": "Optional key attestation requirements.",
35236
+ "type": "object",
35237
+ "properties": {
35238
+ "key_storage": {
35239
+ "description": "Required key storage attestations.",
35240
+ "type": "array",
35241
+ "items": {
35242
+ "type": "string"
35243
+ }
35244
+ },
35245
+ "user_authentication": {
35246
+ "description": "Required user authentication attestations.",
35247
+ "type": "array",
35248
+ "items": {
35249
+ "type": "string"
35250
+ }
35251
+ }
35252
+ },
35253
+ "additionalProperties": false
35254
+ },
35255
+ "proofTypesSupported": {
35256
+ "description": "Supported proof types for issuance requests.",
35257
+ "type": "array",
35258
+ "items": {
35259
+ "type": "string",
35260
+ "enum": [
35261
+ "jwt",
35262
+ "attestation"
35263
+ ]
35264
+ }
35265
+ },
35266
+ "credentialReusePolicy": {
35267
+ "description": "Optional PID/EAA reuse policy published in credential metadata.",
35268
+ "type": "object",
35269
+ "properties": {
35270
+ "id": {
35271
+ "type": "string",
35272
+ "minLength": 1
35273
+ },
35274
+ "options": {
35275
+ "type": "array",
35276
+ "items": {
35277
+ "type": "object",
35278
+ "properties": {
35279
+ "details": {
35280
+ "minItems": 1,
35281
+ "type": "array",
35282
+ "items": {
35283
+ "type": "string",
35284
+ "enum": [
35285
+ "once_only",
35286
+ "limited_time",
35287
+ "limited-time",
35288
+ "rotating-batch",
35289
+ "per-relying-party"
35290
+ ]
35291
+ }
35292
+ },
35293
+ "batch_size": {
35294
+ "type": "integer",
35295
+ "minimum": 2,
35296
+ "maximum": 9007199254740991
35297
+ },
35298
+ "reissue_trigger_unused": {
35299
+ "type": "integer",
35300
+ "minimum": 0,
35301
+ "maximum": 9007199254740991
35302
+ },
35303
+ "reissue_trigger_lifetime_left": {
35304
+ "type": "integer",
35305
+ "minimum": 0,
35306
+ "maximum": 9007199254740991
35307
+ }
35308
+ },
35309
+ "required": [
35310
+ "details"
35311
+ ],
35312
+ "additionalProperties": false
35313
+ }
35314
+ }
35315
+ },
35316
+ "required": [
35317
+ "id"
35318
+ ],
35319
+ "additionalProperties": false
35320
+ }
35321
+ },
35322
+ "required": [
35323
+ "format",
35324
+ "display"
35325
+ ],
35326
+ "additionalProperties": false,
35327
+ "description": "Issuer metadata-facing credential configuration."
35328
+ },
35329
+ "fields": {
35330
+ "type": "array",
35331
+ "items": {
35332
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/__schema0"
35333
+ },
35334
+ "description": "Claim field definitions for credential issuance."
35335
+ },
35336
+ "attributeProviderId": {
35337
+ "description": "Optional attribute provider id used to resolve claim values.",
35338
+ "type": [
35339
+ "string",
35340
+ "null"
35341
+ ]
35342
+ },
35343
+ "webhookEndpointId": {
35344
+ "description": "Not used for notifications: they go to the webhook endpoint of the offer.",
35345
+ "type": [
35346
+ "string",
35347
+ "null"
35348
+ ]
35349
+ },
35350
+ "vct": {
35351
+ "description": "Optional VCT value or structured VCT metadata.",
35352
+ "anyOf": [
35353
+ {
35354
+ "type": "string"
35355
+ },
35356
+ {
35357
+ "type": "object",
35358
+ "properties": {
35359
+ "vct": {
35360
+ "description": "VCT identifier.",
35361
+ "type": "string"
35362
+ },
35363
+ "name": {
35364
+ "description": "Human-readable VCT name.",
35365
+ "type": "string"
35366
+ },
35367
+ "description": {
35368
+ "description": "Optional VCT description.",
35369
+ "type": "string"
35370
+ },
35371
+ "extends": {
35372
+ "description": "Optional base VCT reference.",
35373
+ "type": "string"
35374
+ },
35375
+ "extends#integrity": {
35376
+ "description": "Integrity hash for the extends reference.",
35377
+ "type": "string"
35378
+ },
35379
+ "schema_uri": {
35380
+ "description": "Optional schema URI for the VCT.",
35381
+ "type": "string"
35382
+ },
35383
+ "schema_uri#integrity": {
35384
+ "description": "Integrity hash for schema_uri.",
35385
+ "type": "string"
35386
+ }
35387
+ },
35388
+ "additionalProperties": false
35389
+ },
35390
+ {
35391
+ "type": "null"
35392
+ }
35393
+ ]
35394
+ },
35395
+ "keyBinding": {
35396
+ "description": "Enable key binding requirements.",
35397
+ "type": "boolean"
35398
+ },
35399
+ "keyChainId": {
35400
+ "description": "Optional key chain id used for credential signing.",
35401
+ "type": "string",
35402
+ "minLength": 1
35403
+ },
35404
+ "statusManagement": {
35405
+ "description": "Enable status management for issued credentials.",
35406
+ "type": "boolean"
35407
+ },
35408
+ "activeCredentials": {
35409
+ "description": "Optional issuer-side policy limiting simultaneously active credentials per subject. Requires statusManagement.",
35410
+ "anyOf": [
35411
+ {
35412
+ "type": "object",
35413
+ "properties": {
35414
+ "enabled": {
35415
+ "type": "boolean",
35416
+ "description": "Ensure a subject has at most one active credential of this configuration."
35417
+ },
35418
+ "tracking": {
35419
+ "description": "How the subject's active credential set is tracked. Only 'internal' (pseudonymous, issuer-side) is currently supported.",
35420
+ "type": "string",
35421
+ "enum": [
35422
+ "internal"
35423
+ ]
35424
+ }
35425
+ },
35426
+ "required": [
35427
+ "enabled"
35428
+ ],
35429
+ "additionalProperties": false,
35430
+ "description": "Issuer-side policy limiting the number of simultaneously active credentials per subject."
35431
+ },
35432
+ {
35433
+ "type": "null"
35434
+ }
35435
+ ]
35436
+ },
35437
+ "iaeActions": {
35438
+ "description": "Interactive authorization steps (a presentation or a web flow) that the wallet completes, in order, before the credential is issued.",
35439
+ "anyOf": [
35440
+ {
35441
+ "type": "array",
35442
+ "items": {
35443
+ "oneOf": [
35444
+ {
35445
+ "type": "object",
35446
+ "properties": {
35447
+ "type": {
35448
+ "type": "string",
35449
+ "const": "openid4vp_presentation",
35450
+ "description": "Trigger an OpenID4VP presentation action."
35451
+ },
35452
+ "label": {
35453
+ "description": "Optional UI label for the action.",
35454
+ "type": "string"
35455
+ },
35456
+ "presentationConfigId": {
35457
+ "type": "string",
35458
+ "minLength": 1,
35459
+ "description": "Presentation configuration id to execute."
35460
+ }
35461
+ },
35462
+ "required": [
35463
+ "type",
35464
+ "presentationConfigId"
35465
+ ],
35466
+ "additionalProperties": false
35467
+ },
35468
+ {
35469
+ "type": "object",
35470
+ "properties": {
35471
+ "type": {
35472
+ "type": "string",
35473
+ "const": "redirect_to_web",
35474
+ "description": "Trigger a redirect-to-web action."
35475
+ },
35476
+ "label": {
35477
+ "description": "Optional UI label for the action.",
35478
+ "type": "string"
35479
+ },
35480
+ "url": {
35481
+ "type": "string",
35482
+ "format": "uri",
35483
+ "description": "Destination URL for the redirect action."
35484
+ },
35485
+ "callbackUrl": {
35486
+ "description": "Optional callback URL after redirect completion.",
35487
+ "type": "string",
35488
+ "format": "uri"
35489
+ },
35490
+ "description": {
35491
+ "description": "Optional action description.",
35492
+ "type": "string"
35493
+ }
35494
+ },
35495
+ "required": [
35496
+ "type",
35497
+ "url"
35498
+ ],
35499
+ "additionalProperties": false
35500
+ }
35501
+ ],
35502
+ "description": "In-app experience action definitions."
35503
+ }
35504
+ },
35505
+ {
35506
+ "type": "null"
35507
+ }
35508
+ ]
35509
+ },
35510
+ "sdJwtTrustFormat": {
35511
+ "description": "Trust format used for SD-JWT verification metadata.",
35512
+ "anyOf": [
35513
+ {
35514
+ "type": "string",
35515
+ "enum": [
35516
+ "x5c",
35517
+ "federation"
35518
+ ]
35519
+ },
35520
+ {
35521
+ "type": "null"
35522
+ }
35523
+ ]
35524
+ },
35525
+ "lifeTime": {
35526
+ "description": "Credential lifetime in seconds.",
35527
+ "type": "integer",
35528
+ "minimum": 1,
35529
+ "maximum": 9007199254740991
35530
+ },
35531
+ "schemaMeta": {
35532
+ "description": "Optional schema metadata and trust bindings.",
35533
+ "anyOf": [
35534
+ {
35535
+ "type": "object",
35536
+ "properties": {
35537
+ "id": {
35538
+ "description": "Optional schema metadata identifier.",
35539
+ "type": "string"
35540
+ },
35541
+ "name": {
35542
+ "description": "Optional schema metadata name.",
35543
+ "type": "string"
35544
+ },
35545
+ "version": {
35546
+ "type": "string",
35547
+ "description": "Schema metadata version."
35548
+ },
35549
+ "rulebookURI": {
35550
+ "description": "Optional rulebook URI reference.",
35551
+ "type": "string"
35552
+ },
35553
+ "attestationLoS": {
35554
+ "type": "string",
35555
+ "enum": [
35556
+ "iso_18045_high",
35557
+ "iso_18045_moderate",
35558
+ "iso_18045_enhanced-basic",
35559
+ "iso_18045_basic"
35560
+ ],
35561
+ "description": "Assurance level for attestation requirements."
35562
+ },
35563
+ "bindingType": {
35564
+ "type": "string",
35565
+ "enum": [
35566
+ "claim",
35567
+ "key",
35568
+ "biometric",
35569
+ "none"
35570
+ ],
35571
+ "description": "Subject binding type."
35572
+ },
35573
+ "schemaURIs": {
35574
+ "description": "Optional schema URI entries.",
35575
+ "type": "array",
35576
+ "items": {
35577
+ "type": "object",
35578
+ "properties": {
35579
+ "credentialConfigId": {
35580
+ "description": "Optional credential configuration id this schema URI applies to.",
35581
+ "type": "string"
35582
+ },
35583
+ "format": {
35584
+ "description": "Optional credential format for this schema URI.",
35585
+ "type": "string"
35586
+ },
35587
+ "uri": {
35588
+ "description": "Schema URI reference.",
35589
+ "type": "string"
35590
+ },
35591
+ "meta": {
35592
+ "description": "Optional metadata attached to the schema URI.",
35593
+ "type": "object",
35594
+ "propertyNames": {
35595
+ "type": "string"
35596
+ },
35597
+ "additionalProperties": {}
35598
+ }
35599
+ },
35600
+ "additionalProperties": false
35601
+ }
35602
+ },
35603
+ "trustedAuthorities": {
35604
+ "description": "Optional trusted authority entries.",
35605
+ "type": "array",
35606
+ "items": {
35607
+ "type": "object",
35608
+ "properties": {
35609
+ "trustListId": {
35610
+ "description": "Optional trust list id.",
35611
+ "type": "string"
35612
+ },
35613
+ "frameworkType": {
35614
+ "description": "Trust framework type. `x509` takes a root certificate in `value` and no `verificationMethod`.",
35615
+ "type": "string",
35616
+ "enum": [
35617
+ "aki",
35618
+ "etsi_tl",
35619
+ "openid_federation",
35620
+ "x509"
35621
+ ]
35622
+ },
35623
+ "value": {
35624
+ "description": "Framework-specific authority value, for example the trust list URL for `etsi_tl` or the root certificate (base64 DER or PEM) for `x509`.",
35625
+ "type": "string"
35626
+ },
35627
+ "verificationMethod": {
35628
+ "description": "Verification method descriptor.",
35629
+ "anyOf": [
35630
+ {
35631
+ "type": "object",
35632
+ "propertyNames": {
35633
+ "type": "string"
35634
+ },
35635
+ "additionalProperties": {}
35636
+ },
35637
+ {
35638
+ "type": "string"
35639
+ }
35640
+ ]
35641
+ }
35642
+ },
35643
+ "additionalProperties": false
35644
+ }
35645
+ }
35646
+ },
35647
+ "required": [
35648
+ "version",
35649
+ "attestationLoS",
35650
+ "bindingType"
35651
+ ],
35652
+ "additionalProperties": false
35653
+ },
35654
+ {
35655
+ "type": "null"
35656
+ }
35657
+ ]
35658
+ },
35659
+ "embeddedDisclosurePolicy": {
35660
+ "description": "Optional embedded disclosure policy.",
35661
+ "anyOf": [
35662
+ {
35663
+ "oneOf": [
35664
+ {
35665
+ "type": "object",
35666
+ "properties": {
35667
+ "policy": {
35668
+ "type": "string",
35669
+ "const": "attestationBased",
35670
+ "description": "Attestation-based policy discriminator."
35671
+ },
35672
+ "values": {
35673
+ "type": "array",
35674
+ "items": {
35675
+ "type": "object",
35676
+ "properties": {
35677
+ "claims": {
35678
+ "description": "Claims constraints considered by policy evaluation.",
35679
+ "type": "array",
35680
+ "items": {}
35681
+ },
35682
+ "credentials": {
35683
+ "type": "array",
35684
+ "items": {},
35685
+ "description": "Credential constraints considered by policy evaluation."
35686
+ },
35687
+ "credential_sets": {
35688
+ "description": "Optional credential set constraints.",
35689
+ "type": "array",
35690
+ "items": {}
35691
+ }
35692
+ },
35693
+ "required": [
35694
+ "credentials"
35695
+ ],
35696
+ "additionalProperties": false
35697
+ },
35698
+ "description": "Attestation requirements used for policy enforcement."
35699
+ }
35700
+ },
35701
+ "required": [
35702
+ "policy",
35703
+ "values"
35704
+ ],
35705
+ "additionalProperties": false
35706
+ },
35707
+ {
35708
+ "type": "object",
35709
+ "properties": {
35710
+ "policy": {
35711
+ "type": "string",
35712
+ "const": "none",
35713
+ "description": "No disclosure policy enforcement."
35714
+ }
35715
+ },
35716
+ "required": [
35717
+ "policy"
35718
+ ],
35719
+ "additionalProperties": false
35720
+ },
35721
+ {
35722
+ "type": "object",
35723
+ "properties": {
35724
+ "policy": {
35725
+ "type": "string",
35726
+ "const": "allowList",
35727
+ "description": "Allow-list based policy discriminator."
35728
+ },
35729
+ "values": {
35730
+ "type": "array",
35731
+ "items": {
35732
+ "type": "string"
35733
+ },
35734
+ "description": "Allowed values for policy checks."
35735
+ }
35736
+ },
35737
+ "required": [
35738
+ "policy",
35739
+ "values"
35740
+ ],
35741
+ "additionalProperties": false
35742
+ },
35743
+ {
35744
+ "type": "object",
35745
+ "properties": {
35746
+ "policy": {
35747
+ "type": "string",
35748
+ "const": "rootOfTrust",
35749
+ "description": "Root-of-trust policy discriminator."
35750
+ },
35751
+ "values": {
35752
+ "type": "string",
35753
+ "description": "Root-of-trust identifier or reference."
35754
+ }
35755
+ },
35756
+ "required": [
35757
+ "policy",
35758
+ "values"
35759
+ ],
35760
+ "additionalProperties": false
35761
+ }
35762
+ ],
35763
+ "description": "Embedded disclosure policy configuration."
35764
+ },
35765
+ {
35766
+ "type": "null"
35767
+ }
35768
+ ]
35769
+ }
35770
+ },
35771
+ "required": [
35772
+ "id",
35773
+ "config",
35774
+ "fields"
35775
+ ],
35776
+ "additionalProperties": false,
35777
+ "description": "Payload for creating credential issuance configuration.",
35778
+ "$defs": {
35779
+ "__schema0": {
35780
+ "type": "object",
35781
+ "properties": {
35782
+ "path": {
35783
+ "type": "array",
35784
+ "items": {
35785
+ "type": [
35786
+ "string",
35787
+ "number",
35788
+ "null"
35789
+ ]
35790
+ },
35791
+ "description": "Path to this claim inside the credential payload."
35792
+ },
35793
+ "type": {
35794
+ "type": "string",
35795
+ "enum": [
35796
+ "string",
35797
+ "number",
35798
+ "integer",
35799
+ "boolean",
35800
+ "object",
35801
+ "array"
35802
+ ],
35803
+ "description": "Data type of the claim value."
35804
+ },
35805
+ "defaultValue": {
35806
+ "description": "Optional default value for this field."
35807
+ },
35808
+ "mandatory": {
35809
+ "description": "Whether the field is required at issuance time.",
35810
+ "type": "boolean"
35811
+ },
35812
+ "disclosable": {
35813
+ "description": "Whether the claim is selectively disclosable.",
35814
+ "type": "boolean"
35815
+ },
35816
+ "namespace": {
35817
+ "description": "Optional namespace for claim grouping.",
35818
+ "type": "string"
35819
+ },
35820
+ "display": {
35821
+ "description": "Localized display metadata for this field.",
35822
+ "type": "array",
35823
+ "items": {
35824
+ "type": "object",
35825
+ "properties": {
35826
+ "locale": {
35827
+ "type": "string",
35828
+ "minLength": 1,
35829
+ "description": "Locale tag for the display entry."
35830
+ },
35831
+ "name": {
35832
+ "type": "string",
35833
+ "minLength": 1,
35834
+ "description": "Human-readable field name."
35835
+ },
35836
+ "description": {
35837
+ "description": "Optional field description for this locale.",
35838
+ "type": "string"
35839
+ }
35840
+ },
35841
+ "required": [
35842
+ "locale",
35843
+ "name"
35844
+ ],
35845
+ "additionalProperties": false
35846
+ }
35847
+ },
35848
+ "constraints": {
35849
+ "description": "Optional JSON Schema 2020-12 validation keywords for the claim value. Only the JSON Schema keywords listed under Constraints in the claims documentation are accepted (validation keywords such as pattern, minLength or enum, subschemas such as items or properties, and annotations); other keys, such as format or $ref, are refused.",
35850
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35851
+ },
35852
+ "children": {
35853
+ "description": "Nested child claim definitions for object or array fields.",
35854
+ "type": "array",
35855
+ "items": {
35856
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/__schema0"
35857
+ }
35858
+ }
35859
+ },
35860
+ "required": [
35861
+ "path",
35862
+ "type"
35863
+ ],
35864
+ "additionalProperties": false
35865
+ },
35866
+ "ClaimConstraints": {
35867
+ "type": "object",
35868
+ "properties": {
35869
+ "type": {},
35870
+ "enum": {},
35871
+ "const": {},
35872
+ "multipleOf": {},
35873
+ "maximum": {},
35874
+ "exclusiveMaximum": {},
35875
+ "minimum": {},
35876
+ "exclusiveMinimum": {},
35877
+ "maxLength": {},
35878
+ "minLength": {},
35879
+ "pattern": {},
35880
+ "maxItems": {},
35881
+ "minItems": {},
35882
+ "uniqueItems": {},
35883
+ "maxContains": {},
35884
+ "minContains": {},
35885
+ "maxProperties": {},
35886
+ "minProperties": {},
35887
+ "required": {},
35888
+ "dependentRequired": {},
35889
+ "title": {},
35890
+ "description": {},
35891
+ "default": {},
35892
+ "examples": {},
35893
+ "deprecated": {},
35894
+ "readOnly": {},
35895
+ "writeOnly": {},
35896
+ "$comment": {},
35897
+ "items": {
35898
+ "anyOf": [
35899
+ {
35900
+ "type": "boolean"
35901
+ },
35902
+ {
35903
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35904
+ }
35905
+ ]
35906
+ },
35907
+ "contains": {
35908
+ "anyOf": [
35909
+ {
35910
+ "type": "boolean"
35911
+ },
35912
+ {
35913
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35914
+ }
35915
+ ]
35916
+ },
35917
+ "additionalProperties": {
35918
+ "anyOf": [
35919
+ {
35920
+ "type": "boolean"
35921
+ },
35922
+ {
35923
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35924
+ }
35925
+ ]
35926
+ },
35927
+ "propertyNames": {
35928
+ "anyOf": [
35929
+ {
35930
+ "type": "boolean"
35931
+ },
35932
+ {
35933
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35934
+ }
35935
+ ]
35936
+ },
35937
+ "not": {
35938
+ "anyOf": [
35939
+ {
35940
+ "type": "boolean"
35941
+ },
35942
+ {
35943
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35944
+ }
35945
+ ]
35946
+ },
35947
+ "if": {
35948
+ "anyOf": [
35949
+ {
35950
+ "type": "boolean"
35951
+ },
35952
+ {
35953
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35954
+ }
35955
+ ]
35956
+ },
35957
+ "then": {
35958
+ "anyOf": [
35959
+ {
35960
+ "type": "boolean"
35961
+ },
35962
+ {
35963
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35964
+ }
35965
+ ]
35966
+ },
35967
+ "else": {
35968
+ "anyOf": [
35969
+ {
35970
+ "type": "boolean"
35971
+ },
35972
+ {
35973
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35974
+ }
35975
+ ]
35976
+ },
35977
+ "unevaluatedItems": {
35978
+ "anyOf": [
35979
+ {
35980
+ "type": "boolean"
35981
+ },
35982
+ {
35983
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35984
+ }
35985
+ ]
35986
+ },
35987
+ "unevaluatedProperties": {
35988
+ "anyOf": [
35989
+ {
35990
+ "type": "boolean"
35991
+ },
35992
+ {
35993
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
35994
+ }
35995
+ ]
35996
+ },
35997
+ "prefixItems": {
35998
+ "type": "array",
35999
+ "items": {
36000
+ "anyOf": [
36001
+ {
36002
+ "type": "boolean"
36003
+ },
36004
+ {
36005
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
36006
+ }
36007
+ ]
36008
+ }
36009
+ },
36010
+ "allOf": {
36011
+ "type": "array",
36012
+ "items": {
36013
+ "anyOf": [
36014
+ {
36015
+ "type": "boolean"
36016
+ },
36017
+ {
36018
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
36019
+ }
36020
+ ]
36021
+ }
36022
+ },
36023
+ "anyOf": {
36024
+ "type": "array",
36025
+ "items": {
36026
+ "anyOf": [
36027
+ {
36028
+ "type": "boolean"
36029
+ },
36030
+ {
36031
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
36032
+ }
36033
+ ]
36034
+ }
36035
+ },
36036
+ "oneOf": {
36037
+ "type": "array",
36038
+ "items": {
36039
+ "anyOf": [
36040
+ {
36041
+ "type": "boolean"
36042
+ },
36043
+ {
36044
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
36045
+ }
36046
+ ]
36047
+ }
36048
+ },
36049
+ "properties": {
36050
+ "type": "object",
36051
+ "propertyNames": {
36052
+ "type": "string"
36053
+ },
36054
+ "additionalProperties": {
36055
+ "anyOf": [
36056
+ {
36057
+ "type": "boolean"
36058
+ },
36059
+ {
36060
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
36061
+ }
36062
+ ]
36063
+ }
36064
+ },
36065
+ "patternProperties": {
36066
+ "type": "object",
36067
+ "propertyNames": {
36068
+ "type": "string"
36069
+ },
36070
+ "additionalProperties": {
36071
+ "anyOf": [
36072
+ {
36073
+ "type": "boolean"
36074
+ },
36075
+ {
36076
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
36077
+ }
36078
+ ]
36079
+ }
36080
+ },
36081
+ "dependentSchemas": {
36082
+ "type": "object",
36083
+ "propertyNames": {
36084
+ "type": "string"
36085
+ },
36086
+ "additionalProperties": {
36087
+ "anyOf": [
36088
+ {
36089
+ "type": "boolean"
36090
+ },
36091
+ {
36092
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
36093
+ }
36094
+ ]
36095
+ }
36096
+ }
36097
+ },
36098
+ "additionalProperties": false
36099
+ }
36100
+ },
36101
+ "title": "CredentialConfigCreate"
36102
+ }
36103
+ }
36104
+ },
36105
+ {
36106
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
36107
+ "$id": "https://eudiplo.dev/schemas/v4/IssuanceConfigFile.schema.json",
36108
+ "title": "IssuanceConfigFile",
36109
+ "type": "object",
36110
+ "properties": {
36111
+ "$schema": {
36112
+ "type": "string",
36113
+ "const": "https://eudiplo.dev/schemas/v4/IssuanceConfigFile.schema.json"
36114
+ },
36115
+ "metadata": {
36116
+ "type": "object",
36117
+ "properties": {
36118
+ "generation": {
36119
+ "type": "integer",
36120
+ "minimum": 1,
36121
+ "description": "Monotonically increasing configuration generation."
36122
+ },
36123
+ "ownership": {
36124
+ "type": "string",
36125
+ "enum": [
36126
+ "unmanaged",
36127
+ "file-managed"
36128
+ ],
36129
+ "description": "Requested ownership recorded when the document is applied."
36130
+ }
36131
+ },
36132
+ "additionalProperties": false
36133
+ },
36134
+ "spec": {
36135
+ "$ref": "#/$defs/IssuanceConfig"
36136
+ }
36137
+ },
36138
+ "required": [
36139
+ "$schema",
36140
+ "spec"
36141
+ ],
36142
+ "additionalProperties": false,
36143
+ "$defs": {
36144
+ "IssuanceConfig": {
36145
+ "type": "object",
36146
+ "properties": {
36147
+ "batchSize": {
36148
+ "description": "Optional issuance batch size.",
36149
+ "type": "integer",
36150
+ "minimum": 1,
36151
+ "maximum": 9007199254740991
36152
+ },
36153
+ "dPopRequired": {
36154
+ "description": "Require DPoP proofs for issuance endpoints.",
36155
+ "type": "boolean"
36156
+ },
36157
+ "walletAttestationRequired": {
36158
+ "description": "Default wallet attestation requirement for managed authorization servers.",
36159
+ "type": "boolean"
36160
+ },
36161
+ "walletProviderTrustLists": {
36162
+ "description": "Shared wallet provider trust lists for key attestations and default authorization server wallet authentication.",
36163
+ "type": "array",
36164
+ "items": {
36165
+ "type": "object",
36166
+ "properties": {
36167
+ "trustListId": {
36168
+ "type": "string",
36169
+ "minLength": 1
36170
+ },
36171
+ "url": {
36172
+ "description": "URL of the wallet provider trust list.",
36173
+ "type": "string",
36174
+ "format": "uri"
36175
+ },
36176
+ "verifierKey": {
36177
+ "description": "Optional verifier key material used for trust list verification.",
36178
+ "type": "object",
36179
+ "propertyNames": {
36180
+ "type": "string"
36181
+ },
36182
+ "additionalProperties": {}
36183
+ },
36184
+ "verifierKeyPem": {
36185
+ "description": "Optional verifier public key in SPKI PEM form (-----BEGIN PUBLIC KEY-----).",
36186
+ "type": "string",
36187
+ "pattern": "^\\s*-----BEGIN PUBLIC KEY-----[A-Za-z0-9+/=\\s]+-----END PUBLIC KEY-----\\s*$"
36188
+ },
36189
+ "verifierX509Der": {
36190
+ "description": "Optional verifier certificate in DER/base64 form.",
36191
+ "type": "string"
36192
+ }
36193
+ },
36194
+ "additionalProperties": false
36195
+ }
36196
+ },
36197
+ "walletAttestationStatusCheckMode": {
36198
+ "description": "Default status check mode for wallet attestations at managed authorization servers: strict, best_effort (default) or disabled.",
36199
+ "anyOf": [
36200
+ {
36201
+ "type": "string",
36202
+ "enum": [
36203
+ "strict",
36204
+ "best_effort",
36205
+ "disabled"
36206
+ ]
36207
+ },
36208
+ {
36209
+ "type": "null"
36210
+ }
36211
+ ]
36212
+ },
36213
+ "signingKeyId": {
36214
+ "description": "Default signing key chain id for credential issuance.",
36215
+ "type": "string",
36216
+ "minLength": 1
36217
+ },
36218
+ "authorizationServers": {
36219
+ "minItems": 1,
36220
+ "type": "array",
36221
+ "items": {
36222
+ "oneOf": [
36223
+ {
36224
+ "type": "object",
36225
+ "properties": {
36226
+ "type": {
36227
+ "type": "string",
36228
+ "const": "external",
36229
+ "description": "Use an externally managed authorization server."
36230
+ },
36231
+ "id": {
36232
+ "type": "string",
36233
+ "minLength": 1,
36234
+ "description": "Authorization server identifier."
36235
+ },
36236
+ "issuer": {
36237
+ "type": "string",
36238
+ "format": "uri",
36239
+ "description": "Issuer URL for the external authorization server."
36240
+ },
36241
+ "sessionBinding": {
36242
+ "description": "Explicit mapping from an external access-token claim to an existing issuance session.",
36243
+ "type": "object",
36244
+ "properties": {
36245
+ "method": {
36246
+ "type": "string",
36247
+ "const": "access_token_claim",
36248
+ "description": "Read the correlation value from a configured access-token claim."
36249
+ },
36250
+ "claim": {
36251
+ "type": "string",
36252
+ "minLength": 1,
36253
+ "description": "Claim name that contains the issuance-session correlation value."
36254
+ }
36255
+ },
36256
+ "required": [
36257
+ "method",
36258
+ "claim"
36259
+ ],
36260
+ "additionalProperties": false
36261
+ },
36262
+ "label": {
36263
+ "description": "Optional display label for UI selection.",
36264
+ "type": "string"
36265
+ },
36266
+ "enabled": {
36267
+ "description": "Whether this authorization server entry is enabled.",
36268
+ "type": "boolean"
36269
+ }
36270
+ },
36271
+ "required": [
36272
+ "type",
36273
+ "id",
36274
+ "issuer"
36275
+ ],
36276
+ "additionalProperties": false
36277
+ },
36278
+ {
36279
+ "type": "object",
36280
+ "properties": {
36281
+ "type": {
36282
+ "type": "string",
36283
+ "const": "oid4vp",
36284
+ "description": "Use OID4VP-based authorization server chaining."
36285
+ },
36286
+ "id": {
36287
+ "type": "string",
36288
+ "minLength": 1,
36289
+ "description": "Authorization server identifier."
36290
+ },
36291
+ "presentationConfigId": {
36292
+ "type": "string",
36293
+ "minLength": 1,
36294
+ "description": "Presentation configuration id used during authorization."
36295
+ },
36296
+ "immediateWalletRedirect": {
36297
+ "description": "Redirect wallets immediately after authorization response creation.",
36298
+ "type": "boolean"
36299
+ },
36300
+ "token": {
36301
+ "description": "Optional token issuance settings.",
36302
+ "type": "object",
36303
+ "properties": {
36304
+ "lifetimeSeconds": {
36305
+ "description": "Access token lifetime in seconds.",
36306
+ "type": "number",
36307
+ "minimum": 60
36308
+ },
36309
+ "signingKeyId": {
36310
+ "description": "Optional key chain id used to sign issued tokens.",
36311
+ "type": "string",
36312
+ "minLength": 1
36313
+ },
36314
+ "refreshTokenEnabled": {
36315
+ "description": "Enable issuing refresh tokens.",
36316
+ "type": "boolean"
36317
+ },
36318
+ "refreshTokenExpiresInSeconds": {
36319
+ "description": "Refresh token lifetime in seconds.",
36320
+ "type": "number",
36321
+ "minimum": 60
36322
+ }
36323
+ },
36324
+ "additionalProperties": false
36325
+ },
36326
+ "requireDPoP": {
36327
+ "description": "Require DPoP proofs for token/credential requests.",
36328
+ "type": "boolean"
36329
+ },
35195
36330
  "walletAttestationRequired": {
35196
36331
  "description": "Require wallet attestation for this authorization server.",
35197
36332
  "type": "boolean"
@@ -38585,6 +39720,7 @@ var CONFIG_SCHEMAS = [
38585
39720
  ];
38586
39721
 
38587
39722
  // ../../packages/eudiplo-config-format/dist/config-validator.js
39723
+ var DISPLAY_COLOR_PATH = /^\/spec\/config\/display\/\d+\/(?:background|text)_color$/;
38588
39724
  var ajv = new import__.Ajv2020({
38589
39725
  allErrors: true,
38590
39726
  strict: false,
@@ -38604,7 +39740,7 @@ function validateConfigDocument(document) {
38604
39740
  severity: "error",
38605
39741
  code: "CONFIG_SCHEMA_VALIDATION_FAILED",
38606
39742
  path: issue.instancePath || "/",
38607
- message: issue.keyword === "additionalProperties" ? `Unknown property: ${String(issue.params.additionalProperty)}` : issue.message ?? "Invalid configuration",
39743
+ message: issue.keyword === "additionalProperties" ? `Unknown property: ${String(issue.params.additionalProperty)}` : issue.keyword === "pattern" && DISPLAY_COLOR_PATH.test(issue.instancePath) ? DISPLAY_COLOR_MESSAGE : issue.message ?? "Invalid configuration",
38608
39744
  resource: { kind: document.kind, id: resourceId(document) }
38609
39745
  });
38610
39746
  }
@@ -38616,8 +39752,21 @@ function validateConfigDocument(document) {
38616
39752
  path: document.kind === "Client" ? "/spec/clientId" : "/spec/id",
38617
39753
  message: "Resource identifier does not match metadata.id"
38618
39754
  });
39755
+ issues.push(...configRuleIssues(document));
38619
39756
  return issues;
38620
39757
  }
39758
+ function configRuleIssues(document) {
39759
+ const display = document.spec.config?.display;
39760
+ if (document.kind !== "CredentialConfig" || resolveConfigIdentity(serializeDocument(document)).version < 4 || !Array.isArray(display))
39761
+ return [];
39762
+ return findDuplicateDisplayLocales(display).map((duplicate) => ({
39763
+ severity: "error",
39764
+ code: "DISPLAY_LOCALE_DUPLICATE",
39765
+ path: `/spec/config/display/${duplicate.index}/locale`,
39766
+ message: duplicateDisplayLocaleMessage(duplicate),
39767
+ resource: { kind: document.kind, id: resourceId(document) }
39768
+ }));
39769
+ }
38621
39770
 
38622
39771
  // src/commands/config/portability/migrations.ts
38623
39772
  function upgradeDocument(input) {
@@ -39412,11 +40561,11 @@ function pluralize(label, count2) {
39412
40561
  }
39413
40562
 
39414
40563
  // src/commands/config/validate/validator.ts
39415
- var import__2 = __toESM(require__(), 1);
39416
- var import_ajv_formats = __toESM(require_dist(), 1);
39417
40564
  import { existsSync } from "node:fs";
39418
40565
  import { readdir as readdir3, readFile as readFile7 } from "node:fs/promises";
39419
40566
  import { basename as basename4, join as join7 } from "node:path";
40567
+ var import__2 = __toESM(require__(), 1);
40568
+ var import_ajv_formats = __toESM(require_dist(), 1);
39420
40569
  async function discoverTenantDirectories(rootPath) {
39421
40570
  const entries = await readdir3(rootPath, { withFileTypes: true });
39422
40571
  return entries.filter((entry) => entry.isDirectory()).map((entry) => entry.name).sort((left, right) => left.localeCompare(right));
@@ -39612,6 +40761,27 @@ async function validateResourceFile(filePath, relativeFile, schemaFile, getValid
39612
40761
  metadata: { generation: 1 },
39613
40762
  spec
39614
40763
  };
40764
+ if (kind === "CredentialConfig") {
40765
+ let issues;
40766
+ try {
40767
+ issues = validateConfigDocument(
40768
+ normalizeDocument(resolved)
40769
+ );
40770
+ } catch (error) {
40771
+ errors.push({
40772
+ file: relativeFile,
40773
+ message: error.message
40774
+ });
40775
+ return false;
40776
+ }
40777
+ for (const issue of issues)
40778
+ errors.push({
40779
+ file: relativeFile,
40780
+ path: issue.path,
40781
+ message: issue.message
40782
+ });
40783
+ if (issues.length) return false;
40784
+ }
39615
40785
  }
39616
40786
  }
39617
40787
  const validate = getValidator(schemaFile);
@@ -41361,7 +42531,7 @@ function createDeploymentCommands(context, setExitCode) {
41361
42531
  // package.json
41362
42532
  var package_default = {
41363
42533
  name: "@eudiplo/cli",
41364
- version: "9.1.0-main.8be8b4e",
42534
+ version: "9.1.0-main.8e6a2ad",
41365
42535
  description: "Deployment-aware command line tools for EUDIPLO",
41366
42536
  private: false,
41367
42537
  type: "module",