@eudiplo/cli 9.1.0-main.1a18187 → 9.1.0-main.1b295eb

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
@@ -3099,9 +3099,9 @@ var require_data = __commonJS({
3099
3099
  }
3100
3100
  });
3101
3101
 
3102
- // ../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/utils.js
3102
+ // ../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/utils.js
3103
3103
  var require_utils = __commonJS({
3104
- "../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/utils.js"(exports, module) {
3104
+ "../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/utils.js"(exports, module) {
3105
3105
  "use strict";
3106
3106
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
3107
3107
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
@@ -3333,6 +3333,37 @@ var require_utils = __commonJS({
3333
3333
  }
3334
3334
  return output.join("");
3335
3335
  }
3336
+ function removeDotSegmentsRelative(path2) {
3337
+ if (path2 === "" || path2[0] === "/") {
3338
+ return removeDotSegments(path2);
3339
+ }
3340
+ const segments = path2.split("/");
3341
+ const last = segments.length - 1;
3342
+ const output = [];
3343
+ let trailingDirectory = false;
3344
+ for (let i2 = 0; i2 <= last; i2++) {
3345
+ const segment = segments[i2];
3346
+ if (segment === "." || segment === "..") {
3347
+ if (segment === "..") {
3348
+ if (output.length !== 0 && output[output.length - 1] !== "..") {
3349
+ output.pop();
3350
+ } else {
3351
+ output.push("..");
3352
+ }
3353
+ }
3354
+ trailingDirectory = i2 === last;
3355
+ } else {
3356
+ output.push(segment);
3357
+ }
3358
+ }
3359
+ if (trailingDirectory && output[output.length - 1] !== "..") {
3360
+ output.push("");
3361
+ }
3362
+ if (output.length === 0 || output[0] === "" || output[0].includes(":")) {
3363
+ output.unshift(".");
3364
+ }
3365
+ return output.join("/");
3366
+ }
3336
3367
  var HOST_DELIMS = { "@": "%40", "/": "%2F", "?": "%3F", "#": "%23", ":": "%3A" };
3337
3368
  var HOST_DELIM_RE = /[@/?#:]/g;
3338
3369
  var HOST_DELIM_NO_COLON_RE = /[@/?#]/g;
@@ -3593,6 +3624,7 @@ var require_utils = __commonJS({
3593
3624
  encodeFragment,
3594
3625
  escapePreservingEscapes,
3595
3626
  removeDotSegments,
3627
+ removeDotSegmentsRelative,
3596
3628
  isIPv4,
3597
3629
  isUUID,
3598
3630
  normalizeIPv6,
@@ -3601,9 +3633,9 @@ var require_utils = __commonJS({
3601
3633
  }
3602
3634
  });
3603
3635
 
3604
- // ../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/schemes.js
3636
+ // ../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/schemes.js
3605
3637
  var require_schemes = __commonJS({
3606
- "../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3638
+ "../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/lib/schemes.js"(exports, module) {
3607
3639
  "use strict";
3608
3640
  var { isUUID } = require_utils();
3609
3641
  var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
@@ -3812,20 +3844,22 @@ var require_schemes = __commonJS({
3812
3844
  }
3813
3845
  });
3814
3846
 
3815
- // ../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/index.js
3847
+ // ../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/index.js
3816
3848
  var require_fast_uri = __commonJS({
3817
- "../../node_modules/.pnpm/fast-uri@3.1.8/node_modules/fast-uri/index.js"(exports, module) {
3849
+ "../../node_modules/.pnpm/fast-uri@3.1.9/node_modules/fast-uri/index.js"(exports, module) {
3818
3850
  "use strict";
3819
- var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3851
+ var { normalizeIPv6, removeDotSegments, removeDotSegmentsRelative, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
3820
3852
  var { SCHEMES, getSchemeHandler } = require_schemes();
3821
3853
  var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
3822
3854
  var MALFORMED_SCHEME_ERROR = "URI scheme is malformed.";
3823
- function decodeValidScheme(scheme) {
3824
- const decodedScheme = unescape(String(scheme));
3825
- if (!VALID_SCHEME.test(decodedScheme)) {
3855
+ var MALFORMED_HOST_ERROR = "URI host is malformed.";
3856
+ var FORBIDDEN_DOMAIN_HOST_CHARACTER = /[\0-\x20"#/:<>?@[\\\]^`{|}\x7F]/u;
3857
+ function validateScheme(scheme) {
3858
+ const stringScheme = String(scheme);
3859
+ if (!VALID_SCHEME.test(stringScheme)) {
3826
3860
  throw new TypeError(MALFORMED_SCHEME_ERROR);
3827
3861
  }
3828
- return decodedScheme;
3862
+ return stringScheme;
3829
3863
  }
3830
3864
  function normalize(uri, options) {
3831
3865
  if (typeof uri === "string") {
@@ -3862,6 +3896,9 @@ var require_fast_uri = __commonJS({
3862
3896
  const resolvedSchemeHandler = getSchemeHandler(options && options.scheme || resolved.scheme);
3863
3897
  const resolvedHost = resolved.host;
3864
3898
  const resolvedHostIsIP = resolvedHost !== void 0 && resolvedHost !== "" && (isIPv4(resolvedHost) || normalizeIPv6(resolvedHost).isIPV6);
3899
+ if (hasForbiddenDomainHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP)) {
3900
+ throw new Error(MALFORMED_HOST_ERROR);
3901
+ }
3865
3902
  canonicalizeHost(resolved, options || {}, resolvedSchemeHandler, resolvedHostIsIP);
3866
3903
  const encodedASCIIHost = resolvedHost && resolvedHost.indexOf("%") !== -1 && !new RegExp("\\P{ASCII}", "u").test(resolvedHost);
3867
3904
  if (resolved.error && !encodedASCIIHost) {
@@ -3903,14 +3940,15 @@ var require_fast_uri = __commonJS({
3903
3940
  if (relative3.path[0] === "/") {
3904
3941
  target.path = removeDotSegments(relative3.path);
3905
3942
  } else {
3906
- if ((base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0) && !base.path) {
3943
+ const baseHasAuthority = base.userinfo !== void 0 || base.host !== void 0 || base.port !== void 0;
3944
+ if (baseHasAuthority && !base.path) {
3907
3945
  target.path = "/" + relative3.path;
3908
3946
  } else if (!base.path) {
3909
3947
  target.path = relative3.path;
3910
3948
  } else {
3911
3949
  target.path = base.path.slice(0, base.path.lastIndexOf("/") + 1) + relative3.path;
3912
3950
  }
3913
- target.path = removeDotSegments(target.path);
3951
+ target.path = base.scheme === void 0 && !baseHasAuthority && target.path[0] !== "/" ? removeDotSegmentsRelative(target.path) : removeDotSegments(target.path);
3914
3952
  }
3915
3953
  target.query = relative3.query;
3916
3954
  }
@@ -3948,12 +3986,13 @@ var require_fast_uri = __commonJS({
3948
3986
  const options = Object.assign({}, opts);
3949
3987
  const uriTokens = [];
3950
3988
  if (component.scheme) {
3951
- component.scheme = decodeValidScheme(component.scheme);
3989
+ component.scheme = validateScheme(component.scheme);
3952
3990
  }
3953
3991
  const schemeHandler = getSchemeHandler(options.scheme || component.scheme);
3954
3992
  if (schemeHandler && schemeHandler.serialize) schemeHandler.serialize(component, options);
3955
3993
  const hasAuthority = component.userinfo !== void 0 || component.host !== void 0 || component.port !== void 0;
3956
- const pathNoScheme = !options.skipEscape && component.scheme === void 0 && !hasAuthority;
3994
+ const schemelessReference = (component.scheme === void 0 || options.reference === "suffix") && !hasAuthority;
3995
+ const pathNoScheme = !options.skipEscape && schemelessReference;
3957
3996
  if (component.path !== void 0) {
3958
3997
  if (!options.skipEscape) {
3959
3998
  component.path = serializePathEncoding(component.path, pathNoScheme);
@@ -3962,7 +4001,7 @@ var require_fast_uri = __commonJS({
3962
4001
  }
3963
4002
  }
3964
4003
  if (options.reference !== "suffix" && component.scheme) {
3965
- component.scheme = decodeValidScheme(component.scheme);
4004
+ component.scheme = validateScheme(component.scheme);
3966
4005
  uriTokens.push(component.scheme, ":");
3967
4006
  }
3968
4007
  const authority = recomposeAuthority(component);
@@ -3978,9 +4017,9 @@ var require_fast_uri = __commonJS({
3978
4017
  if (component.path !== void 0) {
3979
4018
  let s = component.path;
3980
4019
  if (!options.absolutePath && (!schemeHandler || !schemeHandler.absolutePath)) {
3981
- s = removeDotSegments(s);
4020
+ s = schemelessReference && s[0] !== "/" ? removeDotSegmentsRelative(s) : removeDotSegments(s);
3982
4021
  }
3983
- if (pathNoScheme) {
4022
+ if (schemelessReference) {
3984
4023
  s = serializePathEncoding(s, true);
3985
4024
  }
3986
4025
  if (authority === void 0 && s[0] === "/" && s[1] === "/") {
@@ -4027,16 +4066,34 @@ var require_fast_uri = __commonJS({
4027
4066
  return hasMalformedPercentEncoding(matches[3]) || host !== void 0 && !isIPLiteral(host) && hasMalformedPercentEncoding(host) || hasMalformedPercentEncoding(matches[6]) || hasMalformedPercentEncoding(matches[7]) || hasMalformedPercentEncoding(matches[8]);
4028
4067
  }
4029
4068
  function canonicalizeHost(parsed, options, schemeHandler, isIP) {
4069
+ if (hasForbiddenDomainHost(parsed, options, schemeHandler, isIP)) {
4070
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
4071
+ return true;
4072
+ }
4030
4073
  if (!options.unicodeSupport && (!schemeHandler || !schemeHandler.unicodeSupport) && parsed.host && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && isIP === false && nonSimpleDomain(parsed.host)) {
4074
+ let url;
4031
4075
  try {
4032
- parsed.host = new URL("http://" + parsed.host).hostname;
4076
+ url = new URL("http://" + parsed.host);
4033
4077
  } catch (e) {
4034
4078
  parsed.error = parsed.error || "Host's domain name can not be converted to ASCII: " + e;
4035
4079
  return true;
4036
4080
  }
4081
+ if (!isHostOnlyURL(url)) {
4082
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
4083
+ return true;
4084
+ }
4085
+ parsed.host = url.hostname;
4037
4086
  }
4038
4087
  return false;
4039
4088
  }
4089
+ function hasForbiddenDomainHost(parsed, options, schemeHandler, isIP) {
4090
+ return Boolean(
4091
+ parsed.host && isIP === false && !isIPLiteral(parsed.host) && (options.domainHost || schemeHandler && schemeHandler.domainHost) && FORBIDDEN_DOMAIN_HOST_CHARACTER.test(parsed.host)
4092
+ );
4093
+ }
4094
+ function isHostOnlyURL(url) {
4095
+ return url.username === "" && url.password === "" && url.port === "" && url.pathname === "/" && url.search === "" && url.hash === "" && url.hostname !== "";
4096
+ }
4040
4097
  function parseWithStatus(uri, opts) {
4041
4098
  const options = Object.assign({}, opts);
4042
4099
  const parsed = {
@@ -4091,9 +4148,8 @@ var require_fast_uri = __commonJS({
4091
4148
  parsed.query = matches[7];
4092
4149
  parsed.fragment = matches[8];
4093
4150
  if (parsed.scheme !== void 0) {
4094
- const decodedScheme = unescape(parsed.scheme);
4095
- if (VALID_SCHEME.test(decodedScheme)) {
4096
- parsed.scheme = decodedScheme.toLowerCase();
4151
+ if (VALID_SCHEME.test(parsed.scheme)) {
4152
+ parsed.scheme = parsed.scheme.toLowerCase();
4097
4153
  } else {
4098
4154
  parsed.error = parsed.error || MALFORMED_SCHEME_ERROR;
4099
4155
  malformedScheme = true;
@@ -4121,7 +4177,7 @@ var require_fast_uri = __commonJS({
4121
4177
  malformedIPLiteral = hasIPLiteralBracket && (!bracketedIPLiteral || ipv6result.error === true);
4122
4178
  parsed.host = isIP ? ipv6result.host : ipv6result.host.toLowerCase();
4123
4179
  if (malformedIPLiteral) {
4124
- parsed.error = parsed.error || "URI host is malformed.";
4180
+ parsed.error = parsed.error || MALFORMED_HOST_ERROR;
4125
4181
  malformedAuthorityOrPort = true;
4126
4182
  }
4127
4183
  } else {
@@ -4149,7 +4205,7 @@ var require_fast_uri = __commonJS({
4149
4205
  if (!isIP) {
4150
4206
  host = normalizePercentEncoding(host.toLowerCase());
4151
4207
  }
4152
- parsed.host = reescapeHostDelimiters(host, isIP);
4208
+ parsed.host = isIP || options.scheme !== "null" ? reescapeHostDelimiters(host, isIP) : host;
4153
4209
  }
4154
4210
  if (!schemeHandler || schemeHandler && !schemeHandler.skipNormalize) {
4155
4211
  if (parsed.path) {
@@ -13695,6 +13751,17 @@ var registry_default = [
13695
13751
  "/apps/backend/test/fixtures/*/info.json"
13696
13752
  ]
13697
13753
  },
13754
+ {
13755
+ kind: "file",
13756
+ file: "key-chain-defaults.json",
13757
+ resourceType: "key chain defaults",
13758
+ schemaFile: "KeyChainDefaultsConfigFile.schema.json",
13759
+ required: false,
13760
+ fileMatch: [
13761
+ "/assets/config/*/key-chain-defaults.json",
13762
+ "/apps/backend/test/fixtures/*/key-chain-defaults.json"
13763
+ ]
13764
+ },
13698
13765
  {
13699
13766
  kind: "file",
13700
13767
  file: "registrar.json",
@@ -15089,12 +15156,152 @@ function unzipSync(data, opts) {
15089
15156
  return files;
15090
15157
  }
15091
15158
 
15159
+ // ../../packages/eudiplo-config-format/dist/claim-constraints.js
15160
+ var CONSTRAINT_VALUE_KEYWORDS = [
15161
+ "type",
15162
+ "enum",
15163
+ "const",
15164
+ "multipleOf",
15165
+ "maximum",
15166
+ "exclusiveMaximum",
15167
+ "minimum",
15168
+ "exclusiveMinimum",
15169
+ "maxLength",
15170
+ "minLength",
15171
+ "pattern",
15172
+ "maxItems",
15173
+ "minItems",
15174
+ "uniqueItems",
15175
+ "maxContains",
15176
+ "minContains",
15177
+ "maxProperties",
15178
+ "minProperties",
15179
+ "required",
15180
+ "dependentRequired",
15181
+ "title",
15182
+ "description",
15183
+ "default",
15184
+ "examples",
15185
+ "deprecated",
15186
+ "readOnly",
15187
+ "writeOnly",
15188
+ "$comment"
15189
+ ];
15190
+ var CONSTRAINT_SCHEMA_KEYWORDS = [
15191
+ "items",
15192
+ "contains",
15193
+ "additionalProperties",
15194
+ "propertyNames",
15195
+ "not",
15196
+ "if",
15197
+ "then",
15198
+ "else",
15199
+ "unevaluatedItems",
15200
+ "unevaluatedProperties"
15201
+ ];
15202
+ var CONSTRAINT_SCHEMA_LIST_KEYWORDS = [
15203
+ "prefixItems",
15204
+ "allOf",
15205
+ "anyOf",
15206
+ "oneOf"
15207
+ ];
15208
+ var CONSTRAINT_SCHEMA_MAP_KEYWORDS = [
15209
+ "properties",
15210
+ "patternProperties",
15211
+ "dependentSchemas"
15212
+ ];
15213
+ var VALUE_KEYWORDS = new Set(CONSTRAINT_VALUE_KEYWORDS);
15214
+ var SCHEMA_KEYWORDS = new Set(CONSTRAINT_SCHEMA_KEYWORDS);
15215
+ var SCHEMA_LIST_KEYWORDS = new Set(CONSTRAINT_SCHEMA_LIST_KEYWORDS);
15216
+ var SCHEMA_MAP_KEYWORDS = new Set(CONSTRAINT_SCHEMA_MAP_KEYWORDS);
15217
+ function isPlainObject(value) {
15218
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15219
+ }
15220
+ function pointer(path2, segment) {
15221
+ return `${path2}/${String(segment).replaceAll("~", "~0").replaceAll("/", "~1")}`;
15222
+ }
15223
+ function sanitizeSchema(value, path2, removed) {
15224
+ if (typeof value === "boolean") {
15225
+ return value;
15226
+ }
15227
+ if (!isPlainObject(value)) {
15228
+ removed.push(path2);
15229
+ return void 0;
15230
+ }
15231
+ const entries = [];
15232
+ for (const [key, child] of Object.entries(value)) {
15233
+ const childPath = pointer(path2, key);
15234
+ if (VALUE_KEYWORDS.has(key)) {
15235
+ entries.push([key, child]);
15236
+ } else if (SCHEMA_KEYWORDS.has(key)) {
15237
+ const schema = sanitizeSchema(child, childPath, removed);
15238
+ if (schema !== void 0) {
15239
+ entries.push([key, schema]);
15240
+ }
15241
+ } else if (SCHEMA_LIST_KEYWORDS.has(key) && Array.isArray(child)) {
15242
+ entries.push([
15243
+ key,
15244
+ child.map((schema, index) => sanitizeSchema(schema, pointer(childPath, index), removed)).filter((schema) => schema !== void 0)
15245
+ ]);
15246
+ } else if (SCHEMA_MAP_KEYWORDS.has(key) && isPlainObject(child)) {
15247
+ entries.push([
15248
+ key,
15249
+ Object.fromEntries(Object.entries(child).map(([name, schema]) => [
15250
+ name,
15251
+ sanitizeSchema(schema, pointer(childPath, name), removed)
15252
+ ]).filter(([, schema]) => schema !== void 0))
15253
+ ]);
15254
+ } else {
15255
+ removed.push(childPath);
15256
+ }
15257
+ }
15258
+ return Object.fromEntries(entries);
15259
+ }
15260
+ function sanitizeClaimConstraints(constraints) {
15261
+ const removed = [];
15262
+ const schema = sanitizeSchema(constraints, "", removed);
15263
+ return {
15264
+ constraints: isPlainObject(schema) ? schema : {},
15265
+ removed
15266
+ };
15267
+ }
15268
+ function sanitizeClaimFields(fields, path2 = "") {
15269
+ const removed = [];
15270
+ const sanitized = fields.map((field, index) => {
15271
+ if (!isPlainObject(field))
15272
+ return field;
15273
+ const fieldPath = pointer(path2, index);
15274
+ let next = field;
15275
+ if (isPlainObject(field.constraints)) {
15276
+ const result = sanitizeClaimConstraints(field.constraints);
15277
+ if (result.removed.length > 0) {
15278
+ next = { ...next, constraints: result.constraints };
15279
+ removed.push(...result.removed.map((removedPath) => `${fieldPath}/constraints${removedPath}`));
15280
+ }
15281
+ }
15282
+ if (Array.isArray(field.children)) {
15283
+ const children = sanitizeClaimFields(field.children, pointer(fieldPath, "children"));
15284
+ if (children.removed.length > 0) {
15285
+ next = { ...next, children: children.fields };
15286
+ removed.push(...children.removed);
15287
+ }
15288
+ }
15289
+ return next;
15290
+ });
15291
+ return { fields: sanitized, removed };
15292
+ }
15293
+
15092
15294
  // ../../packages/eudiplo-config-format/dist/config-format.js
15093
15295
  var CONFIG_FORMATS = {
15094
- Tenant: { slug: "tenant", file: "TenantConfigFile", version: 1 },
15296
+ Tenant: { slug: "tenant", file: "TenantConfigFile", version: 4 },
15095
15297
  Client: { slug: "client", file: "ClientConfigFile", version: 2 },
15096
15298
  KmsConfig: { slug: "kms-config", file: "KmsConfigFile", version: 2 },
15097
15299
  KeyChain: { slug: "key-chain", file: "KeyChainConfigFile", version: 3 },
15300
+ KeyChainDefaults: {
15301
+ slug: "key-chain-defaults",
15302
+ file: "KeyChainDefaultsConfigFile",
15303
+ version: 1
15304
+ },
15098
15305
  RegistrarConfig: {
15099
15306
  slug: "registrar-config",
15100
15307
  file: "RegistrarConfigFile",
@@ -15108,7 +15315,7 @@ var CONFIG_FORMATS = {
15108
15315
  CredentialConfig: {
15109
15316
  slug: "credential-config",
15110
15317
  file: "CredentialConfigFile",
15111
- version: 2
15318
+ version: 3
15112
15319
  },
15113
15320
  PresentationConfig: {
15114
15321
  slug: "presentation-config",
@@ -15143,7 +15350,8 @@ var CONFIG_SINGLETON_IDS = {
15143
15350
  Tenant: "tenant",
15144
15351
  KmsConfig: "kms",
15145
15352
  RegistrarConfig: "registrar",
15146
- IssuanceConfig: "issuance"
15353
+ IssuanceConfig: "issuance",
15354
+ KeyChainDefaults: "defaults"
15147
15355
  };
15148
15356
  function resourceId(input) {
15149
15357
  const { kind } = resolveConfigIdentity(input);
@@ -15165,6 +15373,11 @@ function bareFileVersion(kind, spec) {
15165
15373
  }
15166
15374
  if (kind === "RegistrarConfig")
15167
15375
  return "relyingPartyContact" in spec ? 2 : 1;
15376
+ if (kind === "Tenant") {
15377
+ if ("defaultKeyChains" in spec)
15378
+ return 3;
15379
+ return "defaultAccessKeyChainId" in spec ? 2 : 1;
15380
+ }
15168
15381
  if (kind === "KmsConfig") {
15169
15382
  const providers = Array.isArray(spec.providers) ? spec.providers : [];
15170
15383
  return providers.some((provider) => typeof provider === "object" && provider !== null && ("algorithms" in provider || "defaultAlgorithm" in provider)) ? 2 : 1;
@@ -15245,6 +15458,54 @@ var presentationConfigV1ToV2 = {
15245
15458
  };
15246
15459
  }
15247
15460
  };
15461
+ var tenantConfigV3ToV4 = {
15462
+ id: "tenant-v4-key-chain-defaults",
15463
+ kind: "Tenant",
15464
+ from: 3,
15465
+ to: 4,
15466
+ // v4 moves the tenant's default key chains to their own resource,
15467
+ // KeyChainDefaults (key-chain-defaults.json). Only development builds of
15468
+ // 10.0 wrote defaultKeyChains, so the step drops it with a warning instead
15469
+ // of creating that document.
15470
+ migrate(spec) {
15471
+ if (!("defaultKeyChains" in spec))
15472
+ return { spec };
15473
+ const { defaultKeyChains: _, ...rest } = spec;
15474
+ return {
15475
+ spec: rest,
15476
+ issues: [
15477
+ {
15478
+ severity: "warning",
15479
+ code: "DEFAULT_KEY_CHAINS_MOVED",
15480
+ path: "/spec/defaultKeyChains",
15481
+ message: 'defaultKeyChains is no longer part of the tenant settings and was removed. Set the default key chains in key-chain-defaults.json (KeyChainDefaults), for example { "access": "<key chain ID>" }.'
15482
+ }
15483
+ ]
15484
+ };
15485
+ }
15486
+ };
15487
+ var credentialConfigV2ToV3 = {
15488
+ id: "credential-config-v3-claim-constraint-keywords",
15489
+ kind: "CredentialConfig",
15490
+ from: 2,
15491
+ to: 3,
15492
+ migrate(spec) {
15493
+ if (!Array.isArray(spec.fields))
15494
+ return { spec };
15495
+ const { fields, removed } = sanitizeClaimFields(spec.fields, "/spec/fields");
15496
+ if (removed.length === 0)
15497
+ return { spec };
15498
+ return {
15499
+ spec: { ...spec, fields },
15500
+ issues: removed.map((path2) => ({
15501
+ severity: "warning",
15502
+ code: "CLAIM_CONSTRAINT_KEYWORD_REMOVED",
15503
+ path: path2,
15504
+ message: "Removed: constraints accept only JSON Schema validation and annotation keywords."
15505
+ }))
15506
+ };
15507
+ }
15508
+ };
15248
15509
  var CONFIG_MIGRATIONS = [
15249
15510
  {
15250
15511
  id: "issuance-config-v2-offer-lifetime",
@@ -15304,6 +15565,36 @@ var CONFIG_MIGRATIONS = [
15304
15565
  // as before.
15305
15566
  migrate: (spec) => ({ spec })
15306
15567
  },
15568
+ {
15569
+ id: "tenant-v2-default-access-key-chain",
15570
+ kind: "Tenant",
15571
+ from: 1,
15572
+ to: 2,
15573
+ // v2 only adds the optional defaultAccessKeyChainId: a v1 spec is a
15574
+ // valid v2 spec, whose tenant keeps picking its access key chain by
15575
+ // rule.
15576
+ migrate: (spec) => ({ spec })
15577
+ },
15578
+ {
15579
+ id: "tenant-v3-default-key-chains",
15580
+ kind: "Tenant",
15581
+ from: 2,
15582
+ to: 3,
15583
+ // v3 keeps the tenant's default key chains in a map by usage type:
15584
+ // defaultAccessKeyChainId becomes defaultKeyChains.access.
15585
+ migrate: (spec) => {
15586
+ const { defaultAccessKeyChainId, ...rest } = spec;
15587
+ return {
15588
+ spec: typeof defaultAccessKeyChainId === "string" ? {
15589
+ ...rest,
15590
+ defaultKeyChains: {
15591
+ access: defaultAccessKeyChainId
15592
+ }
15593
+ } : rest
15594
+ };
15595
+ }
15596
+ },
15597
+ tenantConfigV3ToV4,
15307
15598
  {
15308
15599
  id: "key-chain-v2-type",
15309
15600
  kind: "KeyChain",
@@ -15332,6 +15623,7 @@ var CONFIG_MIGRATIONS = [
15332
15623
  // spec is a valid v2 spec.
15333
15624
  migrate: (spec) => ({ spec })
15334
15625
  },
15626
+ credentialConfigV2ToV3,
15335
15627
  presentationConfigV1ToV2,
15336
15628
  {
15337
15629
  id: "presentation-config-v3-typed-claim-values",
@@ -18042,6 +18334,54 @@ var CONFIG_SCHEMAS = [
18042
18334
  ],
18043
18335
  "additionalProperties": false
18044
18336
  },
18337
+ {
18338
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
18339
+ "$id": "https://eudiplo.dev/schemas/v1/KeyChainDefaultsConfigFile.schema.json",
18340
+ "title": "KeyChainDefaultsConfigFile",
18341
+ "type": "object",
18342
+ "properties": {
18343
+ "$schema": {
18344
+ "type": "string",
18345
+ "const": "https://eudiplo.dev/schemas/v1/KeyChainDefaultsConfigFile.schema.json"
18346
+ },
18347
+ "metadata": {
18348
+ "type": "object",
18349
+ "properties": {
18350
+ "generation": {
18351
+ "type": "integer",
18352
+ "minimum": 1,
18353
+ "maximum": 9007199254740991
18354
+ },
18355
+ "ownership": {
18356
+ "type": "string",
18357
+ "enum": [
18358
+ "unmanaged",
18359
+ "file-managed"
18360
+ ]
18361
+ }
18362
+ },
18363
+ "additionalProperties": false
18364
+ },
18365
+ "spec": {
18366
+ "type": "object",
18367
+ "properties": {
18368
+ "access": {
18369
+ "description": "ID of the access key chain used where no configuration names one: presentation requests of configurations without accessKeyChainId and the signed issuer metadata. Without it, EUDIPLO picks one of the tenant's access key chains by rule.",
18370
+ "type": "string",
18371
+ "minLength": 1
18372
+ }
18373
+ },
18374
+ "additionalProperties": false,
18375
+ "description": "The tenant's key chain per usage type, used where no configuration names one. A usage type without an entry uses a key chain picked by rule."
18376
+ }
18377
+ },
18378
+ "required": [
18379
+ "$schema",
18380
+ "metadata",
18381
+ "spec"
18382
+ ],
18383
+ "additionalProperties": false
18384
+ },
18045
18385
  {
18046
18386
  "$schema": "https://json-schema.org/draft/2020-12/schema",
18047
18387
  "$id": "https://eudiplo.dev/schemas/v1/KmsConfigFile.schema.json",
@@ -24583,13 +24923,13 @@ var CONFIG_SCHEMAS = [
24583
24923
  },
24584
24924
  {
24585
24925
  "$schema": "https://json-schema.org/draft/2020-12/schema",
24586
- "$id": "https://eudiplo.dev/schemas/v3/IssuanceConfigFile.schema.json",
24587
- "title": "IssuanceConfigFile",
24926
+ "$id": "https://eudiplo.dev/schemas/v2/TenantConfigFile.schema.json",
24927
+ "title": "TenantConfigFile",
24588
24928
  "type": "object",
24589
24929
  "properties": {
24590
24930
  "$schema": {
24591
24931
  "type": "string",
24592
- "const": "https://eudiplo.dev/schemas/v3/IssuanceConfigFile.schema.json"
24932
+ "const": "https://eudiplo.dev/schemas/v2/TenantConfigFile.schema.json"
24593
24933
  },
24594
24934
  "metadata": {
24595
24935
  "type": "object",
@@ -24597,33 +24937,1190 @@ var CONFIG_SCHEMAS = [
24597
24937
  "generation": {
24598
24938
  "type": "integer",
24599
24939
  "minimum": 1,
24600
- "description": "Monotonically increasing configuration generation."
24940
+ "maximum": 9007199254740991
24601
24941
  },
24602
24942
  "ownership": {
24603
24943
  "type": "string",
24604
24944
  "enum": [
24605
24945
  "unmanaged",
24606
24946
  "file-managed"
24607
- ],
24608
- "description": "Requested ownership recorded when the document is applied."
24947
+ ]
24609
24948
  }
24610
24949
  },
24611
24950
  "additionalProperties": false
24612
24951
  },
24613
24952
  "spec": {
24614
- "$ref": "#/$defs/IssuanceConfig"
24953
+ "type": "object",
24954
+ "properties": {
24955
+ "name": {
24956
+ "default": "EUDIPLO",
24957
+ "description": "Display name of the tenant.",
24958
+ "type": "string",
24959
+ "minLength": 1
24960
+ },
24961
+ "description": {
24962
+ "description": "Optional tenant description.",
24963
+ "type": "string",
24964
+ "minLength": 1
24965
+ },
24966
+ "sessionConfig": {
24967
+ "description": "Optional tenant-specific session storage configuration.",
24968
+ "type": "object",
24969
+ "properties": {
24970
+ "ttlSeconds": {
24971
+ "description": "Session time-to-live in seconds.",
24972
+ "type": "integer",
24973
+ "minimum": 60,
24974
+ "maximum": 9007199254740991
24975
+ },
24976
+ "cleanupMode": {
24977
+ "description": "Whether to fully delete or anonymize expired sessions.",
24978
+ "type": "string",
24979
+ "enum": [
24980
+ "full",
24981
+ "anonymize"
24982
+ ]
24983
+ }
24984
+ },
24985
+ "additionalProperties": false
24986
+ },
24987
+ "statusListConfig": {
24988
+ "description": "Optional tenant-specific status list defaults.",
24989
+ "type": "object",
24990
+ "properties": {
24991
+ "capacity": {
24992
+ "description": "Default status list capacity.",
24993
+ "type": "integer",
24994
+ "minimum": 100,
24995
+ "maximum": 9007199254740991
24996
+ },
24997
+ "bits": {
24998
+ "description": "Bits-per-status setting (1, 2, 4, or 8).",
24999
+ "anyOf": [
25000
+ {
25001
+ "type": "number",
25002
+ "const": 1
25003
+ },
25004
+ {
25005
+ "type": "number",
25006
+ "const": 2
25007
+ },
25008
+ {
25009
+ "type": "number",
25010
+ "const": 4
25011
+ },
25012
+ {
25013
+ "type": "number",
25014
+ "const": 8
25015
+ }
25016
+ ]
25017
+ },
25018
+ "ttl": {
25019
+ "description": "JWT TTL for status list tokens in seconds.",
25020
+ "type": "integer",
25021
+ "minimum": 60,
25022
+ "maximum": 9007199254740991
25023
+ },
25024
+ "immediateUpdate": {
25025
+ "description": "Regenerate status list JWTs immediately after status updates.",
25026
+ "type": "boolean"
25027
+ },
25028
+ "enableAggregation": {
25029
+ "description": "Include aggregation_uri in generated status list JWTs.",
25030
+ "type": "boolean"
25031
+ }
25032
+ },
25033
+ "additionalProperties": false
25034
+ },
25035
+ "defaultAccessKeyChainId": {
25036
+ "description": "ID of the access key chain used where no configuration names one: presentation requests of configurations without accessKeyChainId and the signed issuer metadata. Without it, EUDIPLO picks one of the tenant's access key chains by rule.",
25037
+ "type": "string",
25038
+ "minLength": 1
25039
+ }
25040
+ },
25041
+ "required": [
25042
+ "name"
25043
+ ],
25044
+ "additionalProperties": false,
25045
+ "description": "Payload used when importing tenant metadata from config files."
24615
25046
  }
24616
25047
  },
24617
25048
  "required": [
24618
25049
  "$schema",
25050
+ "metadata",
24619
25051
  "spec"
24620
25052
  ],
24621
- "additionalProperties": false,
24622
- "$defs": {
24623
- "IssuanceConfig": {
25053
+ "additionalProperties": false
25054
+ },
25055
+ {
25056
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
25057
+ "$id": "https://eudiplo.dev/schemas/v3/CredentialConfigFile.schema.json",
25058
+ "title": "CredentialConfigFile",
25059
+ "type": "object",
25060
+ "properties": {
25061
+ "$schema": {
25062
+ "type": "string",
25063
+ "const": "https://eudiplo.dev/schemas/v3/CredentialConfigFile.schema.json"
25064
+ },
25065
+ "metadata": {
24624
25066
  "type": "object",
24625
25067
  "properties": {
24626
- "batchSize": {
25068
+ "generation": {
25069
+ "type": "integer",
25070
+ "minimum": 1,
25071
+ "description": "Monotonically increasing configuration generation."
25072
+ },
25073
+ "ownership": {
25074
+ "type": "string",
25075
+ "enum": [
25076
+ "unmanaged",
25077
+ "file-managed"
25078
+ ],
25079
+ "description": "Requested ownership recorded when the document is applied."
25080
+ }
25081
+ },
25082
+ "additionalProperties": false
25083
+ },
25084
+ "spec": {
25085
+ "allOf": [
25086
+ {
25087
+ "$ref": "#/$defs/CredentialConfigCreate"
25088
+ },
25089
+ {
25090
+ "type": "object",
25091
+ "required": [
25092
+ "id"
25093
+ ],
25094
+ "properties": {
25095
+ "id": {
25096
+ "type": "string",
25097
+ "minLength": 1
25098
+ }
25099
+ }
25100
+ }
25101
+ ]
25102
+ }
25103
+ },
25104
+ "required": [
25105
+ "$schema",
25106
+ "spec"
25107
+ ],
25108
+ "additionalProperties": false,
25109
+ "$defs": {
25110
+ "CredentialConfigCreate": {
25111
+ "type": "object",
25112
+ "properties": {
25113
+ "id": {
25114
+ "type": "string",
25115
+ "minLength": 1,
25116
+ "description": "Credential configuration identifier."
25117
+ },
25118
+ "description": {
25119
+ "description": "Optional description for operators and tooling.",
25120
+ "type": [
25121
+ "string",
25122
+ "null"
25123
+ ]
25124
+ },
25125
+ "config": {
25126
+ "type": "object",
25127
+ "properties": {
25128
+ "format": {
25129
+ "type": "string",
25130
+ "enum": [
25131
+ "mso_mdoc",
25132
+ "dc+sd-jwt"
25133
+ ],
25134
+ "description": "Credential format emitted by this configuration."
25135
+ },
25136
+ "display": {
25137
+ "type": "array",
25138
+ "items": {
25139
+ "type": "object",
25140
+ "properties": {
25141
+ "locale": {
25142
+ "type": "string",
25143
+ "minLength": 1,
25144
+ "description": "Locale tag for the display entry."
25145
+ },
25146
+ "name": {
25147
+ "type": "string",
25148
+ "minLength": 1,
25149
+ "description": "Human-readable field name."
25150
+ },
25151
+ "description": {
25152
+ "description": "Optional field description for this locale.",
25153
+ "type": "string"
25154
+ },
25155
+ "background_color": {
25156
+ "description": "Optional background color for card-style rendering.",
25157
+ "type": "string"
25158
+ },
25159
+ "text_color": {
25160
+ "description": "Optional text color for card-style rendering.",
25161
+ "type": "string"
25162
+ },
25163
+ "background_image": {
25164
+ "description": "Optional background image.",
25165
+ "type": "object",
25166
+ "properties": {
25167
+ "uri": {
25168
+ "type": "string",
25169
+ "minLength": 1,
25170
+ "description": "Image URI."
25171
+ }
25172
+ },
25173
+ "required": [
25174
+ "uri"
25175
+ ],
25176
+ "additionalProperties": false
25177
+ },
25178
+ "logo": {
25179
+ "description": "Optional logo image.",
25180
+ "type": "object",
25181
+ "properties": {
25182
+ "uri": {
25183
+ "type": "string",
25184
+ "minLength": 1,
25185
+ "description": "Image URI."
25186
+ }
25187
+ },
25188
+ "required": [
25189
+ "uri"
25190
+ ],
25191
+ "additionalProperties": false
25192
+ }
25193
+ },
25194
+ "required": [
25195
+ "locale",
25196
+ "name"
25197
+ ],
25198
+ "additionalProperties": false
25199
+ },
25200
+ "description": "Display metadata shown by wallets."
25201
+ },
25202
+ "scope": {
25203
+ "description": "Optional OAuth scope associated with this credential type.",
25204
+ "type": "string"
25205
+ },
25206
+ "docType": {
25207
+ "description": "Optional mDoc document type.",
25208
+ "type": "string"
25209
+ },
25210
+ "keyAttestationsRequired": {
25211
+ "description": "Optional key attestation requirements.",
25212
+ "type": "object",
25213
+ "properties": {
25214
+ "key_storage": {
25215
+ "description": "Required key storage attestations.",
25216
+ "type": "array",
25217
+ "items": {
25218
+ "type": "string"
25219
+ }
25220
+ },
25221
+ "user_authentication": {
25222
+ "description": "Required user authentication attestations.",
25223
+ "type": "array",
25224
+ "items": {
25225
+ "type": "string"
25226
+ }
25227
+ }
25228
+ },
25229
+ "additionalProperties": false
25230
+ },
25231
+ "proofTypesSupported": {
25232
+ "description": "Supported proof types for issuance requests.",
25233
+ "type": "array",
25234
+ "items": {
25235
+ "type": "string",
25236
+ "enum": [
25237
+ "jwt",
25238
+ "attestation"
25239
+ ]
25240
+ }
25241
+ },
25242
+ "credentialReusePolicy": {
25243
+ "description": "Optional PID/EAA reuse policy published in credential metadata.",
25244
+ "type": "object",
25245
+ "properties": {
25246
+ "id": {
25247
+ "type": "string",
25248
+ "minLength": 1
25249
+ },
25250
+ "options": {
25251
+ "type": "array",
25252
+ "items": {
25253
+ "type": "object",
25254
+ "properties": {
25255
+ "details": {
25256
+ "minItems": 1,
25257
+ "type": "array",
25258
+ "items": {
25259
+ "type": "string",
25260
+ "enum": [
25261
+ "once_only",
25262
+ "limited_time",
25263
+ "limited-time",
25264
+ "rotating-batch",
25265
+ "per-relying-party"
25266
+ ]
25267
+ }
25268
+ },
25269
+ "batch_size": {
25270
+ "type": "integer",
25271
+ "minimum": 2,
25272
+ "maximum": 9007199254740991
25273
+ },
25274
+ "reissue_trigger_unused": {
25275
+ "type": "integer",
25276
+ "minimum": 0,
25277
+ "maximum": 9007199254740991
25278
+ },
25279
+ "reissue_trigger_lifetime_left": {
25280
+ "type": "integer",
25281
+ "minimum": 0,
25282
+ "maximum": 9007199254740991
25283
+ }
25284
+ },
25285
+ "required": [
25286
+ "details"
25287
+ ],
25288
+ "additionalProperties": false
25289
+ }
25290
+ }
25291
+ },
25292
+ "required": [
25293
+ "id"
25294
+ ],
25295
+ "additionalProperties": false
25296
+ }
25297
+ },
25298
+ "required": [
25299
+ "format",
25300
+ "display"
25301
+ ],
25302
+ "additionalProperties": false,
25303
+ "description": "Issuer metadata-facing credential configuration."
25304
+ },
25305
+ "fields": {
25306
+ "type": "array",
25307
+ "items": {
25308
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/__schema0"
25309
+ },
25310
+ "description": "Claim field definitions for credential issuance."
25311
+ },
25312
+ "attributeProviderId": {
25313
+ "description": "Optional attribute provider id used to resolve claim values.",
25314
+ "type": [
25315
+ "string",
25316
+ "null"
25317
+ ]
25318
+ },
25319
+ "webhookEndpointId": {
25320
+ "description": "Not used for notifications: they go to the webhook endpoint of the offer.",
25321
+ "type": [
25322
+ "string",
25323
+ "null"
25324
+ ]
25325
+ },
25326
+ "vct": {
25327
+ "description": "Optional VCT value or structured VCT metadata.",
25328
+ "anyOf": [
25329
+ {
25330
+ "type": "string"
25331
+ },
25332
+ {
25333
+ "type": "object",
25334
+ "properties": {
25335
+ "vct": {
25336
+ "description": "VCT identifier.",
25337
+ "type": "string"
25338
+ },
25339
+ "name": {
25340
+ "description": "Human-readable VCT name.",
25341
+ "type": "string"
25342
+ },
25343
+ "description": {
25344
+ "description": "Optional VCT description.",
25345
+ "type": "string"
25346
+ },
25347
+ "extends": {
25348
+ "description": "Optional base VCT reference.",
25349
+ "type": "string"
25350
+ },
25351
+ "extends#integrity": {
25352
+ "description": "Integrity hash for the extends reference.",
25353
+ "type": "string"
25354
+ },
25355
+ "schema_uri": {
25356
+ "description": "Optional schema URI for the VCT.",
25357
+ "type": "string"
25358
+ },
25359
+ "schema_uri#integrity": {
25360
+ "description": "Integrity hash for schema_uri.",
25361
+ "type": "string"
25362
+ }
25363
+ },
25364
+ "additionalProperties": false
25365
+ },
25366
+ {
25367
+ "type": "null"
25368
+ }
25369
+ ]
25370
+ },
25371
+ "keyBinding": {
25372
+ "description": "Enable key binding requirements.",
25373
+ "type": "boolean"
25374
+ },
25375
+ "keyChainId": {
25376
+ "description": "Optional key chain id used for credential signing.",
25377
+ "type": "string",
25378
+ "minLength": 1
25379
+ },
25380
+ "statusManagement": {
25381
+ "description": "Enable status management for issued credentials.",
25382
+ "type": "boolean"
25383
+ },
25384
+ "activeCredentials": {
25385
+ "description": "Optional issuer-side policy limiting simultaneously active credentials per subject. Requires statusManagement.",
25386
+ "anyOf": [
25387
+ {
25388
+ "type": "object",
25389
+ "properties": {
25390
+ "enabled": {
25391
+ "type": "boolean",
25392
+ "description": "Ensure a subject has at most one active credential of this configuration."
25393
+ },
25394
+ "tracking": {
25395
+ "description": "How the subject's active credential set is tracked. Only 'internal' (pseudonymous, issuer-side) is currently supported.",
25396
+ "type": "string",
25397
+ "enum": [
25398
+ "internal"
25399
+ ]
25400
+ }
25401
+ },
25402
+ "required": [
25403
+ "enabled"
25404
+ ],
25405
+ "additionalProperties": false,
25406
+ "description": "Issuer-side policy limiting the number of simultaneously active credentials per subject."
25407
+ },
25408
+ {
25409
+ "type": "null"
25410
+ }
25411
+ ]
25412
+ },
25413
+ "iaeActions": {
25414
+ "description": "Interactive authorization steps (a presentation or a web flow) that the wallet completes, in order, before the credential is issued.",
25415
+ "anyOf": [
25416
+ {
25417
+ "type": "array",
25418
+ "items": {
25419
+ "oneOf": [
25420
+ {
25421
+ "type": "object",
25422
+ "properties": {
25423
+ "type": {
25424
+ "type": "string",
25425
+ "const": "openid4vp_presentation",
25426
+ "description": "Trigger an OpenID4VP presentation action."
25427
+ },
25428
+ "label": {
25429
+ "description": "Optional UI label for the action.",
25430
+ "type": "string"
25431
+ },
25432
+ "presentationConfigId": {
25433
+ "type": "string",
25434
+ "minLength": 1,
25435
+ "description": "Presentation configuration id to execute."
25436
+ }
25437
+ },
25438
+ "required": [
25439
+ "type",
25440
+ "presentationConfigId"
25441
+ ],
25442
+ "additionalProperties": false
25443
+ },
25444
+ {
25445
+ "type": "object",
25446
+ "properties": {
25447
+ "type": {
25448
+ "type": "string",
25449
+ "const": "redirect_to_web",
25450
+ "description": "Trigger a redirect-to-web action."
25451
+ },
25452
+ "label": {
25453
+ "description": "Optional UI label for the action.",
25454
+ "type": "string"
25455
+ },
25456
+ "url": {
25457
+ "type": "string",
25458
+ "format": "uri",
25459
+ "description": "Destination URL for the redirect action."
25460
+ },
25461
+ "callbackUrl": {
25462
+ "description": "Optional callback URL after redirect completion.",
25463
+ "type": "string",
25464
+ "format": "uri"
25465
+ },
25466
+ "description": {
25467
+ "description": "Optional action description.",
25468
+ "type": "string"
25469
+ }
25470
+ },
25471
+ "required": [
25472
+ "type",
25473
+ "url"
25474
+ ],
25475
+ "additionalProperties": false
25476
+ }
25477
+ ],
25478
+ "description": "In-app experience action definitions."
25479
+ }
25480
+ },
25481
+ {
25482
+ "type": "null"
25483
+ }
25484
+ ]
25485
+ },
25486
+ "sdJwtTrustFormat": {
25487
+ "description": "Trust format used for SD-JWT verification metadata.",
25488
+ "anyOf": [
25489
+ {
25490
+ "type": "string",
25491
+ "enum": [
25492
+ "x5c",
25493
+ "federation"
25494
+ ]
25495
+ },
25496
+ {
25497
+ "type": "null"
25498
+ }
25499
+ ]
25500
+ },
25501
+ "lifeTime": {
25502
+ "description": "Credential lifetime in seconds.",
25503
+ "type": "integer",
25504
+ "minimum": 1,
25505
+ "maximum": 9007199254740991
25506
+ },
25507
+ "schemaMeta": {
25508
+ "description": "Optional schema metadata and trust bindings.",
25509
+ "anyOf": [
25510
+ {
25511
+ "type": "object",
25512
+ "properties": {
25513
+ "id": {
25514
+ "description": "Optional schema metadata identifier.",
25515
+ "type": "string"
25516
+ },
25517
+ "name": {
25518
+ "description": "Optional schema metadata name.",
25519
+ "type": "string"
25520
+ },
25521
+ "version": {
25522
+ "type": "string",
25523
+ "description": "Schema metadata version."
25524
+ },
25525
+ "rulebookURI": {
25526
+ "description": "Optional rulebook URI reference.",
25527
+ "type": "string"
25528
+ },
25529
+ "attestationLoS": {
25530
+ "type": "string",
25531
+ "enum": [
25532
+ "iso_18045_high",
25533
+ "iso_18045_moderate",
25534
+ "iso_18045_enhanced-basic",
25535
+ "iso_18045_basic"
25536
+ ],
25537
+ "description": "Assurance level for attestation requirements."
25538
+ },
25539
+ "bindingType": {
25540
+ "type": "string",
25541
+ "enum": [
25542
+ "claim",
25543
+ "key",
25544
+ "biometric",
25545
+ "none"
25546
+ ],
25547
+ "description": "Subject binding type."
25548
+ },
25549
+ "schemaURIs": {
25550
+ "description": "Optional schema URI entries.",
25551
+ "type": "array",
25552
+ "items": {
25553
+ "type": "object",
25554
+ "properties": {
25555
+ "credentialConfigId": {
25556
+ "description": "Optional credential configuration id this schema URI applies to.",
25557
+ "type": "string"
25558
+ },
25559
+ "format": {
25560
+ "description": "Optional credential format for this schema URI.",
25561
+ "type": "string"
25562
+ },
25563
+ "uri": {
25564
+ "description": "Schema URI reference.",
25565
+ "type": "string"
25566
+ },
25567
+ "meta": {
25568
+ "description": "Optional metadata attached to the schema URI.",
25569
+ "type": "object",
25570
+ "propertyNames": {
25571
+ "type": "string"
25572
+ },
25573
+ "additionalProperties": {}
25574
+ }
25575
+ },
25576
+ "additionalProperties": false
25577
+ }
25578
+ },
25579
+ "trustedAuthorities": {
25580
+ "description": "Optional trusted authority entries.",
25581
+ "type": "array",
25582
+ "items": {
25583
+ "type": "object",
25584
+ "properties": {
25585
+ "trustListId": {
25586
+ "description": "Optional trust list id.",
25587
+ "type": "string"
25588
+ },
25589
+ "frameworkType": {
25590
+ "description": "Trust framework type. `x509` takes a root certificate in `value` and no `verificationMethod`.",
25591
+ "type": "string",
25592
+ "enum": [
25593
+ "aki",
25594
+ "etsi_tl",
25595
+ "openid_federation",
25596
+ "x509"
25597
+ ]
25598
+ },
25599
+ "value": {
25600
+ "description": "Framework-specific authority value, for example the trust list URL for `etsi_tl` or the root certificate (base64 DER or PEM) for `x509`.",
25601
+ "type": "string"
25602
+ },
25603
+ "verificationMethod": {
25604
+ "description": "Verification method descriptor.",
25605
+ "anyOf": [
25606
+ {
25607
+ "type": "object",
25608
+ "propertyNames": {
25609
+ "type": "string"
25610
+ },
25611
+ "additionalProperties": {}
25612
+ },
25613
+ {
25614
+ "type": "string"
25615
+ }
25616
+ ]
25617
+ }
25618
+ },
25619
+ "additionalProperties": false
25620
+ }
25621
+ }
25622
+ },
25623
+ "required": [
25624
+ "version",
25625
+ "attestationLoS",
25626
+ "bindingType"
25627
+ ],
25628
+ "additionalProperties": false
25629
+ },
25630
+ {
25631
+ "type": "null"
25632
+ }
25633
+ ]
25634
+ },
25635
+ "embeddedDisclosurePolicy": {
25636
+ "description": "Optional embedded disclosure policy.",
25637
+ "anyOf": [
25638
+ {
25639
+ "oneOf": [
25640
+ {
25641
+ "type": "object",
25642
+ "properties": {
25643
+ "policy": {
25644
+ "type": "string",
25645
+ "const": "attestationBased",
25646
+ "description": "Attestation-based policy discriminator."
25647
+ },
25648
+ "values": {
25649
+ "type": "array",
25650
+ "items": {
25651
+ "type": "object",
25652
+ "properties": {
25653
+ "claims": {
25654
+ "description": "Claims constraints considered by policy evaluation.",
25655
+ "type": "array",
25656
+ "items": {}
25657
+ },
25658
+ "credentials": {
25659
+ "type": "array",
25660
+ "items": {},
25661
+ "description": "Credential constraints considered by policy evaluation."
25662
+ },
25663
+ "credential_sets": {
25664
+ "description": "Optional credential set constraints.",
25665
+ "type": "array",
25666
+ "items": {}
25667
+ }
25668
+ },
25669
+ "required": [
25670
+ "credentials"
25671
+ ],
25672
+ "additionalProperties": false
25673
+ },
25674
+ "description": "Attestation requirements used for policy enforcement."
25675
+ }
25676
+ },
25677
+ "required": [
25678
+ "policy",
25679
+ "values"
25680
+ ],
25681
+ "additionalProperties": false
25682
+ },
25683
+ {
25684
+ "type": "object",
25685
+ "properties": {
25686
+ "policy": {
25687
+ "type": "string",
25688
+ "const": "none",
25689
+ "description": "No disclosure policy enforcement."
25690
+ }
25691
+ },
25692
+ "required": [
25693
+ "policy"
25694
+ ],
25695
+ "additionalProperties": false
25696
+ },
25697
+ {
25698
+ "type": "object",
25699
+ "properties": {
25700
+ "policy": {
25701
+ "type": "string",
25702
+ "const": "allowList",
25703
+ "description": "Allow-list based policy discriminator."
25704
+ },
25705
+ "values": {
25706
+ "type": "array",
25707
+ "items": {
25708
+ "type": "string"
25709
+ },
25710
+ "description": "Allowed values for policy checks."
25711
+ }
25712
+ },
25713
+ "required": [
25714
+ "policy",
25715
+ "values"
25716
+ ],
25717
+ "additionalProperties": false
25718
+ },
25719
+ {
25720
+ "type": "object",
25721
+ "properties": {
25722
+ "policy": {
25723
+ "type": "string",
25724
+ "const": "rootOfTrust",
25725
+ "description": "Root-of-trust policy discriminator."
25726
+ },
25727
+ "values": {
25728
+ "type": "string",
25729
+ "description": "Root-of-trust identifier or reference."
25730
+ }
25731
+ },
25732
+ "required": [
25733
+ "policy",
25734
+ "values"
25735
+ ],
25736
+ "additionalProperties": false
25737
+ }
25738
+ ],
25739
+ "description": "Embedded disclosure policy configuration."
25740
+ },
25741
+ {
25742
+ "type": "null"
25743
+ }
25744
+ ]
25745
+ }
25746
+ },
25747
+ "required": [
25748
+ "id",
25749
+ "config",
25750
+ "fields"
25751
+ ],
25752
+ "additionalProperties": false,
25753
+ "description": "Payload for creating credential issuance configuration.",
25754
+ "$defs": {
25755
+ "__schema0": {
25756
+ "type": "object",
25757
+ "properties": {
25758
+ "path": {
25759
+ "type": "array",
25760
+ "items": {
25761
+ "type": [
25762
+ "string",
25763
+ "number",
25764
+ "null"
25765
+ ]
25766
+ },
25767
+ "description": "Path to this claim inside the credential payload."
25768
+ },
25769
+ "type": {
25770
+ "type": "string",
25771
+ "enum": [
25772
+ "string",
25773
+ "number",
25774
+ "integer",
25775
+ "boolean",
25776
+ "object",
25777
+ "array"
25778
+ ],
25779
+ "description": "Data type of the claim value."
25780
+ },
25781
+ "defaultValue": {
25782
+ "description": "Optional default value for this field."
25783
+ },
25784
+ "mandatory": {
25785
+ "description": "Whether the field is required at issuance time.",
25786
+ "type": "boolean"
25787
+ },
25788
+ "disclosable": {
25789
+ "description": "Whether the claim is selectively disclosable.",
25790
+ "type": "boolean"
25791
+ },
25792
+ "namespace": {
25793
+ "description": "Optional namespace for claim grouping.",
25794
+ "type": "string"
25795
+ },
25796
+ "display": {
25797
+ "description": "Localized display metadata for this field.",
25798
+ "type": "array",
25799
+ "items": {
25800
+ "type": "object",
25801
+ "properties": {
25802
+ "locale": {
25803
+ "type": "string",
25804
+ "minLength": 1,
25805
+ "description": "Locale tag for the display entry."
25806
+ },
25807
+ "name": {
25808
+ "type": "string",
25809
+ "minLength": 1,
25810
+ "description": "Human-readable field name."
25811
+ },
25812
+ "description": {
25813
+ "description": "Optional field description for this locale.",
25814
+ "type": "string"
25815
+ }
25816
+ },
25817
+ "required": [
25818
+ "locale",
25819
+ "name"
25820
+ ],
25821
+ "additionalProperties": false
25822
+ }
25823
+ },
25824
+ "constraints": {
25825
+ "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.",
25826
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25827
+ },
25828
+ "children": {
25829
+ "description": "Nested child claim definitions for object or array fields.",
25830
+ "type": "array",
25831
+ "items": {
25832
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/__schema0"
25833
+ }
25834
+ }
25835
+ },
25836
+ "required": [
25837
+ "path",
25838
+ "type"
25839
+ ],
25840
+ "additionalProperties": false
25841
+ },
25842
+ "ClaimConstraints": {
25843
+ "type": "object",
25844
+ "properties": {
25845
+ "type": {},
25846
+ "enum": {},
25847
+ "const": {},
25848
+ "multipleOf": {},
25849
+ "maximum": {},
25850
+ "exclusiveMaximum": {},
25851
+ "minimum": {},
25852
+ "exclusiveMinimum": {},
25853
+ "maxLength": {},
25854
+ "minLength": {},
25855
+ "pattern": {},
25856
+ "maxItems": {},
25857
+ "minItems": {},
25858
+ "uniqueItems": {},
25859
+ "maxContains": {},
25860
+ "minContains": {},
25861
+ "maxProperties": {},
25862
+ "minProperties": {},
25863
+ "required": {},
25864
+ "dependentRequired": {},
25865
+ "title": {},
25866
+ "description": {},
25867
+ "default": {},
25868
+ "examples": {},
25869
+ "deprecated": {},
25870
+ "readOnly": {},
25871
+ "writeOnly": {},
25872
+ "$comment": {},
25873
+ "items": {
25874
+ "anyOf": [
25875
+ {
25876
+ "type": "boolean"
25877
+ },
25878
+ {
25879
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25880
+ }
25881
+ ]
25882
+ },
25883
+ "contains": {
25884
+ "anyOf": [
25885
+ {
25886
+ "type": "boolean"
25887
+ },
25888
+ {
25889
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25890
+ }
25891
+ ]
25892
+ },
25893
+ "additionalProperties": {
25894
+ "anyOf": [
25895
+ {
25896
+ "type": "boolean"
25897
+ },
25898
+ {
25899
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25900
+ }
25901
+ ]
25902
+ },
25903
+ "propertyNames": {
25904
+ "anyOf": [
25905
+ {
25906
+ "type": "boolean"
25907
+ },
25908
+ {
25909
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25910
+ }
25911
+ ]
25912
+ },
25913
+ "not": {
25914
+ "anyOf": [
25915
+ {
25916
+ "type": "boolean"
25917
+ },
25918
+ {
25919
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25920
+ }
25921
+ ]
25922
+ },
25923
+ "if": {
25924
+ "anyOf": [
25925
+ {
25926
+ "type": "boolean"
25927
+ },
25928
+ {
25929
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25930
+ }
25931
+ ]
25932
+ },
25933
+ "then": {
25934
+ "anyOf": [
25935
+ {
25936
+ "type": "boolean"
25937
+ },
25938
+ {
25939
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25940
+ }
25941
+ ]
25942
+ },
25943
+ "else": {
25944
+ "anyOf": [
25945
+ {
25946
+ "type": "boolean"
25947
+ },
25948
+ {
25949
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25950
+ }
25951
+ ]
25952
+ },
25953
+ "unevaluatedItems": {
25954
+ "anyOf": [
25955
+ {
25956
+ "type": "boolean"
25957
+ },
25958
+ {
25959
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25960
+ }
25961
+ ]
25962
+ },
25963
+ "unevaluatedProperties": {
25964
+ "anyOf": [
25965
+ {
25966
+ "type": "boolean"
25967
+ },
25968
+ {
25969
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25970
+ }
25971
+ ]
25972
+ },
25973
+ "prefixItems": {
25974
+ "type": "array",
25975
+ "items": {
25976
+ "anyOf": [
25977
+ {
25978
+ "type": "boolean"
25979
+ },
25980
+ {
25981
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25982
+ }
25983
+ ]
25984
+ }
25985
+ },
25986
+ "allOf": {
25987
+ "type": "array",
25988
+ "items": {
25989
+ "anyOf": [
25990
+ {
25991
+ "type": "boolean"
25992
+ },
25993
+ {
25994
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
25995
+ }
25996
+ ]
25997
+ }
25998
+ },
25999
+ "anyOf": {
26000
+ "type": "array",
26001
+ "items": {
26002
+ "anyOf": [
26003
+ {
26004
+ "type": "boolean"
26005
+ },
26006
+ {
26007
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
26008
+ }
26009
+ ]
26010
+ }
26011
+ },
26012
+ "oneOf": {
26013
+ "type": "array",
26014
+ "items": {
26015
+ "anyOf": [
26016
+ {
26017
+ "type": "boolean"
26018
+ },
26019
+ {
26020
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
26021
+ }
26022
+ ]
26023
+ }
26024
+ },
26025
+ "properties": {
26026
+ "type": "object",
26027
+ "propertyNames": {
26028
+ "type": "string"
26029
+ },
26030
+ "additionalProperties": {
26031
+ "anyOf": [
26032
+ {
26033
+ "type": "boolean"
26034
+ },
26035
+ {
26036
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
26037
+ }
26038
+ ]
26039
+ }
26040
+ },
26041
+ "patternProperties": {
26042
+ "type": "object",
26043
+ "propertyNames": {
26044
+ "type": "string"
26045
+ },
26046
+ "additionalProperties": {
26047
+ "anyOf": [
26048
+ {
26049
+ "type": "boolean"
26050
+ },
26051
+ {
26052
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
26053
+ }
26054
+ ]
26055
+ }
26056
+ },
26057
+ "dependentSchemas": {
26058
+ "type": "object",
26059
+ "propertyNames": {
26060
+ "type": "string"
26061
+ },
26062
+ "additionalProperties": {
26063
+ "anyOf": [
26064
+ {
26065
+ "type": "boolean"
26066
+ },
26067
+ {
26068
+ "$ref": "#/$defs/CredentialConfigCreate/$defs/ClaimConstraints"
26069
+ }
26070
+ ]
26071
+ }
26072
+ }
26073
+ },
26074
+ "additionalProperties": false
26075
+ }
26076
+ },
26077
+ "title": "CredentialConfigCreate"
26078
+ }
26079
+ }
26080
+ },
26081
+ {
26082
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
26083
+ "$id": "https://eudiplo.dev/schemas/v3/IssuanceConfigFile.schema.json",
26084
+ "title": "IssuanceConfigFile",
26085
+ "type": "object",
26086
+ "properties": {
26087
+ "$schema": {
26088
+ "type": "string",
26089
+ "const": "https://eudiplo.dev/schemas/v3/IssuanceConfigFile.schema.json"
26090
+ },
26091
+ "metadata": {
26092
+ "type": "object",
26093
+ "properties": {
26094
+ "generation": {
26095
+ "type": "integer",
26096
+ "minimum": 1,
26097
+ "description": "Monotonically increasing configuration generation."
26098
+ },
26099
+ "ownership": {
26100
+ "type": "string",
26101
+ "enum": [
26102
+ "unmanaged",
26103
+ "file-managed"
26104
+ ],
26105
+ "description": "Requested ownership recorded when the document is applied."
26106
+ }
26107
+ },
26108
+ "additionalProperties": false
26109
+ },
26110
+ "spec": {
26111
+ "$ref": "#/$defs/IssuanceConfig"
26112
+ }
26113
+ },
26114
+ "required": [
26115
+ "$schema",
26116
+ "spec"
26117
+ ],
26118
+ "additionalProperties": false,
26119
+ "$defs": {
26120
+ "IssuanceConfig": {
26121
+ "type": "object",
26122
+ "properties": {
26123
+ "batchSize": {
24627
26124
  "description": "Optional issuance batch size.",
24628
26125
  "type": "integer",
24629
26126
  "minimum": 1,
@@ -26314,80 +27811,218 @@ var CONFIG_SCHEMAS = [
26314
27811
  {
26315
27812
  "type": "null"
26316
27813
  }
26317
- ]
26318
- },
26319
- "webhookEndpointId": {
26320
- "description": "Optional webhook endpoint id for presentation callbacks.",
26321
- "type": [
26322
- "string",
26323
- "null"
26324
- ]
27814
+ ]
27815
+ },
27816
+ "webhookEndpointId": {
27817
+ "description": "Optional webhook endpoint id for presentation callbacks.",
27818
+ "type": [
27819
+ "string",
27820
+ "null"
27821
+ ]
27822
+ },
27823
+ "attached": {
27824
+ "description": "Optional attachments included with presentation requests.",
27825
+ "anyOf": [
27826
+ {
27827
+ "type": "array",
27828
+ "items": {
27829
+ "type": "object",
27830
+ "properties": {
27831
+ "format": {
27832
+ "type": "string",
27833
+ "description": "Attachment format identifier."
27834
+ },
27835
+ "data": {
27836
+ "description": "Attachment payload."
27837
+ },
27838
+ "credential_ids": {
27839
+ "description": "Optional credential query ids bound to this attachment.",
27840
+ "type": "array",
27841
+ "items": {
27842
+ "type": "string"
27843
+ }
27844
+ }
27845
+ },
27846
+ "required": [
27847
+ "format",
27848
+ "data"
27849
+ ],
27850
+ "additionalProperties": false
27851
+ }
27852
+ },
27853
+ {
27854
+ "type": "null"
27855
+ }
27856
+ ]
27857
+ },
27858
+ "redirectUri": {
27859
+ "description": "Optional redirect URI after presentation completion.",
27860
+ "type": [
27861
+ "string",
27862
+ "null"
27863
+ ]
27864
+ },
27865
+ "accessKeyChainId": {
27866
+ "description": "Optional key chain id for access token/auth operations.",
27867
+ "type": [
27868
+ "string",
27869
+ "null"
27870
+ ]
27871
+ },
27872
+ "readerAuth": {
27873
+ "description": "Whether reader authentication is required for mDoc requests.",
27874
+ "type": [
27875
+ "boolean",
27876
+ "null"
27877
+ ]
27878
+ }
27879
+ },
27880
+ "required": [
27881
+ "id",
27882
+ "dcql_query"
27883
+ ],
27884
+ "additionalProperties": false,
27885
+ "title": "PresentationConfigCreateDto"
27886
+ }
27887
+ }
27888
+ },
27889
+ {
27890
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
27891
+ "$id": "https://eudiplo.dev/schemas/v3/TenantConfigFile.schema.json",
27892
+ "title": "TenantConfigFile",
27893
+ "type": "object",
27894
+ "properties": {
27895
+ "$schema": {
27896
+ "type": "string",
27897
+ "const": "https://eudiplo.dev/schemas/v3/TenantConfigFile.schema.json"
27898
+ },
27899
+ "metadata": {
27900
+ "type": "object",
27901
+ "properties": {
27902
+ "generation": {
27903
+ "type": "integer",
27904
+ "minimum": 1,
27905
+ "maximum": 9007199254740991
27906
+ },
27907
+ "ownership": {
27908
+ "type": "string",
27909
+ "enum": [
27910
+ "unmanaged",
27911
+ "file-managed"
27912
+ ]
27913
+ }
27914
+ },
27915
+ "additionalProperties": false
27916
+ },
27917
+ "spec": {
27918
+ "type": "object",
27919
+ "properties": {
27920
+ "name": {
27921
+ "default": "EUDIPLO",
27922
+ "description": "Display name of the tenant.",
27923
+ "type": "string",
27924
+ "minLength": 1
27925
+ },
27926
+ "description": {
27927
+ "description": "Optional tenant description.",
27928
+ "type": "string",
27929
+ "minLength": 1
27930
+ },
27931
+ "sessionConfig": {
27932
+ "description": "Optional tenant-specific session storage configuration.",
27933
+ "type": "object",
27934
+ "properties": {
27935
+ "ttlSeconds": {
27936
+ "description": "Session time-to-live in seconds.",
27937
+ "type": "integer",
27938
+ "minimum": 60,
27939
+ "maximum": 9007199254740991
27940
+ },
27941
+ "cleanupMode": {
27942
+ "description": "Whether to fully delete or anonymize expired sessions.",
27943
+ "type": "string",
27944
+ "enum": [
27945
+ "full",
27946
+ "anonymize"
27947
+ ]
27948
+ }
27949
+ },
27950
+ "additionalProperties": false
26325
27951
  },
26326
- "attached": {
26327
- "description": "Optional attachments included with presentation requests.",
26328
- "anyOf": [
26329
- {
26330
- "type": "array",
26331
- "items": {
26332
- "type": "object",
26333
- "properties": {
26334
- "format": {
26335
- "type": "string",
26336
- "description": "Attachment format identifier."
26337
- },
26338
- "data": {
26339
- "description": "Attachment payload."
26340
- },
26341
- "credential_ids": {
26342
- "description": "Optional credential query ids bound to this attachment.",
26343
- "type": "array",
26344
- "items": {
26345
- "type": "string"
26346
- }
26347
- }
27952
+ "statusListConfig": {
27953
+ "description": "Optional tenant-specific status list defaults.",
27954
+ "type": "object",
27955
+ "properties": {
27956
+ "capacity": {
27957
+ "description": "Default status list capacity.",
27958
+ "type": "integer",
27959
+ "minimum": 100,
27960
+ "maximum": 9007199254740991
27961
+ },
27962
+ "bits": {
27963
+ "description": "Bits-per-status setting (1, 2, 4, or 8).",
27964
+ "anyOf": [
27965
+ {
27966
+ "type": "number",
27967
+ "const": 1
26348
27968
  },
26349
- "required": [
26350
- "format",
26351
- "data"
26352
- ],
26353
- "additionalProperties": false
26354
- }
27969
+ {
27970
+ "type": "number",
27971
+ "const": 2
27972
+ },
27973
+ {
27974
+ "type": "number",
27975
+ "const": 4
27976
+ },
27977
+ {
27978
+ "type": "number",
27979
+ "const": 8
27980
+ }
27981
+ ]
26355
27982
  },
26356
- {
26357
- "type": "null"
27983
+ "ttl": {
27984
+ "description": "JWT TTL for status list tokens in seconds.",
27985
+ "type": "integer",
27986
+ "minimum": 60,
27987
+ "maximum": 9007199254740991
27988
+ },
27989
+ "immediateUpdate": {
27990
+ "description": "Regenerate status list JWTs immediately after status updates.",
27991
+ "type": "boolean"
27992
+ },
27993
+ "enableAggregation": {
27994
+ "description": "Include aggregation_uri in generated status list JWTs.",
27995
+ "type": "boolean"
26358
27996
  }
26359
- ]
26360
- },
26361
- "redirectUri": {
26362
- "description": "Optional redirect URI after presentation completion.",
26363
- "type": [
26364
- "string",
26365
- "null"
26366
- ]
26367
- },
26368
- "accessKeyChainId": {
26369
- "description": "Optional key chain id for access token/auth operations.",
26370
- "type": [
26371
- "string",
26372
- "null"
26373
- ]
27997
+ },
27998
+ "additionalProperties": false
26374
27999
  },
26375
- "readerAuth": {
26376
- "description": "Whether reader authentication is required for mDoc requests.",
26377
- "type": [
26378
- "boolean",
26379
- "null"
26380
- ]
28000
+ "defaultKeyChains": {
28001
+ "type": "object",
28002
+ "properties": {
28003
+ "access": {
28004
+ "description": "ID of the access key chain used where no configuration names one: presentation requests of configurations without accessKeyChainId and the signed issuer metadata. Without it, EUDIPLO picks one of the tenant's access key chains by rule.",
28005
+ "type": "string",
28006
+ "minLength": 1
28007
+ }
28008
+ },
28009
+ "additionalProperties": false,
28010
+ "description": "The tenant's key chain per usage type, used where no configuration names one. A usage type without an entry uses a key chain picked by rule."
26381
28011
  }
26382
28012
  },
26383
28013
  "required": [
26384
- "id",
26385
- "dcql_query"
28014
+ "name"
26386
28015
  ],
26387
28016
  "additionalProperties": false,
26388
- "title": "PresentationConfigCreateDto"
28017
+ "description": "Payload used when importing tenant metadata from config files."
26389
28018
  }
26390
- }
28019
+ },
28020
+ "required": [
28021
+ "$schema",
28022
+ "metadata",
28023
+ "spec"
28024
+ ],
28025
+ "additionalProperties": false
26391
28026
  },
26392
28027
  {
26393
28028
  "$schema": "https://json-schema.org/draft/2020-12/schema",
@@ -27127,6 +28762,132 @@ var CONFIG_SCHEMAS = [
27127
28762
  }
27128
28763
  }
27129
28764
  },
28765
+ {
28766
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
28767
+ "$id": "https://eudiplo.dev/schemas/v4/TenantConfigFile.schema.json",
28768
+ "title": "TenantConfigFile",
28769
+ "type": "object",
28770
+ "properties": {
28771
+ "$schema": {
28772
+ "type": "string",
28773
+ "const": "https://eudiplo.dev/schemas/v4/TenantConfigFile.schema.json"
28774
+ },
28775
+ "metadata": {
28776
+ "type": "object",
28777
+ "properties": {
28778
+ "generation": {
28779
+ "type": "integer",
28780
+ "minimum": 1,
28781
+ "maximum": 9007199254740991
28782
+ },
28783
+ "ownership": {
28784
+ "type": "string",
28785
+ "enum": [
28786
+ "unmanaged",
28787
+ "file-managed"
28788
+ ]
28789
+ }
28790
+ },
28791
+ "additionalProperties": false
28792
+ },
28793
+ "spec": {
28794
+ "type": "object",
28795
+ "properties": {
28796
+ "name": {
28797
+ "default": "EUDIPLO",
28798
+ "description": "Display name of the tenant.",
28799
+ "type": "string",
28800
+ "minLength": 1
28801
+ },
28802
+ "description": {
28803
+ "description": "Optional tenant description.",
28804
+ "type": "string",
28805
+ "minLength": 1
28806
+ },
28807
+ "sessionConfig": {
28808
+ "description": "Optional tenant-specific session storage configuration.",
28809
+ "type": "object",
28810
+ "properties": {
28811
+ "ttlSeconds": {
28812
+ "description": "Session time-to-live in seconds.",
28813
+ "type": "integer",
28814
+ "minimum": 60,
28815
+ "maximum": 9007199254740991
28816
+ },
28817
+ "cleanupMode": {
28818
+ "description": "Whether to fully delete or anonymize expired sessions.",
28819
+ "type": "string",
28820
+ "enum": [
28821
+ "full",
28822
+ "anonymize"
28823
+ ]
28824
+ }
28825
+ },
28826
+ "additionalProperties": false
28827
+ },
28828
+ "statusListConfig": {
28829
+ "description": "Optional tenant-specific status list defaults.",
28830
+ "type": "object",
28831
+ "properties": {
28832
+ "capacity": {
28833
+ "description": "Default status list capacity.",
28834
+ "type": "integer",
28835
+ "minimum": 100,
28836
+ "maximum": 9007199254740991
28837
+ },
28838
+ "bits": {
28839
+ "description": "Bits-per-status setting (1, 2, 4, or 8).",
28840
+ "anyOf": [
28841
+ {
28842
+ "type": "number",
28843
+ "const": 1
28844
+ },
28845
+ {
28846
+ "type": "number",
28847
+ "const": 2
28848
+ },
28849
+ {
28850
+ "type": "number",
28851
+ "const": 4
28852
+ },
28853
+ {
28854
+ "type": "number",
28855
+ "const": 8
28856
+ }
28857
+ ]
28858
+ },
28859
+ "ttl": {
28860
+ "description": "JWT TTL for status list tokens in seconds.",
28861
+ "type": "integer",
28862
+ "minimum": 60,
28863
+ "maximum": 9007199254740991
28864
+ },
28865
+ "immediateUpdate": {
28866
+ "description": "Regenerate status list JWTs immediately after status updates.",
28867
+ "type": "boolean"
28868
+ },
28869
+ "enableAggregation": {
28870
+ "description": "Include aggregation_uri in generated status list JWTs.",
28871
+ "type": "boolean"
28872
+ }
28873
+ },
28874
+ "additionalProperties": false
28875
+ }
28876
+ },
28877
+ "required": [
28878
+ "name"
28879
+ ],
28880
+ "additionalProperties": false,
28881
+ "description": "Payload used when importing tenant metadata from config files."
28882
+ }
28883
+ },
28884
+ "required": [
28885
+ "$schema",
28886
+ "metadata",
28887
+ "spec"
28888
+ ],
28889
+ "additionalProperties": false
28890
+ },
27130
28891
  {
27131
28892
  "$schema": "https://json-schema.org/draft/2020-12/schema",
27132
28893
  "$id": "https://eudiplo.dev/schemas/v5/IssuanceConfigFile.schema.json",
@@ -28065,12 +29826,7 @@ function inferredKind(path2) {
28065
29826
  function wrapBare(kind, input, path2) {
28066
29827
  if (!input || typeof input !== "object" || Array.isArray(input))
28067
29828
  throw new Error(`${path2}: configuration must be an object`);
28068
- const singleton = {
28069
- Tenant: "tenant",
28070
- KmsConfig: "kms",
28071
- RegistrarConfig: "registrar",
28072
- IssuanceConfig: "issuance"
28073
- };
29829
+ const singleton = CONFIG_SINGLETON_IDS;
28074
29830
  const spec = structuredClone(input);
28075
29831
  if (kind === "KeyChain" && spec.key && !spec.keySource) {
28076
29832
  spec.keySource = { type: "private-jwk", jwk: spec.key };
@@ -30720,7 +32476,7 @@ function createDeploymentCommands(context, setExitCode) {
30720
32476
  // package.json
30721
32477
  var package_default = {
30722
32478
  name: "@eudiplo/cli",
30723
- version: "9.1.0-main.1a18187",
32479
+ version: "9.1.0-main.1b295eb",
30724
32480
  description: "Deployment-aware command line tools for EUDIPLO",
30725
32481
  private: false,
30726
32482
  type: "module",
@@ -30781,12 +32537,12 @@ var package_default = {
30781
32537
  "jsonc-parser": "^3.3.1"
30782
32538
  },
30783
32539
  devDependencies: {
30784
- "@biomejs/biome": "2.5.15",
30785
- "@types/node": "^26.6.4",
32540
+ "@biomejs/biome": "2.6.3",
32541
+ "@types/node": "^26.6.5",
30786
32542
  esbuild: "^0.28.2",
30787
32543
  tsx: "^4.23.15",
30788
32544
  typescript: "^7.0.2",
30789
- vitest: "5.0.3"
32545
+ vitest: "5.0.5"
30790
32546
  }
30791
32547
  };
30792
32548