{
  "info": {
    "name": "EDK Customer REST walkthrough",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
    "description": "Customer REST requests: platform bootstrap, tenant confidential client, tenant services, Azure Key Vault, and a hosted OID4VCI wallet proxy federated to Keycloak. Tokens are managed by Postman OAuth2 at each authority boundary. The optional pre-authorized OID4VCI grant is an explicit protocol request because Postman has no built-in helper for that grant. Generated by generate-customer-postman.mjs; internal automation is maintained separately."
  },
  "auth": {
    "type": "noauth"
  },
  "event": [
    {
      "listen": "prerequest",
      "script": {
        "type": "text/javascript",
        "exec": [
          "// Every URL in this collection follows from two values: baseDomain and tenantSubdomain. The platform is",
          "// platform.<baseDomain>, a tenant is <tenantSubdomain>.<baseDomain>, and every API base is a path under",
          "// one of those two origins. This script recomputes all of them before every request and keeps the",
          "// results in collection scope only, so the environment holds nothing but what you typed and a",
          "// change to baseDomain or tenantSubdomain takes effect on the next request.",
          "const read = (key, fallback) => {",
          "  const value = String(pm.environment.get(key) || pm.collectionVariables.get(key) || fallback || '').trim();",
          "  return value;",
          "};",
          "const derive = (key, value) => {",
          "  if (value !== undefined && value !== null && String(value).trim()) {",
          "    pm.collectionVariables.set(key, String(value).trim().replace(/\\/+$/, ''));",
          "  }",
          "};",
          "const didWebDocumentUrl = (did, gatewayUrl) => {",
          "  const prefix = 'did:web:';",
          "  if (!String(did || '').startsWith(prefix)) return '';",
          "  const parts = String(did).slice(prefix.length).split(':').map((part) => decodeURIComponent(part));",
          "  const didAuthority = parts.shift();",
          "  if (!didAuthority) return '';",
          "  const gatewayMatch = String(gatewayUrl || '').match(/^([a-z][a-z0-9+.-]*):\\/\\/([^/?#]+)/i);",
          "  const gatewayAuthority = gatewayMatch ? gatewayMatch[2] : '';",
          "  const useGatewayAuthority = gatewayAuthority.replace(/:\\d+$/, '') === didAuthority.replace(/:\\d+$/, '') || gatewayAuthority === didAuthority;",
          "  const authority = useGatewayAuthority ? gatewayAuthority : didAuthority;",
          "  const documentPath = parts.length ? '/' + parts.map((part) => encodeURIComponent(part)).join('/') + '/did.json' : '/.well-known/did.json';",
          "  return 'https://' + authority + documentPath;",
          "};",
          "let baseDomain = read('baseDomain').replace(/^https?:\\/\\//i, '').replace(/\\/+$/, '');",
          "let publicPort = '';",
          "const basePort = baseDomain.match(/:(\\d+)$/);",
          "if (basePort) {",
          "  publicPort = ':' + basePort[1];",
          "  baseDomain = baseDomain.slice(0, -basePort[0].length);",
          "}",
          "const tenantSubdomain = read('tenantSubdomain', 'acme').toLowerCase();",
          "const tenantName = read('tenantName', 'Acme Corporation');",
          "derive('tenantSubdomain', tenantSubdomain);",
          "derive('tenantName', tenantName);",
          "if (baseDomain) {",
          "  const platformUrl = 'https://platform.' + baseDomain + publicPort;",
          "  const tenantHost = tenantSubdomain + '.' + baseDomain;",
          "  const tenantPublicAuthority = tenantHost + publicPort;",
          "  const tenantGatewayUrl = 'https://' + tenantPublicAuthority;",
          "  derive('baseDomain', baseDomain);",
          "  derive('publicPort', publicPort);",
          "  derive('platformUrl', platformUrl);",
          "  derive('adminConsoleUrl', platformUrl + '/admin-console');",
          "  derive('operatorRedirectUri', platformUrl + '/admin-console/callback');",
          "  derive('tenantHost', tenantHost);",
          "  derive('tenantPublicAuthority', tenantPublicAuthority);",
          "  derive('tenantGatewayUrl', tenantGatewayUrl);",
          "  derive('tenantIssuerOrigin', tenantGatewayUrl);",
          "  derive('tenantVerifierOrigin', tenantGatewayUrl);",
          "  derive('tenantAuthorizationServerOrigin', tenantGatewayUrl);",
          "  derive('tenantPlatformConfigApiBaseUrl', tenantGatewayUrl + '/api/platform/config/v1');",
          "  derive('tenantDidApiBaseUrl', tenantGatewayUrl + '/api/did/v1');",
          "  derive('tenantCredentialDesignApiBaseUrl', tenantGatewayUrl + '/api/credential-design/v1');",
          "  derive('tenantStatusListApiBaseUrl', tenantGatewayUrl + '/api/statuslist/v1');",
          "  derive('tenantIssuerApiBaseUrl', tenantGatewayUrl + '/api/oid4vci/v1');",
          "  derive('tenantDcqlApiBaseUrl', tenantGatewayUrl + '/api/dcql/v1');",
          "  derive('tenantVerifierBackendBaseUrl', tenantGatewayUrl + '/oid4vp/backend');",
          "  derive('tenantTrustDomainApiBaseUrl', tenantGatewayUrl + '/api/trust-domain/v1');",
          "  derive('tenantKmsApiBaseUrl', tenantGatewayUrl + '/api/kms/v1');",
          "  const did = 'did:web:' + tenantPublicAuthority.replace(/:/g, '%3A');",
          "  derive('did', did);",
          "  derive('didEncoded', encodeURIComponent(did));",
          "  derive('didJsonUrl', didWebDocumentUrl(did, tenantGatewayUrl));",
          "}"
        ]
      }
    }
  ],
  "item": [
    {
      "name": "00 Start here",
      "description": "Import the environment and set baseDomain, tenantSubdomain and tenantName. Send discovery first. Get New Access Token on folder 01 using the existing platform operator account, then Use Token. The deployment must provision developer-postman with the exact Postman browser callback. Run folders interactively; optional scenarios are separate choices, not a Run All checklist.\n\nDocumentation: https://docs.sphereon.com/edk/deployment/onboarding-walkthrough#postman-oauth-and-the-first-tenant-client",
      "auth": {
        "type": "noauth"
      },
      "item": [
        {
          "name": "01 Discover platform OAuth endpoints",
          "request": {
            "method": "GET",
            "url": "{{platformUrl}}/.well-known/openid-configuration",
            "auth": {
              "type": "noauth"
            },
            "header": []
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Request succeeded', () => pm.response.to.have.status(200));",
                  "const parseUrl = value => require('url').parse(value, true);",
                  "const httpsOrigin = value => {",
                  "  const parsed = parseUrl(value);",
                  "  if (parsed.protocol !== 'https:' || !parsed.host || parsed.auth) throw new Error('Expected an HTTPS URL without embedded credentials');",
                  "  return parsed.protocol + '//' + parsed.host.toLowerCase();",
                  "};",
                  "const metadata = pm.response.json();",
                  "for (const key of ['authorization_endpoint', 'token_endpoint']) {",
                  "  pm.expect(httpsOrigin(metadata[key])).to.eql(httpsOrigin(pm.variables.get('platformUrl')));",
                  "}",
                  "pm.collectionVariables.set('platformAuthorizationEndpoint', metadata.authorization_endpoint);",
                  "pm.collectionVariables.set('platformTokenEndpoint', metadata.token_endpoint);"
                ]
              }
            }
          ]
        }
      ]
    },
    {
      "name": "01 Platform - create tenant",
      "description": "Platform operator only. Register the tenant, then repeat status until COMPLETED. Open tenantOwnerActivationLink in your browser, or use the invitation email. Complete owner activation before folder 02.\n\nDocumentation: https://docs.sphereon.com/edk/deployment/onboarding-walkthrough#postman-oauth-and-the-first-tenant-client",
      "auth": {
        "type": "oauth2",
        "oauth2": [
          {
            "key": "tokenName",
            "value": "Platform operator",
            "type": "string"
          },
          {
            "key": "grant_type",
            "value": "authorization_code_with_pkce",
            "type": "string"
          },
          {
            "key": "authUrl",
            "value": "{{platformAuthorizationEndpoint}}",
            "type": "string"
          },
          {
            "key": "accessTokenUrl",
            "value": "{{platformTokenEndpoint}}",
            "type": "string"
          },
          {
            "key": "clientId",
            "value": "developer-postman",
            "type": "string"
          },
          {
            "key": "redirect_uri",
            "value": "https://oauth.pstmn.io/v1/browser-callback",
            "type": "string"
          },
          {
            "key": "scope",
            "value": "openid profile email",
            "type": "string"
          },
          {
            "key": "challengeAlgorithm",
            "value": "S256",
            "type": "string"
          },
          {
            "key": "state",
            "value": "{{$guid}}",
            "type": "string"
          },
          {
            "key": "client_authentication",
            "value": "none",
            "type": "string"
          },
          {
            "key": "addTokenTo",
            "value": "header",
            "type": "string"
          },
          {
            "key": "headerPrefix",
            "value": "Bearer",
            "type": "string"
          }
        ]
      },
      "item": [
        {
          "name": "01 Register tenant",
          "request": {
            "method": "POST",
            "url": "{{platformUrl}}/api/platform/admin/v1/tenants",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"tenant\": {\n    \"tenantType\": \"organization\",\n    \"name\": \"{{tenantName}}\",\n    \"description\": \"{{tenantName}} issuing and verification tenant\",\n    \"slug\": \"{{tenantSubdomain}}\",\n    \"initialPlatformSubdomain\": true\n  },\n  \"contacts\": {\n    \"technical\": {\n      \"email\": \"admin@{{tenantSubdomain}}.example\",\n      \"displayName\": \"{{tenantName}} Technical Contact\"\n    },\n    \"administrativeSameAsTechnical\": true,\n    \"ownerAdmin\": {\n      \"source\": \"technical\"\n    }\n  },\n  \"login\": {\n    \"enabled\": true,\n    \"defaultAuthorizationServerRequired\": true\n  },\n  \"provisioning\": {\n    \"issuer\": true,\n    \"verifier\": true,\n    \"keysAndDids\": true,\n    \"sampleData\": true\n  }\n}"
            },
            "description": "Registers an organization tenant with natural-person contacts, owner/admin login, mandatory default authorization server, and default issuer/verifier/key/DID/sample-data provisioning. The platform selects its configured email route; when none is effective it returns a one-time manual activation link."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Request succeeded', () => pm.response.to.have.status(201));",
                  "const result = pm.response.json();",
                  "pm.expect(result.tenant.id).to.be.a('string').and.not.empty;",
                  "pm.collectionVariables.set('tenantId', result.tenant.id);",
                  "pm.collectionVariables.set('tenantRegistrationCorrelationId', result.correlationId);",
                  "if (result.delivery?.manualActivationLink) {",
                  "  pm.collectionVariables.set('tenantOwnerActivationLink', result.delivery.manualActivationLink);",
                  "}",
                  "// Open the invitation in a browser to choose the owner's password or passkey.",
                  "// Email delivery is equally valid; no password or activation token is exported."
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "POST",
                "url": "https://platform.example.com/api/platform/admin/v1/tenants",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"tenant\": {\n    \"tenantType\": \"organization\",\n    \"name\": \"Acme Corporation\",\n    \"description\": \"Acme Corporation issuing and verification tenant\",\n    \"slug\": \"acme\",\n    \"initialPlatformSubdomain\": true\n  },\n  \"contacts\": {\n    \"technical\": {\n      \"email\": \"admin@acme.example\",\n      \"displayName\": \"Acme Corporation Technical Contact\"\n    },\n    \"administrativeSameAsTechnical\": true,\n    \"ownerAdmin\": {\n      \"source\": \"technical\"\n    }\n  },\n  \"login\": {\n    \"enabled\": true,\n    \"defaultAuthorizationServerRequired\": true\n  },\n  \"provisioning\": {\n    \"issuer\": true,\n    \"verifier\": true,\n    \"keysAndDids\": true,\n    \"sampleData\": true\n  }\n}"
                }
              },
              "status": "Created",
              "code": 201,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"tenant\": {\n    \"id\": \"00000000-0000-4000-8000-000000000000\",\n    \"tenantType\": \"organization\",\n    \"name\": \"Acme Corporation\",\n    \"description\": \"Acme Corporation issuing and verification tenant\",\n    \"slug\": \"acme\",\n    \"parentTenantId\": null,\n    \"status\": \"ACTIVE\",\n    \"system\": false,\n    \"ownerPartyId\": null,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"createdById\": \"00000000-0000-4000-8000-000000000000\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedById\": \"00000000-0000-4000-8000-000000000000\",\n    \"deletedAt\": null,\n    \"deletedById\": null\n  },\n  \"tenantUrl\": \"https://acme.example.com\",\n  \"serviceUrls\": {\n    \"authorizationServerUrl\": \"https://acme.example.com/as/acme\",\n    \"issuerUrl\": \"https://acme.example.com/as/acme\",\n    \"oid4vciIssuerUrl\": \"https://acme.example.com/oid4vci/acme\",\n    \"oid4vpVerifierUrl\": \"https://acme.example.com/oid4vp/acme\"\n  },\n  \"correlationId\": \"00000000-0000-4000-8000-000000000000\",\n  \"created\": {\n    \"ownerPartyId\": \"00000000-0000-4000-8000-000000000000\",\n    \"technicalContactPartyId\": \"00000000-0000-4000-8000-000000000000\",\n    \"administrativeContactPartyId\": \"00000000-0000-4000-8000-000000000000\",\n    \"ownerAdminPartyId\": \"00000000-0000-4000-8000-000000000000\",\n    \"ownerAccountId\": \"00000000-0000-4000-8000-000000000000\",\n    \"ownerIdentityId\": \"00000000-0000-4000-8000-000000000000\",\n    \"relationshipIds\": [\n      \"00000000-0000-4000-8000-000000000000\",\n      \"00000000-0000-4000-8000-000000000000\",\n      \"00000000-0000-4000-8000-000000000000\",\n      \"00000000-0000-4000-8000-000000000000\"\n    ]\n  },\n  \"delivery\": {\n    \"status\": \"MANUAL_READY\",\n    \"invitationId\": \"00000000-0000-4000-8000-000000000000\",\n    \"expiresAt\": \"2027-01-01T00:00:00Z\",\n    \"manualActivationLink\": \"https://acme.example.com/as/acme/account-action#<activation-token>\",\n    \"reason\": null\n  }\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        },
        {
          "name": "02 Get tenant onboarding status",
          "request": {
            "method": "GET",
            "url": "{{platformUrl}}/api/platform/admin/v1/tenant-onboarding/{{tenantRegistrationCorrelationId}}",
            "description": "Reads the platform tenant-onboarding status row produced by registration and verifies the platform completed every default activation step before customer-facing setup continues.",
            "header": []
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Request succeeded', () => pm.response.to.have.status(200));",
                  "const result = pm.response.json();",
                  "pm.expect(result.status).not.to.eql('FAILED');",
                  "// Repeat until COMPLETED before continuing to the tenant owner folder."
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "GET",
                "url": "https://platform.example.com/api/platform/admin/v1/tenant-onboarding/00000000-0000-4000-8000-000000000000",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ]
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"correlationId\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"status\": \"COMPLETED\",\n  \"startedAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\",\n  \"completedAt\": \"2026-01-01T00:00:00Z\",\n  \"lastError\": null,\n  \"steps\": [\n    {\n      \"step\": {\n        \"id\": \"as-endpoint-bound\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"as-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"contacts-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"default-kms-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"default-settings-applied\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"deployment-kms-offers-applied\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"did-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"did-state-migrated\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"internal-client-credential-catalog-v2-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"isolation-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"issuer-endpoint-bound\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"issuer-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"opaque-internal-client-credentials-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"organization-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"owner-invitation-minted\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"owner-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"relationships-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"routing-inserted\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"sample-data-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"software-catalog-reconciled\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"software-resource-authorization-server-authority-migrated\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"software-resource-oid4vci-issuer-authorization-bound\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"tenant-schemas-ensured\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"tenant-workload-clients-migrated\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"verifier-endpoint-bound\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"verifier-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    }\n  ]\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        }
      ]
    },
    {
      "name": "02 Tenant owner - register application",
      "description": "Send discovery before Get New Access Token. Sign in as the activated tenant owner. Set tenantServiceClientId and private tenantServiceClientSecret, then register the confidential client on the default hosted tenant AS. This is the one-time bootstrap; ordinary REST work uses folder 03.\n\nDocumentation: https://docs.sphereon.com/edk/deployment/onboarding-walkthrough#postman-oauth-and-the-first-tenant-client",
      "auth": {
        "type": "oauth2",
        "oauth2": [
          {
            "key": "tokenName",
            "value": "Tenant owner - client bootstrap",
            "type": "string"
          },
          {
            "key": "grant_type",
            "value": "authorization_code_with_pkce",
            "type": "string"
          },
          {
            "key": "authUrl",
            "value": "{{tenantAuthorizationEndpoint}}",
            "type": "string"
          },
          {
            "key": "accessTokenUrl",
            "value": "{{tenantAccessTokenEndpoint}}",
            "type": "string"
          },
          {
            "key": "clientId",
            "value": "developer-postman",
            "type": "string"
          },
          {
            "key": "redirect_uri",
            "value": "https://oauth.pstmn.io/v1/browser-callback",
            "type": "string"
          },
          {
            "key": "scope",
            "value": "openid profile email",
            "type": "string"
          },
          {
            "key": "challengeAlgorithm",
            "value": "S256",
            "type": "string"
          },
          {
            "key": "state",
            "value": "{{$guid}}",
            "type": "string"
          },
          {
            "key": "client_authentication",
            "value": "none",
            "type": "string"
          },
          {
            "key": "addTokenTo",
            "value": "header",
            "type": "string"
          },
          {
            "key": "headerPrefix",
            "value": "Bearer",
            "type": "string"
          }
        ]
      },
      "item": [
        {
          "name": "00 Discover tenant OAuth endpoints",
          "request": {
            "method": "GET",
            "url": "{{tenantGatewayUrl}}/.well-known/openid-configuration",
            "auth": {
              "type": "noauth"
            },
            "header": []
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Request succeeded', () => pm.response.to.have.status(200));",
                  "const parseUrl = value => require('url').parse(value, true);",
                  "const httpsOrigin = value => {",
                  "  const parsed = parseUrl(value);",
                  "  if (parsed.protocol !== 'https:' || !parsed.host || parsed.auth) throw new Error('Expected an HTTPS URL without embedded credentials');",
                  "  return parsed.protocol + '//' + parsed.host.toLowerCase();",
                  "};",
                  "const metadata = pm.response.json();",
                  "for (const key of ['authorization_endpoint', 'token_endpoint']) {",
                  "  pm.expect(httpsOrigin(metadata[key])).to.eql(httpsOrigin(pm.variables.get('tenantGatewayUrl')));",
                  "}",
                  "pm.collectionVariables.set('tenantAuthorizationEndpoint', metadata.authorization_endpoint);",
                  "pm.collectionVariables.set('tenantAccessTokenEndpoint', metadata.token_endpoint);"
                ]
              }
            }
          ]
        },
        {
          "name": "07a Resolve tenant hosted authorization server",
          "request": {
            "method": "GET",
            "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers?page=0&size=100",
            "description": "Lists the authorization servers of the registered tenant through the platform configuration API and selects the tenant default: the active hosted instance tenant registration created and marked default for the GENERAL purpose. The tenant service client is registered on that instance in the next request.",
            "header": []
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('tenant authorization servers listed', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                  "const j = pm.response.json();",
                  "pm.expect(j.items, 'items').to.be.an('array');",
                  "const hosted = j.items.filter((item) => item.deployment === 'HOSTED' && item.lifecycle === 'ACTIVE');",
                  "pm.test('tenant registration created an active hosted authorization server', () => pm.expect(hosted.length).to.be.above(0));",
                  "const defaults = hosted.filter((item) => Array.isArray(item.defaultForPurposes) && item.defaultForPurposes.includes('GENERAL'));",
                  "pm.test('exactly one hosted authorization server is the tenant default', () => pm.expect(defaults.length).to.eql(1));",
                  "const tenantDefault = defaults[0];",
                  "pm.collectionVariables.set('tenantHostedAuthorizationServerId', tenantDefault.id);",
                  "pm.collectionVariables.set('tenantHostedAuthorizationServerSlug', tenantDefault.slug);"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "GET",
                "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/authorization-servers?page=0&size=100",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ]
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"items\": [\n    {\n      \"id\": \"00000000-0000-4000-8000-000000000000\",\n      \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n      \"slug\": \"acme\",\n      \"displayName\": \"Default authorization server\",\n      \"issuer\": \"https://acme.example.com/as/acme\",\n      \"lifecycle\": \"ACTIVE\",\n      \"deployment\": \"HOSTED\",\n      \"authenticationMode\": \"LOCAL_ONLY\",\n      \"purposes\": [\n        \"GENERAL\",\n        \"CREDENTIAL_ISSUANCE\",\n        \"WALLET_LOGIN\"\n      ],\n      \"usages\": [],\n      \"allowedGrantTypes\": [\n        \"authorization_code\",\n        \"urn:ietf:params:oauth:grant-type:pre-authorized_code\",\n        \"client_credentials\",\n        \"refresh_token\"\n      ],\n      \"capabilities\": [\n        \"OAUTH2\",\n        \"OIDC\"\n      ],\n      \"expectedCapabilities\": [],\n      \"system\": true,\n      \"defaultForPurposes\": [\n        \"GENERAL\"\n      ],\n      \"revision\": 1,\n      \"createdAt\": \"2026-01-01T00:00:00Z\",\n      \"updatedAt\": \"2026-01-01T00:00:00Z\"\n    }\n  ],\n  \"total\": 1,\n  \"page\": 0,\n  \"size\": 100\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        },
        {
          "name": "02 Register confidential tenant application",
          "request": {
            "method": "POST",
            "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers/{{tenantHostedAuthorizationServerId}}/clients",
            "description": "Use the tenant owner OAuth token once. Set tenantServiceClientId and a private local tenantServiceClientSecret before sending. The response contains only an opaque credential reference. Then get a client-credentials token on folder 03 Tenant application.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"clientId\": \"{{tenantServiceClientId}}\",\n  \"clientName\": \"{{tenantName}} walkthrough tenant service\",\n  \"clientType\": \"confidential\",\n  \"enabled\": true,\n  \"grantTypes\": [\n    \"client_credentials\"\n  ],\n  \"responseTypes\": [],\n  \"redirectUris\": [],\n  \"defaultAccessTokenAudience\": \"enterprise-platform\",\n  \"allowedAccessTokenAudiences\": [\n    \"enterprise-platform\",\n    \"enterprise-tenant-kms\",\n    \"enterprise-tenant-did\",\n    \"enterprise-tenant-as\",\n    \"enterprise-issuer\",\n    \"enterprise-verifier\",\n    \"enterprise-blob\"\n  ],\n  \"tokenEndpointAuthMethod\": \"client_secret_post\",\n  \"principalRoles\": [\n    \"tenant-admin\"\n  ],\n  \"clientCredential\": {\n    \"method\": \"client_secret_post\",\n    \"clientId\": \"{{tenantServiceClientId}}\",\n    \"secretValue\": \"{{tenantServiceClientSecret}}\"\n  }\n}"
            }
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "for (const key of ['tenantServiceClientId', 'tenantServiceClientSecret']) {",
                  "  if (!String(pm.variables.get(key) || '').trim()) throw new Error('Set the private local input ' + key + ' before registering the client.');",
                  "}"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Request succeeded', () => pm.response.to.have.status(201));",
                  "const result = pm.response.json();",
                  "pm.expect(result.clientId).to.eql(pm.variables.get('tenantServiceClientId'));",
                  "pm.expect(JSON.stringify(result)).not.to.include(pm.variables.get('tenantServiceClientSecret'));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "POST",
                "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/authorization-servers/00000000-0000-4000-8000-000000000000/clients",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientId\": \"edk-walkthrough-tenant-service\",\n  \"clientName\": \"Acme Corporation walkthrough tenant service\",\n  \"clientType\": \"confidential\",\n  \"enabled\": true,\n  \"grantTypes\": [\n    \"client_credentials\"\n  ],\n  \"responseTypes\": [],\n  \"redirectUris\": [],\n  \"defaultAccessTokenAudience\": \"enterprise-platform\",\n  \"allowedAccessTokenAudiences\": [\n    \"enterprise-tenant-kms\",\n    \"enterprise-tenant-did\",\n    \"enterprise-issuer\",\n    \"enterprise-verifier\"\n  ],\n  \"tokenEndpointAuthMethod\": \"client_secret_post\",\n  \"principalRoles\": [\n    \"tenant-admin\"\n  ],\n  \"clientCredential\": {\n    \"method\": \"client_secret_post\",\n    \"clientId\": \"edk-walkthrough-tenant-service\",\n    \"secretValue\": \"<redacted>\"\n  }\n}"
                }
              },
              "status": "Created",
              "code": 201,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"clientId\": \"edk-walkthrough-tenant-service\",\n  \"clientName\": \"Acme Corporation walkthrough tenant service\",\n  \"clientType\": \"confidential\",\n  \"enabled\": true,\n  \"grantTypes\": [\n    \"client_credentials\"\n  ],\n  \"responseTypes\": [],\n  \"redirectUris\": [],\n  \"defaultAccessTokenAudience\": \"enterprise-platform\",\n  \"allowedAccessTokenAudiences\": [\n    \"enterprise-tenant-kms\",\n    \"enterprise-tenant-did\",\n    \"enterprise-issuer\",\n    \"enterprise-verifier\"\n  ],\n  \"principalRoles\": [\n    \"tenant-admin\"\n  ],\n  \"tokenEndpointAuthMethod\": \"client_secret_post\",\n  \"clientCredential\": {\n    \"method\": \"client_secret_post\",\n    \"clientId\": \"edk-walkthrough-tenant-service\",\n    \"secretReference\": {\n      \"resourceHandle\": \"sec_<opaque>\",\n      \"purpose\": \"OAUTH_CLIENT_SECRET\"\n    }\n  },\n  \"postLogoutRedirectUris\": [],\n  \"requestUris\": []\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        }
      ]
    },
    {
      "name": "03 Tenant application",
      "description": "Get New Access Token using Client Credentials, then Use Token. Every ordinary tenant request inherits this OAuth configuration. Refresh here when needed. Use this tenant gateway and tenantId together. All optional cloud/provider examples require your own inputs.\n\nDocumentation: https://docs.sphereon.com/edk/deployment/onboarding-walkthrough#postman-oauth-and-the-first-tenant-client",
      "auth": {
        "type": "oauth2",
        "oauth2": [
          {
            "key": "tokenName",
            "value": "Tenant application",
            "type": "string"
          },
          {
            "key": "grant_type",
            "value": "client_credentials",
            "type": "string"
          },
          {
            "key": "accessTokenUrl",
            "value": "{{tenantAccessTokenEndpoint}}",
            "type": "string"
          },
          {
            "key": "clientId",
            "value": "{{tenantServiceClientId}}",
            "type": "string"
          },
          {
            "key": "clientSecret",
            "value": "{{tenantServiceClientSecret}}",
            "type": "string"
          },
          {
            "key": "client_authentication",
            "value": "body",
            "type": "string"
          },
          {
            "key": "addTokenTo",
            "value": "header",
            "type": "string"
          },
          {
            "key": "headerPrefix",
            "value": "Bearer",
            "type": "string"
          },
          {
            "key": "tokenRequestParams",
            "type": "any",
            "value": [
              {
                "key": "audience",
                "value": "enterprise-platform",
                "enabled": true,
                "send_as": "request_body"
              },
              {
                "key": "audience",
                "value": "enterprise-tenant-kms",
                "enabled": true,
                "send_as": "request_body"
              },
              {
                "key": "audience",
                "value": "enterprise-tenant-did",
                "enabled": true,
                "send_as": "request_body"
              },
              {
                "key": "audience",
                "value": "enterprise-tenant-as",
                "enabled": true,
                "send_as": "request_body"
              },
              {
                "key": "audience",
                "value": "enterprise-issuer",
                "enabled": true,
                "send_as": "request_body"
              },
              {
                "key": "audience",
                "value": "enterprise-verifier",
                "enabled": true,
                "send_as": "request_body"
              },
              {
                "key": "audience",
                "value": "enterprise-blob",
                "enabled": true,
                "send_as": "request_body"
              }
            ]
          }
        ]
      },
      "item": [
        {
          "name": "07 Resolve verifier party id",
          "request": {
            "method": "GET",
            "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/oid4vp/verifier/instances",
            "description": "Reads the verifier instance created during tenant registration and stores its verifier party id. DCQL binding and OID4VP verification requests use this UUID; tenantSubdomain remains only the public host/routing slug.",
            "header": []
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('verifier instances listed', () => pm.response.to.have.status(200));",
                  "const j = pm.response.json();",
                  "const instances = j.data || j.items || j.instances || (Array.isArray(j) ? j : []);",
                  "const stringOf = (value) => typeof value === 'string' && value.trim() ? value.trim() : null;",
                  "const uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;",
                  "const uuidOf = (value) => {",
                  "  const text = stringOf(value);",
                  "  return text && uuidPattern.test(text) ? text : null;",
                  "};",
                  "const capabilityOf = (instance) => instance && typeof instance.capability === 'object' && instance.capability ? instance.capability : {};",
                  "const idOf = (instance) => instance && (",
                  "  uuidOf(instance.partyId) ||",
                  "  uuidOf(capabilityOf(instance).softwarePartyId) ||",
                  "  uuidOf(instance.verifierId) ||",
                  "  uuidOf(instance.id)",
                  ");",
                  "const selected = instances.find((instance) => instance.enabled !== false) || instances[0];",
                  "const resolvedId = idOf(selected);",
                  "const resolvedInstanceId = stringOf(selected && selected.instanceId);",
                  "pm.test('verifier party id resolved from platform config', () => {",
                  "  pm.expect(resolvedId, 'verifier party id').to.be.a('string').and.match(uuidPattern);",
                  "});",
                  "pm.test('verifier runtime instance id resolved from platform config', () => {",
                  "  pm.expect(resolvedInstanceId, 'verifier instance id').to.be.a('string').and.not.empty;",
                  "});",
                  "if (resolvedId) {",
                  "  pm.collectionVariables.set('verifierId', resolvedId);",
                  "}",
                  "if (resolvedInstanceId) {",
                  "  pm.collectionVariables.set('verifierInstanceId', resolvedInstanceId);",
                  "}"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "GET",
                "url": "https://platform.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vp/verifier/instances",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ]
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"items\": [\n    {\n      \"partyId\": \"00000000-0000-4000-8000-000000000000\",\n      \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n      \"displayName\": \"Default Verifier\",\n      \"managementMode\": \"MANAGED\",\n      \"capability\": {\n        \"id\": \"00000000-0000-4000-8000-000000000000\",\n        \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n        \"softwarePartyId\": \"00000000-0000-4000-8000-000000000000\",\n        \"capabilityType\": \"OID4VP_VERIFIER\",\n        \"isEnabled\": true,\n        \"system\": false,\n        \"lifecycleStatus\": \"ACTIVE\",\n        \"createdAt\": \"2026-01-01T00:00:00Z\",\n        \"updatedAt\": \"2026-01-01T00:00:00Z\"\n      },\n      \"instanceId\": \"acme\",\n      \"endpoints\": [\n        {\n          \"id\": \"00000000-0000-4000-8000-000000000000\",\n          \"softwarePartyId\": \"00000000-0000-4000-8000-000000000000\",\n          \"endpointType\": \"BASE\",\n          \"url\": \"https://acme.example.com/oid4vp/acme\",\n          \"source\": \"DECLARED\",\n          \"status\": \"ACTIVE\",\n          \"isPrimary\": true\n        }\n      ],\n      \"credentials\": [],\n      \"createdAt\": \"2026-01-01T00:00:00Z\",\n      \"updatedAt\": \"2026-01-01T00:00:00Z\"\n    }\n  ],\n  \"page\": {\n    \"page\": 0,\n    \"size\": 20,\n    \"totalElements\": 1,\n    \"totalPages\": 1\n  }\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        },
        {
          "name": "08 Resolve issuer instance id",
          "request": {
            "method": "GET",
            "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/oid4vci/issuer/instances",
            "description": "Reads the issuer instance created during tenant registration and stores its runtime instance id. Issuer branding and credential designs bind to this issuer instance id.",
            "header": []
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('issuer instances listed', () => pm.response.to.have.status(200));",
                  "const j = pm.response.json();",
                  "const instances = j.data || j.items || j.instances || (Array.isArray(j) ? j : []);",
                  "const stringOf = (value) => typeof value === 'string' && value.trim() ? value.trim() : null;",
                  "const UUID_SHAPE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;",
                  "const uuidOf = (instance) => instance && ([instance.instanceId, instance.id, instance.issuerId, instance.partyId].map(stringOf).find((v) => v && UUID_SHAPE.test(v)) || null);",
                  "const idOf = (instance) => instance && (",
                  "  stringOf(instance.instanceId) ||",
                  "  stringOf(instance.slug) ||",
                  "  stringOf(instance.id) ||",
                  "  stringOf(instance.issuerId) ||",
                  "  stringOf(instance.partyId)",
                  ");",
                  "const selected = instances.find((instance) => instance.enabled !== false) || instances[0];",
                  "const resolvedId = uuidOf(selected) || idOf(selected);",
                  "pm.test('issuer instance id resolved from platform config', () => {",
                  "  pm.expect(resolvedId, 'issuer instance id').to.be.a('string').and.not.empty;",
                  "});",
                  "if (resolvedId) {",
                  "  pm.collectionVariables.set('issuerId', resolvedId);",
                  "}"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "GET",
                "url": "https://platform.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vci/issuer/instances",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ]
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"items\": [\n    {\n      \"partyId\": \"00000000-0000-4000-8000-000000000000\",\n      \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n      \"displayName\": \"Default Issuer\",\n      \"managementMode\": \"MANAGED\",\n      \"capability\": {\n        \"id\": \"00000000-0000-4000-8000-000000000000\",\n        \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n        \"softwarePartyId\": \"00000000-0000-4000-8000-000000000000\",\n        \"capabilityType\": \"OID4VCI_ISSUER\",\n        \"isEnabled\": true,\n        \"system\": false,\n        \"lifecycleStatus\": \"ACTIVE\",\n        \"createdAt\": \"2026-01-01T00:00:00Z\",\n        \"updatedAt\": \"2026-01-01T00:00:00Z\"\n      },\n      \"instanceId\": \"00000000-0000-4000-8000-000000000000\",\n      \"endpoints\": [\n        {\n          \"id\": \"00000000-0000-4000-8000-000000000000\",\n          \"softwarePartyId\": \"00000000-0000-4000-8000-000000000000\",\n          \"endpointType\": \"BASE\",\n          \"url\": \"https://acme.example.com/oid4vci/acme\",\n          \"source\": \"DECLARED\",\n          \"status\": \"ACTIVE\",\n          \"isPrimary\": true\n        }\n      ],\n      \"credentials\": [],\n      \"createdAt\": \"2026-01-01T00:00:00Z\",\n      \"updatedAt\": \"2026-01-01T00:00:00Z\"\n    }\n  ],\n  \"page\": {\n    \"page\": 0,\n    \"size\": 20,\n    \"totalElements\": 1,\n    \"totalPages\": 1\n  }\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        },
        {
          "name": "06 Tenant Keys and DID",
          "description": "Verifies tenant setup KMS material, discovers the tenant did:web identifier created during tenant activation, and verifies the public did.json document.",
          "item": [
            {
              "name": "01 List KMS offerings",
              "request": {
                "method": "GET",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/kms/offerings",
                "description": "Lists the KMS offerings a tenant may select, using the tenant bearer token. Typed KMS resource management is part of the platform configuration API. Only SOFTWARE, AWS_KMS, and AZURE_KEY_VAULT are tenant-visible; server-only offerings are never discoverable.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('kms offerings listed', () => pm.response.to.have.status(200));",
                      "const kinds = (pm.response.json().offerings || []).map((offering) => offering.kind).filter(Boolean);",
                      "pm.expect(kinds, 'the tenant default SOFTWARE offering is available').to.include('SOFTWARE');",
                      "pm.expect(kinds.filter((kind) => kind === 'SOFTWARE'), 'SOFTWARE is offered once').to.have.lengthOf(1);",
                      "kinds.forEach((kind) => pm.expect(['SOFTWARE', 'AWS_KMS', 'AZURE_KEY_VAULT'], 'offering kind is tenant-visible').to.include(kind));",
                      "(pm.response.json().offerings || []).forEach((offering) => {",
                      "  pm.expect(offering.supportedCredentialOwnerships, 'offering advertises credential ownership').to.be.an('array').and.not.empty;",
                      "  offering.supportedCredentialOwnerships.forEach((ownership) => pm.expect(['PRODUCT_MANAGED', 'TENANT_SUPPLIED'], 'credential ownership').to.include(ownership));",
                      "});",
                      "const text = pm.response.text();",
                      "['INTERNAL_SOFTWARE_KMS', 'internal-token-verifier', 'providerId', 'keyAlias', 'locator', 'permit'].forEach((shape) => pm.expect(text, 'offerings hide ' + shape).to.not.include(shape));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/kms/offerings",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"offerings\": [\n    {\n      \"kind\": \"SOFTWARE\",\n      \"label\": \"Software KMS\",\n      \"available\": true,\n      \"defaultSelected\": true,\n      \"health\": \"UNKNOWN\",\n      \"supportedCredentialOwnerships\": [\n        \"PRODUCT_MANAGED\"\n      ]\n    },\n    {\n      \"kind\": \"AWS_KMS\",\n      \"label\": \"AWS KMS\",\n      \"available\": true,\n      \"defaultSelected\": false,\n      \"health\": \"UNKNOWN\",\n      \"supportedCredentialOwnerships\": [\n        \"PRODUCT_MANAGED\",\n        \"TENANT_SUPPLIED\"\n      ]\n    },\n    {\n      \"kind\": \"AZURE_KEY_VAULT\",\n      \"label\": \"Azure Key Vault\",\n      \"available\": true,\n      \"defaultSelected\": false,\n      \"health\": \"UNKNOWN\",\n      \"supportedCredentialOwnerships\": [\n        \"PRODUCT_MANAGED\",\n        \"TENANT_SUPPLIED\"\n      ]\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 List KMS resources",
              "request": {
                "method": "GET",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/kms/resources",
                "description": "Lists the tenant's typed KMS resources through the platform configuration API. Every resource carries the opaque krh_ handle used for management and the operator-chosen providerId that addresses the same KMS on the runtime KMS REST API. Alias, revision, and locator stay hidden.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('kms resources listed', () => pm.response.to.have.status(200));",
                      "const handles = (pm.response.json().resources || []).map((resource) => resource.handle).filter(Boolean);",
                      "pm.expect(handles, 'tenant setup provisioned a KMS resource').to.have.length.of.at.least(1);",
                      "handles.forEach((handle) => pm.expect(handle, 'resource handle is opaque').to.match(/^krh_[A-Za-z0-9_-]+$/));",
                      "const resources = pm.response.json().resources || [];",
                      "pm.test('every resource publishes the provider id the runtime KMS plane uses', () => {",
                      "  resources.forEach((resource) => {",
                      "    pm.expect(resource.providerId, 'resource provider id').to.match(/^[a-z][a-z0-9-]{2,63}$/);",
                      "    pm.expect(resource.providerId, 'provider id is not the management handle').to.not.match(/^krh_/);",
                      "    pm.expect(['PRODUCT_MANAGED', 'TENANT_SUPPLIED'], 'credential ownership').to.include(resource.credentialOwnership);",
                      "  });",
                      "});",
                      "pm.collectionVariables.set('kmsResourceHandle', handles[0]);",
                      "pm.collectionVariables.set('kmsResourceProviderId', resources[0] && resources[0].providerId);",
                      "pm.collectionVariables.set('kmsResourceKind', resources[0] && resources[0].kind);",
                      "const text = pm.response.text();",
                      "['INTERNAL_SOFTWARE_KMS', 'internal-token-verifier', 'keyAlias', 'locator', 'permit'].forEach((shape) => pm.expect(text, 'resources hide ' + shape).to.not.include(shape));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/kms/resources",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"resources\": [\n    {\n      \"handle\": \"krh_<opaque>\",\n      \"providerId\": \"default\",\n      \"kind\": \"SOFTWARE\",\n      \"displayName\": \"Software KMS\",\n      \"state\": \"CONFIGURED\",\n      \"resourceVersion\": 2,\n      \"credentialConfigured\": true,\n      \"health\": \"UNKNOWN\",\n      \"credentialOwnership\": \"PRODUCT_MANAGED\",\n      \"softwareStorageMode\": \"FILE\",\n      \"softwareKeyStoreFileName\": \"keystore.p12\",\n      \"credentialSecretRef\": \"<redacted>\",\n      \"providerAssignmentId\": null,\n      \"availableActions\": [\n        \"VALIDATE\",\n        \"UPDATE_CREDENTIAL\",\n        \"ROTATE_CREDENTIAL\",\n        \"DETACH\"\n      ],\n      \"declaredByDeployment\": false,\n      \"credentialFromDeployment\": false\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Validate tenant setup KMS resource",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/kms/resources/{{kmsResourceHandle}}/validate",
                "description": "Validates the activation-created typed KMS resource through its opaque krh_ handle. Product DID, issuer, and verifier behavior provides key-operation evidence without exposing internal keys or selectors.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('tenant setup KMS resource validates', () => pm.response.to.have.status(200));",
                      "const j = pm.response.json();",
                      "pm.test('tenant setup KMS validation returns the required public shape', () => {",
                      "  pm.expect(j.handle, 'validated resource handle').to.eql(pm.collectionVariables.get('kmsResourceHandle'));",
                      "  pm.expect(j.handle, 'validated resource handle is opaque').to.match(/^krh_[A-Za-z0-9_-]+$/);",
                      "  pm.expect(['CONFIGURED', 'DEGRADED'], 'validation state').to.include(j.state);",
                      "  pm.expect(['UNKNOWN', 'HEALTHY', 'STALE', 'DEGRADED', 'FAILED'], 'validation health').to.include(j.health);",
                      "});",
                      "const text = pm.response.text();",
                      "['INTERNAL_SOFTWARE_KMS', 'internal-token-verifier', 'providerId', 'keyAlias', 'locator', 'permit'].forEach((shape) => pm.expect(text, 'validation hides ' + shape).to.not.include(shape));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/kms/resources/krh_<opaque>/validate",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"handle\": \"krh_<opaque>\",\n  \"state\": \"CONFIGURED\",\n  \"health\": \"UNKNOWN\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "11 List activation-created DID identifiers",
              "request": {
                "method": "GET",
                "url": "{{tenantDidApiBaseUrl}}/identifiers",
                "description": "Lists managed DIDs for the tenant and verifies tenant activation created the default did:web record. This collection must not create the default DID through the management API.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('did identifiers listed', () => pm.response.to.have.status(200));",
                      "const setPublic = (key, value) => pm.collectionVariables.set(key, value);",
                      "const didWebDocumentUrl = (did, gatewayUrl) => {",
                      "  const prefix = 'did:web:';",
                      "  if (!String(did || '').startsWith(prefix)) return '';",
                      "  const parts = String(did).slice(prefix.length).split(':').map((part) => decodeURIComponent(part));",
                      "  const didAuthority = parts.shift();",
                      "  if (!didAuthority) return '';",
                      "  let scheme = 'https';",
                      "  let gatewayAuthority = '';",
                      "  const gatewayMatch = String(gatewayUrl || '').match(/^([a-z][a-z0-9+.-]*):\\/\\/([^/?#]+)/i);",
                      "  if (gatewayMatch) {",
                      "    scheme = gatewayMatch[1].toLowerCase();",
                      "    gatewayAuthority = gatewayMatch[2];",
                      "  }",
                      "  const gatewayHostname = gatewayAuthority.replace(/:\\d+$/, '');",
                      "  const didAuthorityHostname = didAuthority.replace(/:\\d+$/, '');",
                      "  const useGatewayAuthority = gatewayHostname === didAuthorityHostname || gatewayAuthority === didAuthority;",
                      "  const authority = useGatewayAuthority ? gatewayAuthority : didAuthority;",
                      "  const outputScheme = useGatewayAuthority ? scheme : 'https';",
                      "  const documentPath = parts.length ? '/' + parts.map((part) => encodeURIComponent(part)).join('/') + '/did.json' : '/.well-known/did.json';",
                      "  return outputScheme + '://' + authority + documentPath;",
                      "};",
                      "const collectDids = (value, out) => {",
                      "  if (typeof value === 'string') {",
                      "    if (value.indexOf('did:web:') === 0 && value.indexOf('#') < 0) out.push(value);",
                      "    return out;",
                      "  }",
                      "  if (Array.isArray(value)) { value.forEach((item) => collectDids(item, out)); return out; }",
                      "  if (value && typeof value === 'object') Object.keys(value).forEach((key) => collectDids(value[key], out));",
                      "  return out;",
                      "};",
                      "const body = pm.response.json();",
                      "const expectedDid = pm.collectionVariables.get('did');",
                      "const discovered = collectDids(body, []).filter((did, index, all) => all.indexOf(did) === index);",
                      "const activationDid = discovered.find((did) => did === expectedDid) || discovered[0];",
                      "pm.expect(activationDid, 'activation-created did discovered from identifiers API').to.eql(expectedDid);",
                      "setPublic('did', activationDid);",
                      "setPublic('didEncoded', encodeURIComponent(activationDid));",
                      "setPublic('didJsonUrl', didWebDocumentUrl(activationDid, pm.variables.get('tenantGatewayUrl')));",
                      "pm.expect(pm.collectionVariables.get('didJsonUrl'), 'did.json URL discovered from activation-created did:web').to.include('/did.json');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/did/v1/identifiers",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"items\": [\n    {\n      \"did\": \"did:web:acme.example.com\",\n      \"method\": \"web\",\n      \"alias\": \"acme\",\n      \"role\": \"EXTERNAL\",\n      \"createdAt\": \"2026-01-01T00:00:00Z\",\n      \"updatedAt\": \"2026-01-01T00:00:00Z\"\n    }\n  ],\n  \"page\": {\n    \"limit\": 100,\n    \"offset\": 0,\n    \"page\": 0,\n    \"size\": 100,\n    \"total\": 1,\n    \"totalPages\": 1,\n    \"hasMore\": false\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "12 Resolve activation-created DID",
              "request": {
                "method": "GET",
                "url": "{{tenantDidApiBaseUrl}}/identifiers/{{didEncoded}}",
                "description": "Resolves the activation-created DID through the management API and returns the full record including the DID document.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('did resolved', () => pm.response.to.have.status(200));",
                      "pm.expect(pm.response.text(), 'resolved activation-created did appears').to.include(pm.collectionVariables.get('did'));",
                      "pm.expect(pm.collectionVariables.get('didJsonUrl'), 'did.json URL is available for hosted discovery').to.include('/did.json');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/did/v1/identifiers/did%3Aweb%3Aacme.example.com",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"did\": \"did:web:acme.example.com\",\n  \"method\": \"web\",\n  \"alias\": \"acme\",\n  \"role\": \"EXTERNAL\",\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "13 List activation-created DID verification methods",
              "request": {
                "method": "GET",
                "url": "{{tenantDidApiBaseUrl}}/identifiers/{{didEncoded}}/verification-methods",
                "description": "Lists verification methods on the activation-created managed DID, proving tenant setup attached the verifier authentication key and issuer assertion key.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('verification methods listed', () => pm.response.to.have.status(200));",
                      "const text = pm.response.text();",
                      "pm.expect(text, 'did appears in methods response').to.include(pm.collectionVariables.get('did'));",
                      "const methods = Array.isArray(pm.response.json()) ? pm.response.json() : (pm.response.json().verificationMethods || pm.response.json().items || []);",
                      "pm.expect(methods.length, 'activation DID has product verification methods').to.be.at.least(2);",
                      "methods.forEach((method) => pm.expect(String(method.id || method.verificationMethodId || ''), 'verification method belongs to activation DID').to.include(pm.collectionVariables.get('did') + '#'));",
                      "const verifierMethodId = pm.collectionVariables.get('did') + '#verifier-request-object-' + pm.collectionVariables.get('verifierInstanceId');",
                      "const verifierMethod = methods.find((method) => String(method.id || method.verificationMethodId || '') === verifierMethodId);",
                      "pm.expect(verifierMethod, 'verifier request-object verification method is published').to.be.an('object');",
                      "pm.collectionVariables.set('verifierDidVerificationMethodId', verifierMethodId);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/did/v1/identifiers/did%3Aweb%3Aacme.example.com/verification-methods",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"items\": [\n    {\n      \"id\": \"did:web:acme.example.com#verifier-request-object-acme\",\n      \"type\": \"JsonWebKey2020\",\n      \"controller\": \"did:web:acme.example.com\",\n      \"referenceVerificationRelations\": [\n        \"assertionMethod\",\n        \"authentication\"\n      ],\n      \"ordinal\": 0\n    },\n    {\n      \"id\": \"did:web:acme.example.com#issuer-assertion-acme\",\n      \"type\": \"JsonWebKey2020\",\n      \"controller\": \"did:web:acme.example.com\",\n      \"referenceVerificationRelations\": [\n        \"assertionMethod\"\n      ],\n      \"ordinal\": 1\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "14 Fetch hosted activation did.json",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{didJsonUrl}}",
                "description": "Fetches the activation-created did:web document from the did.json URL derived from the discovered DID.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('did.json returned', () => pm.response.to.have.status(200));",
                      "pm.expect(pm.variables.get('didJsonUrl'), 'did.json URL derived from activation DID').to.include('/did.json');",
                      "const j = pm.response.json();",
                      "pm.expect(j.id, 'hosted did id').to.eql(pm.collectionVariables.get('did'));",
                      "const methods = Array.isArray(j.verificationMethod) ? j.verificationMethod : [];",
                      "pm.expect(methods.length, 'hosted did verification methods').to.be.at.least(2);",
                      "const assertion = Array.isArray(j.assertionMethod) ? j.assertionMethod : [];",
                      "pm.expect(assertion.length, 'hosted did assertion methods').to.be.at.least(2);",
                      "pm.expect(JSON.stringify(assertion), 'assertion methods point at activation DID').to.include(pm.collectionVariables.get('did') + '#');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/.well-known/did.json",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/did+json"
                    }
                  ],
                  "body": "{\n  \"id\": \"did:web:acme.example.com\",\n  \"verificationMethod\": [\n    {\n      \"id\": \"did:web:acme.example.com#verifier-request-object-acme\",\n      \"type\": \"JsonWebKey2020\",\n      \"controller\": \"did:web:acme.example.com\",\n      \"publicKeyJwk\": {\n        \"crv\": \"P-256\",\n        \"kty\": \"EC\",\n        \"x\": \"<public-key-material>\",\n        \"x5c\": [\n          \"<certificate>\"\n        ],\n        \"y\": \"<public-key-material>\"\n      }\n    },\n    {\n      \"id\": \"did:web:acme.example.com#issuer-assertion-acme\",\n      \"type\": \"JsonWebKey2020\",\n      \"controller\": \"did:web:acme.example.com\",\n      \"publicKeyJwk\": {\n        \"crv\": \"P-256\",\n        \"kty\": \"EC\",\n        \"x\": \"<public-key-material>\",\n        \"x5c\": [\n          \"<certificate>\"\n        ],\n        \"y\": \"<public-key-material>\"\n      }\n    }\n  ],\n  \"authentication\": [\n    \"did:web:acme.example.com#verifier-request-object-acme\"\n  ],\n  \"assertionMethod\": [\n    \"did:web:acme.example.com#verifier-request-object-acme\",\n    \"did:web:acme.example.com#issuer-assertion-acme\"\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "07 Azure Key Vault and external keys (optional)",
          "description": "Tenant-owned vault: set tenantAzureVaultUri, tenantAzureTenantId, tenantAzureClientId and private tenantAzureClientSecret. Keys remain in Azure. Supply a matching public DER certificate chain; repeat array entries for intermediates. For a shared platform vault use folder 04 first and skip requests 01-03 here, setting tenantAzureProviderId to the offered providerId.\n\nDocumentation: https://docs.sphereon.com/edk/guides/azure-kms-byok-byoc",
          "item": [
            {
              "name": "01 Create an Azure Key Vault KMS resource",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/kms/resources",
                "description": "Registers your own Azure Key Vault as a KMS resource of this tenant. providerId is the name you will use for this KMS on the KMS runtime API; applicationId is the label EDK stamps on keys it generates in the vault; tenantId and clientId identify the Entra application EDK signs in with. Keys generated through this resource never leave the vault.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"providerId\": \"{{tenantAzureProviderId}}\",\n  \"kind\": \"AZURE_KEY_VAULT\",\n  \"displayName\": \"{{tenantAzureDisplayName}}\",\n  \"configuration\": {\n    \"vaultUri\": \"{{tenantAzureVaultUri}}\",\n    \"tenantId\": \"{{tenantAzureTenantId}}\",\n    \"clientId\": \"{{tenantAzureClientId}}\",\n    \"hsmType\": \"KEYVAULT\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Azure Key Vault KMS resource created', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([201]));",
                      "const resource = pm.response.json();",
                      "pm.test('the resource is addressed by an opaque handle and your provider id', () => {",
                      "  pm.expect(resource.handle, 'resource handle').to.match(/^krh_[A-Za-z0-9_-]+$/);",
                      "  pm.expect(resource.providerId, 'provider id').to.eql(pm.variables.get('tenantAzureProviderId'));",
                      "  pm.expect(resource.kind, 'kind').to.eql('AZURE_KEY_VAULT');",
                      "  pm.expect(resource.credentialConfigured, 'no credential yet').to.eql(false);",
                      "  pm.expect(resource.credentialSecretRef, 'credential slot reference').to.match(/^kcr_[A-Za-z0-9_-]{20,180}_azure$/);",
                      "});",
                      "pm.collectionVariables.set('tenantAzureResourceHandle', resource.handle);",
                      "pm.collectionVariables.set('tenantAzureResourceVersion', String(resource.resourceVersion));",
                      "pm.collectionVariables.set('tenantAzureCredentialSecretRef', resource.credentialSecretRef);",
                      "pm.collectionVariables.set('tenantCloudKmsProviderId', resource.providerId);"
                    ]
                  }
                }
              ]
            },
            {
              "name": "02 Attach the Azure client secret",
              "request": {
                "method": "PUT",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/kms/resources/{{tenantAzureResourceHandle}}/credentials/azure-key-vault",
                "description": "Writes the Entra client secret once. The request names the credential slot the create response returned and the resource version it expects; the response confirms the write without ever returning the secret.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"expectedResourceVersion\": \"{{tenantAzureResourceVersion}}\",\n  \"clientSecretRef\": \"{{tenantAzureCredentialSecretRef}}\",\n  \"clientSecret\": \"{{tenantAzureClientSecret}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Azure client secret attached', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200]));",
                      "const result = pm.response.json();",
                      "pm.test('the write advances the resource version and marks the credential present', () => {",
                      "  pm.expect(result.handle, 'resource handle').to.eql(pm.collectionVariables.get('tenantAzureResourceHandle'));",
                      "  pm.expect(result.credentialConfigured, 'credential configured').to.eql(true);",
                      "  pm.expect(result.secretRef, 'credential slot reference').to.eql(pm.collectionVariables.get('tenantAzureCredentialSecretRef'));",
                      "  pm.expect(result.resourceVersion, 'resource version').to.be.above(Number(pm.collectionVariables.get('tenantAzureResourceVersion')));",
                      "});",
                      "const responseText = pm.response.text();",
                      "pm.expect(responseText, 'the response never echoes the supplied secret').to.not.include(pm.variables.get('tenantAzureClientSecret'));",
                      "pm.expect(responseText, 'the response carries no secret value field').to.not.match(/\"(?:clientSecret|secretAccessKey|password|secretValue)\"\\s*:/i);",
                      "pm.collectionVariables.set('tenantAzureResourceVersion', String(result.resourceVersion));"
                    ]
                  }
                }
              ]
            },
            {
              "name": "03 Validate the Azure Key Vault resource",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/kms/resources/{{tenantAzureResourceHandle}}/validate",
                "description": "Asks the platform to reach the vault with the stored credential. A CONFIGURED state with HEALTHY health means keys can be generated and used there.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Azure Key Vault resource validated', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200]));",
                      "const result = pm.response.json();",
                      "pm.test('the vault is reachable with the stored credential', () => {",
                      "  pm.expect(result.handle, 'resource handle').to.eql(pm.collectionVariables.get('tenantAzureResourceHandle'));",
                      "  pm.expect(result.state, 'state').to.eql('CONFIGURED');",
                      "  pm.expect(['HEALTHY', 'UNKNOWN'], 'health').to.include(result.health);",
                      "});"
                    ]
                  }
                }
              ]
            },
            {
              "name": "04 Register existing Azure key reference",
              "request": {
                "method": "POST",
                "url": "{{tenantKmsApiBaseUrl}}/keys/register",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"providerId\": \"{{tenantAzureProviderId}}\",\n  \"alias\": \"{{externalKeyAlias}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(201));"
                    ]
                  }
                }
              ]
            },
            {
              "name": "05 Read external key public metadata",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/keys/{{externalKeyAlias}}?providerId={{tenantAzureProviderId}}",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ]
            },
            {
              "name": "06 Register externally managed certificate chain",
              "request": {
                "method": "POST",
                "url": "{{tenantKmsApiBaseUrl}}/certificates/register",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"providerId\": \"{{tenantAzureProviderId}}\",\n  \"alias\": \"{{externalAzureCertificateAlias}}\",\n  \"kind\": \"key_certificate_chain\",\n  \"source\": \"stored_public_material\",\n  \"linkedKeyAlias\": \"{{externalKeyAlias}}\",\n  \"certificateChain\": [\n    \"{{externalCertificateDerBase64}}\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(201));"
                    ]
                  }
                }
              ]
            },
            {
              "name": "07 Read the registered certificate chain",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/certificate-chains/{{externalAzureCertificateAlias}}?providerId={{tenantAzureProviderId}}",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ]
            }
          ]
        },
        {
          "name": "08 Enable shared Azure provider (optional)",
          "description": "Run after the platform operator offers the vault in folder 04. Use the tenant application OAuth token. Copy the offered providerId to tenantAzureProviderId before registering external references. Sharing does not grant authority over other tenants or platform keys.",
          "item": [
            {
              "name": "05 List platform KMSes offered to the tenant",
              "request": {
                "method": "GET",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/kms/shared-providers",
                "description": "Lists the platform KMSes this tenant may enable. The offer carries presentation and fulfillment only; the platform KMS configuration and credentials are never part of it.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/kms/shared-providers",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"providers\": [\n    {\n      \"providerId\": \"walkthrough-platform-00000000-0000-4000-8000-000000000000\",\n      \"fulfillment\": \"SHARED_INSTANCE\",\n      \"kind\": \"SOFTWARE\",\n      \"displayName\": \"Developer journey platform software KMS\",\n      \"enabled\": false,\n      \"suggestedDefault\": false,\n      \"declaredByDeployment\": false,\n      \"credentialFromDeployment\": false\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 Enable the offered platform KMS",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/kms/shared-providers/{{platformAzureProviderId}}:enable",
                "description": "The tenant takes up the shared-instance offer. The typed provider resource and credentials remain platform-owned; only this tenant's entitlement and tenant-scoped reference namespace become active.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/kms/shared-providers/walkthrough-platform-00000000-0000-4000-8000-000000000000:enable",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"providerId\": \"walkthrough-platform-00000000-0000-4000-8000-000000000000\",\n  \"fulfillment\": \"SHARED_INSTANCE\",\n  \"kind\": \"SOFTWARE\",\n  \"displayName\": \"Developer journey platform software KMS\",\n  \"enabled\": true,\n  \"suggestedDefault\": false,\n  \"declaredByDeployment\": false,\n  \"credentialFromDeployment\": false\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "09 List runtime KMS providers",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/providers",
                "description": "Lists the providers the tenant reaches on the runtime KMS REST API. The admin console joins this list to the management-plane resource list on providerId, so the two planes must agree on that identifier exactly, and the runtime plane must never answer with the krh_ management handle.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/kms/v1/providers",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"providers\": [\n    {\n      \"providerId\": \"default\",\n      \"type\": \"SOFTWARE\",\n      \"displayName\": \"Software KMS\",\n      \"ownership\": \"TENANT\",\n      \"sharedFromPlatform\": false,\n      \"isDefault\": true\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ]
        },
        {
          "name": "09 Keycloak wallet proxy (optional)",
          "description": "Create a separate hosted wallet AS. The default tenant AS stays LOCAL_ONLY for administration. In Keycloak register federationClientId as a confidential OIDC client with Standard Flow and the exact redirect https://<tenant>/as/<authorizationServerSlug>/federation/callback. Set keycloakIssuer to the realm issuer and federationClientSecret to its private client secret. Keycloak is an upstream login provider, not the OID4VCI authorization server. Run this folder after resolving issuerId. No teardown follows. If this tenant already registered the same Keycloak issuer, set externalAuthorizationServerId to that resource UUID and skip request 25; request 25a verifies the selected external upstream before binding it. Each issuer is registered once per tenant.\n\nDocumentation: https://docs.sphereon.com/edk/guides/tenant/federation#postman-keycloak-wallet-proxy",
          "item": [
            {
              "name": "09 Create hosted authorization server",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers",
                "description": "",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"slug\": \"{{authorizationServerSlug}}\",\n  \"displayName\": \"{{tenantName}} wallet proxy\",\n  \"issuer\": \"{{tenantGatewayUrl}}/as/{{authorizationServerSlug}}\",\n  \"deployment\": \"HOSTED\",\n  \"authenticationMode\": \"FEDERATED_ONLY\",\n  \"purposes\": [\n    \"CREDENTIAL_ISSUANCE\",\n    \"WALLET_LOGIN\"\n  ],\n  \"usages\": [],\n  \"allowedGrantTypes\": [\n    \"authorization_code\",\n    \"refresh_token\"\n  ]\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('hosted authorization server created', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(201));",
                      "const j = pm.response.json();",
                      "pm.expect(j.id, 'resource UUID').to.match(/^[0-9a-f]{8}-[0-9a-f-]{27}$/i);",
                      "pm.collectionVariables.set('hostedAuthorizationServerId', j.id);",
                      "pm.collectionVariables.set('hostedAuthorizationServerRevision', String(j.revision));",
                      "pm.expect(pm.response.json().lifecycle).to.eql('ACTIVE');"
                    ]
                  }
                }
              ]
            },
            {
              "name": "16 Register public hosted client",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers/{{hostedAuthorizationServerId}}/clients",
                "description": "",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"clientId\": \"{{publicHostedClientId}}\",\n  \"clientName\": \"Postman wallet\",\n  \"clientType\": \"public\",\n  \"enabled\": true,\n  \"grantTypes\": [\n    \"authorization_code\",\n    \"refresh_token\"\n  ],\n  \"responseTypes\": [\n    \"code\"\n  ],\n  \"redirectUris\": [\n    \"https://oauth.pstmn.io/v1/browser-callback\"\n  ],\n  \"allowedScopes\": [\n    \"openid\",\n    \"profile\",\n    \"email\"\n  ],\n  \"tokenEndpointAuthMethod\": \"none\",\n  \"requirePkce\": true\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('public client registered', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(201));",
                      "const j = pm.response.json();",
                      "pm.expect(j.clientId).to.eql(pm.variables.replaceIn('{{publicHostedClientId}}'));",
                      "pm.expect(j.tokenEndpointAuthMethod).to.eql('none');"
                    ]
                  }
                }
              ]
            },
            {
              "name": "25 Create external authorization server from discovery",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers",
                "description": "",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"displayName\": \"Keycloak upstream\",\n  \"issuer\": \"{{keycloakIssuer}}\",\n  \"deployment\": \"EXTERNAL\",\n  \"expectedCapabilities\": [\n    \"OAUTH2\",\n    \"OIDC\"\n  ],\n  \"purposes\": [\n    \"WALLET_LOGIN\"\n  ],\n  \"usages\": [\n    \"HOSTED_LOGIN_UPSTREAM\"\n  ],\n  \"allowedGrantTypes\": [\n    \"authorization_code\"\n  ]\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('external authorization server created', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(201));",
                      "const j = pm.response.json();",
                      "pm.expect(j.id, 'resource UUID').to.match(/^[0-9a-f]{8}-[0-9a-f-]{27}$/i);",
                      "pm.collectionVariables.set('externalAuthorizationServerId', j.id);",
                      "pm.collectionVariables.set('externalAuthorizationServerRevision', String(j.revision));",
                      "pm.expect(j.expectedCapabilities).to.have.members(['OAUTH2','OIDC']);",
                      "pm.expect(j.capabilities).to.include.members(['OAUTH2','OIDC']);",
                      "pm.expect(j.discovery.digest).to.match(/^[a-f0-9]{64}$/);",
                      "pm.expect(j.discovery.userinfoEndpoint).to.match(/^https:\\/\\//);",
                      "pm.expect(j.discovery.tokenEndpointAuthMethodsSupported).to.be.an('array');"
                    ]
                  }
                }
              ]
            },
            {
              "name": "25a Read the external upstream by UUID",
              "request": {
                "method": "GET",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers/{{externalAuthorizationServerId}}",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));",
                      "const result = pm.response.json();",
                      "pm.expect(result.id).to.eql(pm.collectionVariables.get('externalAuthorizationServerId'));",
                      "pm.expect(result.deployment).to.eql('EXTERNAL');",
                      "pm.expect(result.issuer).to.eql(pm.variables.get('keycloakIssuer'));",
                      "pm.expect(result.slug == null).to.eql(true);"
                    ]
                  }
                }
              ]
            },
            {
              "name": "26 Validate external authorization server discovery",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers/{{externalAuthorizationServerId}}/validate",
                "description": "",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('external discovery validated', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "pm.expect(j.valid).to.eql(true);",
                      "pm.expect(j.snapshot.freshness).to.eql('CURRENT');",
                      "pm.expect(j.snapshot.digest).to.match(/^[a-f0-9]{64}$/);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/authorization-servers/00000000-0000-4000-8000-000000000000/validate",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"valid\": true,\n  \"checkedAt\": \"2026-01-01T00:00:00Z\",\n  \"snapshot\": {\n    \"capabilities\": [\n      \"OAUTH2\",\n      \"OIDC\"\n    ],\n    \"grantTypes\": [\n      \"authorization_code\",\n      \"urn:ietf:params:oauth:grant-type:pre-authorized_code\",\n      \"client_credentials\",\n      \"refresh_token\"\n    ],\n    \"tokenEndpointAuthMethodsSupported\": [\n      \"client_secret_basic\",\n      \"client_secret_post\"\n    ],\n    \"issuer\": \"https://platform.example.com\",\n    \"authorizationEndpoint\": \"https://platform.example.com/authorize\",\n    \"tokenEndpoint\": \"https://platform.example.com/token\",\n    \"userinfoEndpoint\": \"https://platform.example.com/userinfo\",\n    \"pushedAuthorizationRequestEndpoint\": \"https://platform.example.com/par\",\n    \"jwksUri\": \"https://platform.example.com/.well-known/jwks.json\",\n    \"scopesSupported\": [\n      \"openid\",\n      \"profile\",\n      \"email\",\n      \"developer-console.read\"\n    ],\n    \"idTokenSigningAlgorithms\": [\n      \"ES256\"\n    ],\n    \"sourceUrls\": [\n      \"https://platform.example.com/.well-known/oauth-authorization-server\",\n      \"https://platform.example.com/.well-known/openid-configuration\"\n    ],\n    \"digest\": \"<digest>\",\n    \"validatedAt\": \"2026-01-01T00:00:00Z\",\n    \"validUntil\": \"2027-01-01T00:00:00Z\",\n    \"freshness\": \"CURRENT\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "29 Activate external authorization server",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers/{{externalAuthorizationServerId}}/activate",
                "description": "",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"expectedRevision\": \"{{externalAuthorizationServerRevision}}\"\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('external authorization server activated', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "pm.collectionVariables.set('externalAuthorizationServerRevision', String(j.revision));",
                      "pm.expect(pm.response.json().lifecycle).to.eql('ACTIVE');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/authorization-servers/00000000-0000-4000-8000-000000000000/activate",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"expectedRevision\": \"2\"\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"slug\": \"platform-upstream\",\n  \"displayName\": \"Platform external authorization server\",\n  \"issuer\": \"https://platform.example.com\",\n  \"lifecycle\": \"ACTIVE\",\n  \"deployment\": \"EXTERNAL\",\n  \"purposes\": [\n    \"GENERAL\",\n    \"CREDENTIAL_ISSUANCE\",\n    \"WALLET_LOGIN\"\n  ],\n  \"usages\": [\n    \"OID4VCI_AUTHORIZATION_SERVER\",\n    \"HOSTED_LOGIN_UPSTREAM\"\n  ],\n  \"allowedGrantTypes\": [\n    \"authorization_code\",\n    \"refresh_token\"\n  ],\n  \"capabilities\": [\n    \"OAUTH2\",\n    \"OIDC\"\n  ],\n  \"expectedCapabilities\": [\n    \"OAUTH2\",\n    \"OIDC\"\n  ],\n  \"system\": false,\n  \"defaultForPurposes\": [],\n  \"discovery\": {\n    \"capabilities\": [\n      \"OAUTH2\",\n      \"OIDC\"\n    ],\n    \"grantTypes\": [\n      \"authorization_code\",\n      \"urn:ietf:params:oauth:grant-type:pre-authorized_code\",\n      \"client_credentials\",\n      \"refresh_token\"\n    ],\n    \"tokenEndpointAuthMethodsSupported\": [\n      \"client_secret_basic\",\n      \"client_secret_post\"\n    ],\n    \"issuer\": \"https://platform.example.com\",\n    \"authorizationEndpoint\": \"https://platform.example.com/authorize\",\n    \"tokenEndpoint\": \"https://platform.example.com/token\",\n    \"userinfoEndpoint\": \"https://platform.example.com/userinfo\",\n    \"pushedAuthorizationRequestEndpoint\": \"https://platform.example.com/par\",\n    \"jwksUri\": \"https://platform.example.com/.well-known/jwks.json\",\n    \"scopesSupported\": [\n      \"openid\",\n      \"profile\",\n      \"email\",\n      \"developer-console.read\"\n    ],\n    \"idTokenSigningAlgorithms\": [\n      \"ES256\"\n    ],\n    \"sourceUrls\": [\n      \"https://platform.example.com/.well-known/oauth-authorization-server\",\n      \"https://platform.example.com/.well-known/openid-configuration\"\n    ],\n    \"digest\": \"<digest>\",\n    \"validatedAt\": \"2026-01-01T00:00:00Z\",\n    \"validUntil\": \"2027-01-01T00:00:00Z\",\n    \"freshness\": \"CURRENT\"\n  },\n  \"revision\": 2,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "30 Create disabled federation binding",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers/{{hostedAuthorizationServerId}}/federation-bindings",
                "description": "Creates the disabled binding with an operator-provided client id and a write-once secret. The server persists only the typed OAUTH_CLIENT_SECRET reference and never returns raw secret material.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"externalAuthorizationServerId\": \"{{externalAuthorizationServerId}}\",\n  \"order\": 0,\n  \"enabled\": false,\n  \"scopes\": [\n    \"openid\",\n    \"profile\",\n    \"email\"\n  ],\n  \"claimsMapping\": {\n    \"subject\": \"sub\",\n    \"email\": \"email\",\n    \"displayName\": \"name\"\n  },\n  \"clientAuthentication\": {\n    \"method\": \"client_secret_basic\",\n    \"clientId\": \"{{federationClientId}}\",\n    \"secretValue\": \"{{federationClientSecret}}\"\n  }\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(201));",
                      "const result = pm.response.json();",
                      "pm.collectionVariables.set('federationBindingId', result.id);",
                      "pm.collectionVariables.set('federationBindingRevision', String(result.revision));",
                      "pm.expect(JSON.stringify(result)).not.to.include(pm.variables.get('federationClientSecret'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/authorization-servers/00000000-0000-4000-8000-000000000000/federation-bindings",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"externalAuthorizationServerId\": \"00000000-0000-4000-8000-000000000000\",\n  \"order\": 0,\n  \"enabled\": false,\n  \"scopes\": [\n    \"openid\",\n    \"profile\",\n    \"email\"\n  ],\n  \"claimsMapping\": {\n    \"subject\": \"sub\",\n    \"email\": \"email\",\n    \"displayName\": \"name\"\n  },\n  \"clientAuthentication\": {\n    \"method\": \"client_secret_basic\",\n    \"clientId\": \"walkthrough-federation-client\",\n    \"secretValue\": \"<redacted>\"\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"hostedAuthorizationServerId\": \"00000000-0000-4000-8000-000000000000\",\n  \"externalAuthorizationServerId\": \"00000000-0000-4000-8000-000000000000\",\n  \"order\": 0,\n  \"enabled\": false,\n  \"scopes\": [\n    \"openid\",\n    \"profile\",\n    \"email\"\n  ],\n  \"claimsMapping\": {\n    \"email\": \"email\",\n    \"subject\": \"sub\",\n    \"displayName\": \"name\"\n  },\n  \"clientAuthentication\": {\n    \"method\": \"client_secret_basic\",\n    \"clientId\": \"walkthrough-federation-client\",\n    \"secretReference\": {\n      \"resourceHandle\": \"sec_<opaque>\",\n      \"purpose\": \"OAUTH_CLIENT_SECRET\"\n    }\n  },\n  \"status\": \"UNVALIDATED\",\n  \"revision\": 0\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "31 Validate federation binding",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers/{{hostedAuthorizationServerId}}/federation-bindings/{{federationBindingId}}/validate",
                "description": "",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('federation binding validated', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "pm.expect(j.status).to.eql('VALID');",
                      "pm.expect(j.lastValidatedAt).to.be.a('string');",
                      "pm.collectionVariables.set('federationBindingRevision', String(j.revision));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/authorization-servers/00000000-0000-4000-8000-000000000000/federation-bindings/00000000-0000-4000-8000-000000000000/validate",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"hostedAuthorizationServerId\": \"00000000-0000-4000-8000-000000000000\",\n  \"externalAuthorizationServerId\": \"00000000-0000-4000-8000-000000000000\",\n  \"order\": 0,\n  \"enabled\": false,\n  \"scopes\": [\n    \"openid\",\n    \"profile\",\n    \"email\"\n  ],\n  \"claimsMapping\": {\n    \"email\": \"email\",\n    \"subject\": \"sub\",\n    \"displayName\": \"name\"\n  },\n  \"clientAuthentication\": {\n    \"method\": \"client_secret_basic\",\n    \"clientId\": \"walkthrough-federation-client\",\n    \"secretReference\": {\n      \"resourceHandle\": \"sec_<opaque>\",\n      \"purpose\": \"OAUTH_CLIENT_SECRET\"\n    }\n  },\n  \"status\": \"VALID\",\n  \"lastValidatedAt\": \"2026-01-01T00:00:00Z\",\n  \"revision\": 1\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "34 Enable validated federation binding",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/authorization-servers/{{hostedAuthorizationServerId}}/federation-bindings/{{federationBindingId}}/enable",
                "description": "",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('federation binding enabled', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "pm.expect(j.enabled).to.eql(true);",
                      "pm.expect(j.status).to.eql('VALID');",
                      "pm.collectionVariables.set('federationBindingRevision', String(j.revision));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/authorization-servers/00000000-0000-4000-8000-000000000000/federation-bindings/00000000-0000-4000-8000-000000000000/enable",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"hostedAuthorizationServerId\": \"00000000-0000-4000-8000-000000000000\",\n  \"externalAuthorizationServerId\": \"00000000-0000-4000-8000-000000000000\",\n  \"order\": 0,\n  \"enabled\": true,\n  \"scopes\": [\n    \"openid\",\n    \"profile\",\n    \"email\"\n  ],\n  \"claimsMapping\": {\n    \"email\": \"email\",\n    \"subject\": \"sub\",\n    \"displayName\": \"name\"\n  },\n  \"clientAuthentication\": {\n    \"method\": \"client_secret_basic\",\n    \"clientId\": \"walkthrough-federation-client\",\n    \"secretReference\": {\n      \"resourceHandle\": \"sec_<opaque>\",\n      \"purpose\": \"OAUTH_CLIENT_SECRET\"\n    }\n  },\n  \"status\": \"VALID\",\n  \"lastValidatedAt\": \"2026-01-01T00:00:00Z\",\n  \"revision\": 5\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "36 Bind wallet proxy to issuer for authorization code",
              "request": {
                "method": "POST",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/oid4vci/issuers/{{issuerId}}/authorization-server-bindings",
                "description": "",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"authorizationServerId\": \"{{hostedAuthorizationServerId}}\",\n  \"enabled\": true,\n  \"default\": false,\n  \"allowedGrantTypes\": [\n    \"authorization_code\"\n  ]\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(201));",
                      "const result = pm.response.json();",
                      "pm.collectionVariables.set('issuerAuthorizationServerBindingId', result.id);",
                      "pm.expect(result.authorizationServerId).to.eql(pm.collectionVariables.get('hostedAuthorizationServerId'));"
                    ]
                  }
                }
              ]
            }
          ]
        },
        {
          "name": "10 Issuer Configuration",
          "description": "Issuer configuration is separate from authorization-server configuration. This stage creates the issuer design and display metadata; credential configurations, signing material, and status-list references follow in 11, 12, and 13.\n\nDocumentation: https://docs.sphereon.com/edk/admin-console/guides/issuer-configuration",
          "item": [
            {
              "name": "01 Create issuer design",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/issuers",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"bindings\": [\n    {\n      \"issuerDid\": \"{{did}}\",\n      \"issuerId\": \"{{issuerId}}\",\n      \"issuerUri\": \"{{tenantGatewayUrl}}\"\n    }\n  ],\n  \"alias\": \"{{tenantSubdomain}}-authority\",\n  \"hostingMode\": \"LOCAL\",\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"displayName\": \"{{tenantName}} Authority\",\n      \"description\": \"{{tenantName}} credential issuing authority\"\n    },\n    {\n      \"locale\": \"nl\",\n      \"displayName\": \"{{tenantName}} Autoriteit\",\n      \"description\": \"Uitgevende autoriteit voor verifieerbare credentials van {{tenantName}}\"\n    }\n  ]\n}"
                },
                "description": "Binds the issuing identity to the tenant's did:web identifier. Wallets display this name and description when presenting a credential offer."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('issuer design created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "if (j.id) pm.collectionVariables.set('issuerDesignId', j.id);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/issuers",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"bindings\": [\n    {\n      \"issuerDid\": \"did:web:acme.example.com\",\n      \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n      \"issuerUri\": \"https://acme.example.com\"\n    }\n  ],\n  \"alias\": \"acme-authority\",\n  \"hostingMode\": \"LOCAL\",\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"displayName\": \"Acme Corporation Authority\",\n      \"description\": \"Acme Corporation credential issuing authority\"\n    },\n    {\n      \"locale\": \"nl\",\n      \"displayName\": \"Acme Corporation Autoriteit\",\n      \"description\": \"Uitgevende autoriteit voor verifieerbare credentials van Acme Corporation\"\n    }\n  ]\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"alias\": \"acme-authority\",\n  \"hostingMode\": \"LOCAL\",\n  \"bindings\": [\n    {\n      \"vct\": null,\n      \"vctHostingMode\": \"NONE\",\n      \"credentialConfigurationId\": null,\n      \"schemaId\": null,\n      \"docType\": null,\n      \"type\": null,\n      \"@context\": null,\n      \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n      \"issuerDid\": \"did:web:acme.example.com\",\n      \"issuerUri\": \"https://acme.example.com\",\n      \"verifierClientId\": null,\n      \"ocaSaid\": null,\n      \"credentialType\": null,\n      \"credentialDesignId\": null,\n      \"credentialDesignVersion\": null,\n      \"activeFrom\": null,\n      \"activeUntil\": null\n    }\n  ],\n  \"partyId\": null,\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"displayName\": \"Acme Corporation Authority\",\n      \"description\": \"Acme Corporation credential issuing authority\",\n      \"logo\": null\n    },\n    {\n      \"locale\": \"nl\",\n      \"displayName\": \"Acme Corporation Autoriteit\",\n      \"description\": \"Uitgevende autoriteit voor verifieerbare credentials van Acme Corporation\",\n      \"logo\": null\n    }\n  ],\n  \"renderVariantIds\": [],\n  \"sourceSnapshotIds\": [],\n  \"contentHash\": null,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Upload issuer logo asset",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials/{{issuerDesignId}}/assets/en/LOGO",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "image/png"
                  }
                ],
                "body": {
                  "mode": "file",
                  "file": {
                    "src": "fixtures/logo.png"
                  }
                },
                "description": "Uploads the binary PNG logo as raw application/octet-stream (Content-Type image/png) for this credential design. The response is an AssetReference whose uri is content-addressed (/public/assets/design/<sha256>.png) and whose integrity is sha256-<base64>. The captured uri/integrity are reused by the render variant(s) below so branding is hosted, de-duplicated by content hash, and SRI-verifiable. The runner mounts the file through its configured file resolver."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('02 Upload issuer logo asset succeeded', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const ref = pm.response.json();",
                      "pm.test('asset uri is content-addressed', () => pm.expect(ref.uri, 'uri').to.be.a('string').and.to.include('/public/assets/design/'));",
                      "pm.test('asset carries sha256 integrity', () => pm.expect(ref.integrity, 'integrity').to.be.a('string').and.to.match(/^sha256-/));",
                      "if (ref.uri) pm.collectionVariables.set('issuerLogoUri', ref.uri);",
                      "if (ref.integrity) pm.collectionVariables.set('issuerLogoIntegrity', ref.integrity);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/credentials/00000000-0000-4000-8000-000000000000/assets/en/LOGO",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "image/png"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n  \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n  \"altText\": null,\n  \"contentType\": \"image/png\",\n  \"localBlob\": {\n    \"storeId\": null,\n    \"path\": \"vc-designs/00000000-0000-4000-8000-000000000000/assets/by-hash/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"contentType\": null,\n    \"metadata\": {}\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Create issuer render variant",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/render/variants",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"issuer-card\",\n  \"localeApplicability\": [\n    \"en\",\n    \"nl\"\n  ],\n  \"backgroundColor\": \"#0B5FFF\",\n  \"textColor\": \"#FFFFFF\",\n  \"logo\": {\n    \"uri\": \"{{issuerLogoUri}}\",\n    \"integrity\": \"{{issuerLogoIntegrity}}\",\n    \"altText\": \"{{tenantName}} authority logo\"\n  }\n}"
                },
                "description": "SIMPLE_CARD render variant whose logo references the content-addressed asset uploaded above (uri + uri#integrity SRI), so the hosted branding path is exercised end-to-end."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('issuer render variant created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "if (j.id) pm.collectionVariables.set('issuerVariantId', j.id);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/render/variants",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"issuer-card\",\n  \"localeApplicability\": [\n    \"en\",\n    \"nl\"\n  ],\n  \"backgroundColor\": \"#0B5FFF\",\n  \"textColor\": \"#FFFFFF\",\n  \"logo\": {\n    \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n    \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n    \"altText\": \"Acme Corporation authority logo\"\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"issuer-card\",\n  \"localeApplicability\": [\n    \"en\",\n    \"nl\"\n  ],\n  \"sourceSnapshotId\": null,\n  \"logo\": {\n    \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n    \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n    \"altText\": \"Acme Corporation authority logo\",\n    \"contentType\": null,\n    \"localBlob\": null\n  },\n  \"backgroundImage\": null,\n  \"backgroundColor\": \"#0B5FFF\",\n  \"textColor\": \"#FFFFFF\",\n  \"accentColor\": null,\n  \"svgTemplate\": null,\n  \"w3cRenderMethod\": null,\n  \"pdfTemplate\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Attach render variant to issuer design",
              "request": {
                "method": "PUT",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/issuers/{{issuerDesignId}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"renderVariantIds\": [\n    \"{{issuerVariantId}}\"\n  ]\n}"
                },
                "description": "Attaches the freshly created render variant(s) to the credential design. Done as a follow-up PUT because the design must exist first to give the asset-upload endpoint a real {designId}, and the variants must exist before they can be referenced. Ordering: create design -> upload asset -> create variant(s) -> update design."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('issuer design updated with render variant', () => pm.expect([200, 201]).to.include(pm.response.code));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/issuers/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"renderVariantIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ]\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"alias\": \"acme-authority\",\n  \"hostingMode\": \"LOCAL\",\n  \"bindings\": [\n    {\n      \"vct\": null,\n      \"vctHostingMode\": \"NONE\",\n      \"credentialConfigurationId\": null,\n      \"schemaId\": null,\n      \"docType\": null,\n      \"type\": null,\n      \"@context\": null,\n      \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n      \"issuerDid\": \"did:web:acme.example.com\",\n      \"issuerUri\": \"https://acme.example.com\",\n      \"verifierClientId\": null,\n      \"ocaSaid\": null,\n      \"credentialType\": null,\n      \"credentialDesignId\": null,\n      \"credentialDesignVersion\": null,\n      \"activeFrom\": null,\n      \"activeUntil\": null\n    }\n  ],\n  \"partyId\": null,\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"displayName\": \"Acme Corporation Authority\",\n      \"description\": \"Acme Corporation credential issuing authority\",\n      \"logo\": null\n    },\n    {\n      \"locale\": \"nl\",\n      \"displayName\": \"Acme Corporation Autoriteit\",\n      \"description\": \"Uitgevende autoriteit voor verifieerbare credentials van Acme Corporation\",\n      \"logo\": null\n    }\n  ],\n  \"renderVariantIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"sourceSnapshotIds\": [],\n  \"contentHash\": null,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "11 Credential Designs",
          "description": "Creates the EuPid SD-JWT and Mdl mdoc credential designs, uploads branding assets, attaches render variants, and confirms the tenant can list the designs.\n\nDocumentation: https://docs.sphereon.com/edk/admin-console/guides/credential-designs",
          "item": [
            {
              "name": "01 Create EuPid SD-JWT design",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"bindings\": [\n    {\n      \"vct\": \"EuPid\",\n      \"vctHostingMode\": \"HOSTED\",\n      \"credentialConfigurationId\": \"EuPid\",\n      \"issuerUri\": \"{{tenantGatewayUrl}}\",\n      \"issuerId\": \"{{issuerId}}\"\n    }\n  ],\n  \"alias\": \"eu-pid\",\n  \"hostingMode\": \"LOCAL\",\n  \"credentialType\": {\n    \"format\": \"SD_JWT_VC\",\n    \"vct\": \"EuPid\"\n  },\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"EU Personal ID\",\n      \"description\": \"European personal identity credential\"\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"EU Persoonlijke ID\",\n      \"description\": \"Europese persoonlijke identiteitscredential\"\n    }\n  ],\n  \"claims\": [\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"family_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Family name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Achternaam\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 1,\n      \"sdPolicy\": \"ALWAYS\"\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"given_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Given name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Voornaam\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 2,\n      \"sdPolicy\": \"ALWAYS\"\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"birth_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Date of birth\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Geboortedatum\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 3\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"age_over_18\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Age over 18\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Ouder dan 18\"\n        }\n      ],\n      \"mandatory\": false,\n      \"order\": 4\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"nationality\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Nationality\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Nationaliteit\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 5\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_authority\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing authority\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Uitgevende autoriteit\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 6\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_country\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing country\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Land van uitgifte\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 7,\n      \"sdPolicy\": \"ALWAYS\"\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"document_number\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Document number\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Documentnummer\"\n        }\n      ],\n      \"mandatory\": false,\n      \"order\": 8\n    }\n  ]\n}"
                },
                "description": "EuPid credential design with English and Dutch displays, per-locale claim labels, and the en/nl render variants attached (both at the design level and as per-display preferred variants). family_name, given_name, and issuing_country are always selectively disclosable."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('eupid design created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "if (j.id) pm.collectionVariables.set('eupidDesignId', j.id);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/credentials",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"bindings\": [\n    {\n      \"vct\": \"EuPid\",\n      \"vctHostingMode\": \"HOSTED\",\n      \"credentialConfigurationId\": \"EuPid\",\n      \"issuerUri\": \"https://acme.example.com\",\n      \"issuerId\": \"00000000-0000-4000-8000-000000000000\"\n    }\n  ],\n  \"alias\": \"eu-pid\",\n  \"hostingMode\": \"LOCAL\",\n  \"credentialType\": {\n    \"format\": \"SD_JWT_VC\",\n    \"vct\": \"EuPid\"\n  },\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"EU Personal ID\",\n      \"description\": \"European personal identity credential\"\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"EU Persoonlijke ID\",\n      \"description\": \"Europese persoonlijke identiteitscredential\"\n    }\n  ],\n  \"claims\": [\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"family_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Family name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Achternaam\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 1,\n      \"sdPolicy\": \"ALWAYS\"\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"given_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Given name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Voornaam\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 2,\n      \"sdPolicy\": \"ALWAYS\"\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"birth_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Date of birth\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Geboortedatum\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 3\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"age_over_18\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Age over 18\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Ouder dan 18\"\n        }\n      ],\n      \"mandatory\": false,\n      \"order\": 4\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"nationality\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Nationality\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Nationaliteit\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 5\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_authority\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing authority\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Uitgevende autoriteit\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 6\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_country\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing country\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Land van uitgifte\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 7,\n      \"sdPolicy\": \"ALWAYS\"\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"document_number\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Document number\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Documentnummer\"\n        }\n      ],\n      \"mandatory\": false,\n      \"order\": 8\n    }\n  ]\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"alias\": \"eu-pid\",\n  \"hostingMode\": \"LOCAL\",\n  \"bindings\": [\n    {\n      \"vct\": \"EuPid\",\n      \"vctHostingMode\": \"HOSTED\",\n      \"credentialConfigurationId\": \"EuPid\",\n      \"schemaId\": null,\n      \"docType\": null,\n      \"type\": null,\n      \"@context\": null,\n      \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n      \"issuerDid\": null,\n      \"issuerUri\": \"https://acme.example.com\",\n      \"verifierClientId\": null,\n      \"ocaSaid\": null,\n      \"credentialType\": null,\n      \"credentialDesignId\": null,\n      \"credentialDesignVersion\": null,\n      \"activeFrom\": null,\n      \"activeUntil\": null\n    }\n  ],\n  \"credentialTemplateId\": null,\n  \"issuerDesignId\": null,\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"EU Personal ID\",\n      \"description\": \"European personal identity credential\",\n      \"issuerNameOverride\": null,\n      \"preferredRenderVariantIds\": []\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"EU Persoonlijke ID\",\n      \"description\": \"Europese persoonlijke identiteitscredential\",\n      \"issuerNameOverride\": null,\n      \"preferredRenderVariantIds\": []\n    }\n  ],\n  \"claims\": [\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"family_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Family name\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Achternaam\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALWAYS\",\n      \"order\": 1,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"given_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Given name\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Voornaam\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALWAYS\",\n      \"order\": 2,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"birth_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Date of birth\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Geboortedatum\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 3,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"age_over_18\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Age over 18\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Ouder dan 18\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": false,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 4,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"nationality\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Nationality\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Nationaliteit\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 5,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_authority\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing authority\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Uitgevende autoriteit\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 6,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_country\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing country\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Land van uitgifte\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALWAYS\",\n      \"order\": 7,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"document_number\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Document number\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Documentnummer\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": false,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 8,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    }\n  ],\n  \"renderVariantIds\": [],\n  \"derivedRenderHintsId\": null,\n  \"sourceSnapshotIds\": [],\n  \"contentHash\": null,\n  \"semanticAttributeSetRef\": {\n    \"bundleId\": \"credential-design:00000000-0000-4000-8000-000000000000\",\n    \"version\": \"00000000-0000-4000-8000-000000000000\"\n  },\n  \"attributeProfileId\": null,\n  \"attributeProfileVersion\": null,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\",\n  \"credentialType\": {\n    \"format\": \"SD_JWT_VC\",\n    \"vct\": \"EuPid\",\n    \"docType\": null,\n    \"type\": null,\n    \"@context\": null\n  },\n  \"deferral\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Upload EuPid logo asset",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials/{{eupidDesignId}}/assets/en/LOGO",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "image/png"
                  }
                ],
                "body": {
                  "mode": "file",
                  "file": {
                    "src": "fixtures/logo.png"
                  }
                },
                "description": "Uploads the binary PNG logo as raw application/octet-stream (Content-Type image/png) for this credential design. The response is an AssetReference whose uri is content-addressed (/public/assets/design/<sha256>.png) and whose integrity is sha256-<base64>. The captured uri/integrity are reused by the render variant(s) below so branding is hosted, de-duplicated by content hash, and SRI-verifiable. The runner mounts the file through its configured file resolver."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('02 Upload EuPid logo asset succeeded', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const ref = pm.response.json();",
                      "pm.test('asset uri is content-addressed', () => pm.expect(ref.uri, 'uri').to.be.a('string').and.to.include('/public/assets/design/'));",
                      "pm.test('asset carries sha256 integrity', () => pm.expect(ref.integrity, 'integrity').to.be.a('string').and.to.match(/^sha256-/));",
                      "if (ref.uri) pm.collectionVariables.set('eupidLogoUri', ref.uri);",
                      "if (ref.integrity) pm.collectionVariables.set('eupidLogoIntegrity', ref.integrity);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/credentials/00000000-0000-4000-8000-000000000000/assets/en/LOGO",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "image/png"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n  \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n  \"altText\": null,\n  \"contentType\": \"image/png\",\n  \"localBlob\": {\n    \"storeId\": null,\n    \"path\": \"vc-designs/00000000-0000-4000-8000-000000000000/assets/by-hash/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"contentType\": null,\n    \"metadata\": {}\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Create EuPid render variant (en)",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/render/variants",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"eupid-card-en\",\n  \"localeApplicability\": [\n    \"en\"\n  ],\n  \"backgroundColor\": \"#0B5FFF\",\n  \"textColor\": \"#FFFFFF\",\n  \"logo\": {\n    \"uri\": \"{{eupidLogoUri}}\",\n    \"integrity\": \"{{eupidLogoIntegrity}}\",\n    \"altText\": \"EU PID logo\"\n  }\n}"
                },
                "description": "SIMPLE_CARD render variant whose logo references the content-addressed asset uploaded above (uri + uri#integrity SRI), so the hosted branding path is exercised end-to-end."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('eupid en render variant created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "if (j.id) pm.collectionVariables.set('eupidVariantEnId', j.id);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/render/variants",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"eupid-card-en\",\n  \"localeApplicability\": [\n    \"en\"\n  ],\n  \"backgroundColor\": \"#0B5FFF\",\n  \"textColor\": \"#FFFFFF\",\n  \"logo\": {\n    \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n    \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n    \"altText\": \"EU PID logo\"\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"eupid-card-en\",\n  \"localeApplicability\": [\n    \"en\"\n  ],\n  \"sourceSnapshotId\": null,\n  \"logo\": {\n    \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n    \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n    \"altText\": \"EU PID logo\",\n    \"contentType\": null,\n    \"localBlob\": null\n  },\n  \"backgroundImage\": null,\n  \"backgroundColor\": \"#0B5FFF\",\n  \"textColor\": \"#FFFFFF\",\n  \"accentColor\": null,\n  \"svgTemplate\": null,\n  \"w3cRenderMethod\": null,\n  \"pdfTemplate\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Create EuPid render variant (nl)",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/render/variants",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"eupid-card-nl\",\n  \"localeApplicability\": [\n    \"nl\"\n  ],\n  \"backgroundColor\": \"#0B5FFF\",\n  \"textColor\": \"#FFFFFF\",\n  \"logo\": {\n    \"uri\": \"{{eupidLogoUri}}\",\n    \"integrity\": \"{{eupidLogoIntegrity}}\",\n    \"altText\": \"EU PID logo\"\n  }\n}"
                },
                "description": "SIMPLE_CARD render variant whose logo references the content-addressed asset uploaded above (uri + uri#integrity SRI), so the hosted branding path is exercised end-to-end."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('eupid nl render variant created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "if (j.id) pm.collectionVariables.set('eupidVariantNlId', j.id);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/render/variants",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"eupid-card-nl\",\n  \"localeApplicability\": [\n    \"nl\"\n  ],\n  \"backgroundColor\": \"#0B5FFF\",\n  \"textColor\": \"#FFFFFF\",\n  \"logo\": {\n    \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n    \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n    \"altText\": \"EU PID logo\"\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"eupid-card-nl\",\n  \"localeApplicability\": [\n    \"nl\"\n  ],\n  \"sourceSnapshotId\": null,\n  \"logo\": {\n    \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n    \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n    \"altText\": \"EU PID logo\",\n    \"contentType\": null,\n    \"localBlob\": null\n  },\n  \"backgroundImage\": null,\n  \"backgroundColor\": \"#0B5FFF\",\n  \"textColor\": \"#FFFFFF\",\n  \"accentColor\": null,\n  \"svgTemplate\": null,\n  \"w3cRenderMethod\": null,\n  \"pdfTemplate\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Attach render variants to EuPid design",
              "request": {
                "method": "PUT",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials/{{eupidDesignId}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"EU Personal ID\",\n      \"description\": \"European personal identity credential\",\n      \"preferredRenderVariantIds\": [\n        \"{{eupidVariantEnId}}\"\n      ]\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"EU Persoonlijke ID\",\n      \"description\": \"Europese persoonlijke identiteitscredential\",\n      \"preferredRenderVariantIds\": [\n        \"{{eupidVariantNlId}}\"\n      ]\n    }\n  ],\n  \"renderVariantIds\": [\n    \"{{eupidVariantEnId}}\",\n    \"{{eupidVariantNlId}}\"\n  ]\n}"
                },
                "description": "Attaches the freshly created render variant(s) to the credential design. Done as a follow-up PUT because the design must exist first to give the asset-upload endpoint a real {designId}, and the variants must exist before they can be referenced. Ordering: create design -> upload asset -> create variant(s) -> update design."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('eupid design updated with render variants', () => pm.expect([200, 201]).to.include(pm.response.code));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/credentials/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"EU Personal ID\",\n      \"description\": \"European personal identity credential\",\n      \"preferredRenderVariantIds\": [\n        \"00000000-0000-4000-8000-000000000000\"\n      ]\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"EU Persoonlijke ID\",\n      \"description\": \"Europese persoonlijke identiteitscredential\",\n      \"preferredRenderVariantIds\": [\n        \"00000000-0000-4000-8000-000000000000\"\n      ]\n    }\n  ],\n  \"renderVariantIds\": [\n    \"00000000-0000-4000-8000-000000000000\",\n    \"00000000-0000-4000-8000-000000000000\"\n  ]\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"alias\": \"eu-pid\",\n  \"hostingMode\": \"LOCAL\",\n  \"bindings\": [\n    {\n      \"vct\": \"EuPid\",\n      \"vctHostingMode\": \"HOSTED\",\n      \"credentialConfigurationId\": \"EuPid\",\n      \"schemaId\": null,\n      \"docType\": null,\n      \"type\": null,\n      \"@context\": null,\n      \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n      \"issuerDid\": null,\n      \"issuerUri\": \"https://acme.example.com\",\n      \"verifierClientId\": null,\n      \"ocaSaid\": null,\n      \"credentialType\": null,\n      \"credentialDesignId\": null,\n      \"credentialDesignVersion\": null,\n      \"activeFrom\": null,\n      \"activeUntil\": null\n    }\n  ],\n  \"credentialTemplateId\": null,\n  \"issuerDesignId\": null,\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"EU Personal ID\",\n      \"description\": \"European personal identity credential\",\n      \"issuerNameOverride\": null,\n      \"preferredRenderVariantIds\": [\n        \"00000000-0000-4000-8000-000000000000\"\n      ]\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"EU Persoonlijke ID\",\n      \"description\": \"Europese persoonlijke identiteitscredential\",\n      \"issuerNameOverride\": null,\n      \"preferredRenderVariantIds\": [\n        \"00000000-0000-4000-8000-000000000000\"\n      ]\n    }\n  ],\n  \"claims\": [\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"family_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Family name\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Achternaam\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALWAYS\",\n      \"order\": 1,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"given_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Given name\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Voornaam\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALWAYS\",\n      \"order\": 2,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"birth_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Date of birth\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Geboortedatum\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 3,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"age_over_18\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Age over 18\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Ouder dan 18\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": false,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 4,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"nationality\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Nationality\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Nationaliteit\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 5,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_authority\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing authority\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Uitgevende autoriteit\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 6,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_country\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing country\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Land van uitgifte\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALWAYS\",\n      \"order\": 7,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"document_number\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Document number\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Documentnummer\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": false,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 8,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    }\n  ],\n  \"renderVariantIds\": [\n    \"00000000-0000-4000-8000-000000000000\",\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"derivedRenderHintsId\": null,\n  \"sourceSnapshotIds\": [],\n  \"contentHash\": null,\n  \"semanticAttributeSetRef\": {\n    \"bundleId\": \"credential-design:00000000-0000-4000-8000-000000000000\",\n    \"version\": \"00000000-0000-4000-8000-000000000000\"\n  },\n  \"attributeProfileId\": null,\n  \"attributeProfileVersion\": null,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\",\n  \"credentialType\": {\n    \"format\": \"SD_JWT_VC\",\n    \"vct\": \"EuPid\",\n    \"docType\": null,\n    \"type\": null,\n    \"@context\": null\n  },\n  \"deferral\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 Create Mdl mdoc design",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"bindings\": [\n    {\n      \"docType\": \"org.iso.18013.5.1.mDL\",\n      \"credentialConfigurationId\": \"Mdl\",\n      \"issuerUri\": \"{{tenantGatewayUrl}}\",\n      \"issuerId\": \"{{issuerId}}\"\n    }\n  ],\n  \"alias\": \"mdl\",\n  \"hostingMode\": \"LOCAL\",\n  \"credentialType\": {\n    \"format\": \"MSO_MDOC\",\n    \"docType\": \"org.iso.18013.5.1.mDL\"\n  },\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"Mobile Driving Licence\",\n      \"description\": \"ISO 18013-5 mobile driving licence\"\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"Mobiel Rijbewijs\",\n      \"description\": \"ISO 18013-5 mobiel rijbewijs\"\n    }\n  ],\n  \"claims\": [\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"family_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Family name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Achternaam\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 1\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"given_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Given name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Voornaam\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 2\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"birth_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Date of birth\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Geboortedatum\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 3\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issue_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issue date\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Datum van uitgifte\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 4\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"expiry_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Expiry date\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Vervaldatum\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 5\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_country\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing country\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Land van uitgifte\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 6\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_authority\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing authority\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Uitgevende autoriteit\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 7\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"document_number\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Document number\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Documentnummer\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 8\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"portrait\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Portrait\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Portret\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 9\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"driving_privileges\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Driving privileges\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Rijbevoegdheden\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 10\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"un_distinguishing_sign\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"UN distinguishing sign\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"VN-onderscheidingsteken\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 11\n    }\n  ]\n}"
                },
                "description": "Mdl credential design with English and Dutch displays, per-locale claim labels under the org.iso.18013.5.1 namespace, and the en render variant attached."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('mdl design created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "if (j.id) pm.collectionVariables.set('mdlDesignId', j.id);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/credentials",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"bindings\": [\n    {\n      \"docType\": \"org.iso.18013.5.1.mDL\",\n      \"credentialConfigurationId\": \"Mdl\",\n      \"issuerUri\": \"https://acme.example.com\",\n      \"issuerId\": \"00000000-0000-4000-8000-000000000000\"\n    }\n  ],\n  \"alias\": \"mdl\",\n  \"hostingMode\": \"LOCAL\",\n  \"credentialType\": {\n    \"format\": \"MSO_MDOC\",\n    \"docType\": \"org.iso.18013.5.1.mDL\"\n  },\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"Mobile Driving Licence\",\n      \"description\": \"ISO 18013-5 mobile driving licence\"\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"Mobiel Rijbewijs\",\n      \"description\": \"ISO 18013-5 mobiel rijbewijs\"\n    }\n  ],\n  \"claims\": [\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"family_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Family name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Achternaam\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 1\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"given_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Given name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Voornaam\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 2\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"birth_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Date of birth\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Geboortedatum\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 3\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issue_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issue date\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Datum van uitgifte\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 4\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"expiry_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Expiry date\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Vervaldatum\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 5\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_country\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing country\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Land van uitgifte\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 6\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_authority\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing authority\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Uitgevende autoriteit\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 7\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"document_number\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Document number\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Documentnummer\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 8\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"portrait\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Portrait\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Portret\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 9\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"driving_privileges\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Driving privileges\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Rijbevoegdheden\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 10\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"un_distinguishing_sign\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"UN distinguishing sign\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"VN-onderscheidingsteken\"\n        }\n      ],\n      \"mandatory\": true,\n      \"order\": 11\n    }\n  ]\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"alias\": \"mdl\",\n  \"hostingMode\": \"LOCAL\",\n  \"bindings\": [\n    {\n      \"vct\": null,\n      \"vctHostingMode\": \"NONE\",\n      \"credentialConfigurationId\": \"Mdl\",\n      \"schemaId\": null,\n      \"docType\": \"org.iso.18013.5.1.mDL\",\n      \"type\": null,\n      \"@context\": null,\n      \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n      \"issuerDid\": null,\n      \"issuerUri\": \"https://acme.example.com\",\n      \"verifierClientId\": null,\n      \"ocaSaid\": null,\n      \"credentialType\": null,\n      \"credentialDesignId\": null,\n      \"credentialDesignVersion\": null,\n      \"activeFrom\": null,\n      \"activeUntil\": null\n    }\n  ],\n  \"credentialTemplateId\": null,\n  \"issuerDesignId\": null,\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"Mobile Driving Licence\",\n      \"description\": \"ISO 18013-5 mobile driving licence\",\n      \"issuerNameOverride\": null,\n      \"preferredRenderVariantIds\": []\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"Mobiel Rijbewijs\",\n      \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n      \"issuerNameOverride\": null,\n      \"preferredRenderVariantIds\": []\n    }\n  ],\n  \"claims\": [\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"family_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Family name\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Achternaam\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 1,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"given_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Given name\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Voornaam\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 2,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"birth_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Date of birth\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Geboortedatum\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 3,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issue_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issue date\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Datum van uitgifte\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 4,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"expiry_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Expiry date\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Vervaldatum\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 5,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_country\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing country\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Land van uitgifte\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 6,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_authority\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing authority\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Uitgevende autoriteit\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 7,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"document_number\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Document number\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Documentnummer\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 8,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"portrait\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Portrait\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Portret\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 9,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"driving_privileges\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Driving privileges\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Rijbevoegdheden\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 10,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"un_distinguishing_sign\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"UN distinguishing sign\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"VN-onderscheidingsteken\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 11,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    }\n  ],\n  \"renderVariantIds\": [],\n  \"derivedRenderHintsId\": null,\n  \"sourceSnapshotIds\": [],\n  \"contentHash\": null,\n  \"semanticAttributeSetRef\": {\n    \"bundleId\": \"credential-design:00000000-0000-4000-8000-000000000000\",\n    \"version\": \"00000000-0000-4000-8000-000000000000\"\n  },\n  \"attributeProfileId\": null,\n  \"attributeProfileVersion\": null,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\",\n  \"credentialType\": {\n    \"format\": \"MSO_MDOC\",\n    \"vct\": null,\n    \"docType\": \"org.iso.18013.5.1.mDL\",\n    \"type\": null,\n    \"@context\": null\n  },\n  \"deferral\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "07 Upload Mdl logo asset",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials/{{mdlDesignId}}/assets/en/LOGO",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "image/png"
                  }
                ],
                "body": {
                  "mode": "file",
                  "file": {
                    "src": "fixtures/logo.png"
                  }
                },
                "description": "Uploads the binary PNG logo as raw application/octet-stream (Content-Type image/png) for this credential design. The response is an AssetReference whose uri is content-addressed (/public/assets/design/<sha256>.png) and whose integrity is sha256-<base64>. The captured uri/integrity are reused by the render variant(s) below so branding is hosted, de-duplicated by content hash, and SRI-verifiable. The runner mounts the file through its configured file resolver."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('07 Upload Mdl logo asset succeeded', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const ref = pm.response.json();",
                      "pm.test('asset uri is content-addressed', () => pm.expect(ref.uri, 'uri').to.be.a('string').and.to.include('/public/assets/design/'));",
                      "pm.test('asset carries sha256 integrity', () => pm.expect(ref.integrity, 'integrity').to.be.a('string').and.to.match(/^sha256-/));",
                      "if (ref.uri) pm.collectionVariables.set('mdlLogoUri', ref.uri);",
                      "if (ref.integrity) pm.collectionVariables.set('mdlLogoIntegrity', ref.integrity);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/credentials/00000000-0000-4000-8000-000000000000/assets/en/LOGO",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "image/png"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n  \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n  \"altText\": null,\n  \"contentType\": \"image/png\",\n  \"localBlob\": {\n    \"storeId\": null,\n    \"path\": \"vc-designs/00000000-0000-4000-8000-000000000000/assets/by-hash/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"contentType\": null,\n    \"metadata\": {}\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "08 Create Mdl render variant (en)",
              "request": {
                "method": "POST",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/render/variants",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"mdl-card-en\",\n  \"localeApplicability\": [\n    \"en\"\n  ],\n  \"backgroundColor\": \"#1B5E20\",\n  \"textColor\": \"#FFFFFF\",\n  \"logo\": {\n    \"uri\": \"{{mdlLogoUri}}\",\n    \"integrity\": \"{{mdlLogoIntegrity}}\",\n    \"altText\": \"Mobile driving licence logo\"\n  }\n}"
                },
                "description": "SIMPLE_CARD render variant whose logo references the content-addressed asset uploaded above (uri + uri#integrity SRI), so the hosted branding path is exercised end-to-end."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('mdl en render variant created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "if (j.id) pm.collectionVariables.set('mdlVariantEnId', j.id);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/render/variants",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"mdl-card-en\",\n  \"localeApplicability\": [\n    \"en\"\n  ],\n  \"backgroundColor\": \"#1B5E20\",\n  \"textColor\": \"#FFFFFF\",\n  \"logo\": {\n    \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n    \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n    \"altText\": \"Mobile driving licence logo\"\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"kind\": \"SIMPLE_CARD\",\n  \"alias\": \"mdl-card-en\",\n  \"localeApplicability\": [\n    \"en\"\n  ],\n  \"sourceSnapshotId\": null,\n  \"logo\": {\n    \"uri\": \"/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n    \"integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n    \"altText\": \"Mobile driving licence logo\",\n    \"contentType\": null,\n    \"localBlob\": null\n  },\n  \"backgroundImage\": null,\n  \"backgroundColor\": \"#1B5E20\",\n  \"textColor\": \"#FFFFFF\",\n  \"accentColor\": null,\n  \"svgTemplate\": null,\n  \"w3cRenderMethod\": null,\n  \"pdfTemplate\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "09 Attach render variant to Mdl design",
              "request": {
                "method": "PUT",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials/{{mdlDesignId}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"Mobile Driving Licence\",\n      \"description\": \"ISO 18013-5 mobile driving licence\",\n      \"preferredRenderVariantIds\": [\n        \"{{mdlVariantEnId}}\"\n      ]\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"Mobiel Rijbewijs\",\n      \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n      \"preferredRenderVariantIds\": [\n        \"{{mdlVariantEnId}}\"\n      ]\n    }\n  ],\n  \"renderVariantIds\": [\n    \"{{mdlVariantEnId}}\"\n  ]\n}"
                },
                "description": "Attaches the freshly created render variant(s) to the credential design. Done as a follow-up PUT because the design must exist first to give the asset-upload endpoint a real {designId}, and the variants must exist before they can be referenced. Ordering: create design -> upload asset -> create variant(s) -> update design."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('mdl design updated with render variant', () => pm.expect([200, 201]).to.include(pm.response.code));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/credentials/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"Mobile Driving Licence\",\n      \"description\": \"ISO 18013-5 mobile driving licence\",\n      \"preferredRenderVariantIds\": [\n        \"00000000-0000-4000-8000-000000000000\"\n      ]\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"Mobiel Rijbewijs\",\n      \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n      \"preferredRenderVariantIds\": [\n        \"00000000-0000-4000-8000-000000000000\"\n      ]\n    }\n  ],\n  \"renderVariantIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ]\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"alias\": \"mdl\",\n  \"hostingMode\": \"LOCAL\",\n  \"bindings\": [\n    {\n      \"vct\": null,\n      \"vctHostingMode\": \"NONE\",\n      \"credentialConfigurationId\": \"Mdl\",\n      \"schemaId\": null,\n      \"docType\": \"org.iso.18013.5.1.mDL\",\n      \"type\": null,\n      \"@context\": null,\n      \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n      \"issuerDid\": null,\n      \"issuerUri\": \"https://acme.example.com\",\n      \"verifierClientId\": null,\n      \"ocaSaid\": null,\n      \"credentialType\": null,\n      \"credentialDesignId\": null,\n      \"credentialDesignVersion\": null,\n      \"activeFrom\": null,\n      \"activeUntil\": null\n    }\n  ],\n  \"credentialTemplateId\": null,\n  \"issuerDesignId\": null,\n  \"displays\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"Mobile Driving Licence\",\n      \"description\": \"ISO 18013-5 mobile driving licence\",\n      \"issuerNameOverride\": null,\n      \"preferredRenderVariantIds\": [\n        \"00000000-0000-4000-8000-000000000000\"\n      ]\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"Mobiel Rijbewijs\",\n      \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n      \"issuerNameOverride\": null,\n      \"preferredRenderVariantIds\": [\n        \"00000000-0000-4000-8000-000000000000\"\n      ]\n    }\n  ],\n  \"claims\": [\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"family_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Family name\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Achternaam\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 1,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"given_name\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Given name\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Voornaam\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 2,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"birth_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Date of birth\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Geboortedatum\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 3,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issue_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issue date\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Datum van uitgifte\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 4,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"expiry_date\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Expiry date\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Vervaldatum\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 5,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_country\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing country\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Land van uitgifte\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 6,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"issuing_authority\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing authority\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Uitgevende autoriteit\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 7,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"document_number\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Document number\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Documentnummer\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 8,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"portrait\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Portrait\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Portret\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 9,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"driving_privileges\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Driving privileges\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Rijbevoegdheden\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 10,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    },\n    {\n      \"path\": [\n        {\n          \"type\": \"property\",\n          \"name\": \"org.iso.18013.5.1\"\n        },\n        {\n          \"type\": \"property\",\n          \"name\": \"un_distinguishing_sign\"\n        }\n      ],\n      \"labels\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"UN distinguishing sign\",\n          \"description\": null,\n          \"entryValues\": null\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"VN-onderscheidingsteken\",\n          \"description\": null,\n          \"entryValues\": null\n        }\n      ],\n      \"mandatory\": true,\n      \"sdPolicy\": \"ALLOWED\",\n      \"order\": 11,\n      \"group\": null,\n      \"svgId\": null,\n      \"valueKind\": null,\n      \"widgetHint\": null,\n      \"markdownAllowed\": false,\n      \"entryCodes\": null,\n      \"unit\": null,\n      \"defaultValue\": null,\n      \"exampleValue\": null\n    }\n  ],\n  \"renderVariantIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"derivedRenderHintsId\": null,\n  \"sourceSnapshotIds\": [],\n  \"contentHash\": null,\n  \"semanticAttributeSetRef\": {\n    \"bundleId\": \"credential-design:00000000-0000-4000-8000-000000000000\",\n    \"version\": \"00000000-0000-4000-8000-000000000000\"\n  },\n  \"attributeProfileId\": null,\n  \"attributeProfileVersion\": null,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\",\n  \"credentialType\": {\n    \"format\": \"MSO_MDOC\",\n    \"vct\": null,\n    \"docType\": \"org.iso.18013.5.1.mDL\",\n    \"type\": null,\n    \"@context\": null\n  },\n  \"deferral\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "10 List credential designs",
              "request": {
                "method": "GET",
                "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials",
                "description": "Lists the tenant's credential designs.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('designs listed', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/credential-design/v1/designs/credentials",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "[\n  {\n    \"id\": \"00000000-0000-4000-8000-000000000000\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"alias\": \"eu-pid\",\n    \"hostingMode\": \"LOCAL\",\n    \"bindings\": [\n      {\n        \"vct\": \"EuPid\",\n        \"vctHostingMode\": \"HOSTED\",\n        \"credentialConfigurationId\": \"EuPid\",\n        \"schemaId\": null,\n        \"docType\": null,\n        \"type\": null,\n        \"@context\": null,\n        \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n        \"issuerDid\": null,\n        \"issuerUri\": \"https://acme.example.com/oid4vci/acme\",\n        \"verifierClientId\": null,\n        \"ocaSaid\": null,\n        \"credentialType\": null,\n        \"credentialDesignId\": null,\n        \"credentialDesignVersion\": null,\n        \"activeFrom\": null,\n        \"activeUntil\": null\n      }\n    ],\n    \"credentialTemplateId\": null,\n    \"issuerDesignId\": \"00000000-0000-4000-8000-000000000000\",\n    \"displays\": [\n      {\n        \"locale\": \"en\",\n        \"name\": \"EU Personal ID\",\n        \"description\": \"European personal identity credential\",\n        \"issuerNameOverride\": null,\n        \"preferredRenderVariantIds\": [\n          \"00000000-0000-4000-8000-000000000000\"\n        ]\n      },\n      {\n        \"locale\": \"nl\",\n        \"name\": \"EU Persoonlijke ID\",\n        \"description\": \"Europese persoonlijke identiteitscredential\",\n        \"issuerNameOverride\": null,\n        \"preferredRenderVariantIds\": [\n          \"00000000-0000-4000-8000-000000000000\"\n        ]\n      }\n    ],\n    \"claims\": [\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"family_name\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Family name\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Achternaam\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALWAYS\",\n        \"order\": 1,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"Doe\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"given_name\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Given name\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Voornaam\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALWAYS\",\n        \"order\": 2,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"Jane\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"birth_date\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Date of birth\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Geboortedatum\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 3,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"1990-01-15\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"age_over_18\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Age over 18\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Ouder dan 18\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": false,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 4,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"true\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"nationality\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Nationality\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Nationaliteit\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 5,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"NL\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"issuing_authority\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issuing authority\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Uitgevende autoriteit\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 6,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"Test Authority\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"issuing_country\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issuing country\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Land van uitgifte\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALWAYS\",\n        \"order\": 7,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"NL\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"document_number\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Document number\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Documentnummer\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": false,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 8,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"DOC-102938\"\n      }\n    ],\n    \"renderVariantIds\": [\n      \"00000000-0000-4000-8000-000000000000\",\n      \"00000000-0000-4000-8000-000000000000\"\n    ],\n    \"derivedRenderHintsId\": null,\n    \"sourceSnapshotIds\": [],\n    \"contentHash\": null,\n    \"semanticAttributeSetRef\": {\n      \"bundleId\": \"credential-design:00000000-0000-4000-8000-000000000000\",\n      \"version\": \"00000000-0000-4000-8000-000000000000\"\n    },\n    \"attributeProfileId\": null,\n    \"attributeProfileVersion\": null,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\",\n    \"credentialType\": {\n      \"format\": \"SD_JWT_VC\",\n      \"vct\": \"EuPid\",\n      \"docType\": null,\n      \"type\": null,\n      \"@context\": null\n    },\n    \"deferral\": null\n  },\n  {\n    \"id\": \"00000000-0000-4000-8000-000000000000\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"alias\": \"mdl\",\n    \"hostingMode\": \"LOCAL\",\n    \"bindings\": [\n      {\n        \"vct\": null,\n        \"vctHostingMode\": \"NONE\",\n        \"credentialConfigurationId\": \"Mdl\",\n        \"schemaId\": null,\n        \"docType\": \"org.iso.18013.5.1.mDL\",\n        \"type\": null,\n        \"@context\": null,\n        \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n        \"issuerDid\": null,\n        \"issuerUri\": \"https://acme.example.com/oid4vci/acme\",\n        \"verifierClientId\": null,\n        \"ocaSaid\": null,\n        \"credentialType\": null,\n        \"credentialDesignId\": null,\n        \"credentialDesignVersion\": null,\n        \"activeFrom\": null,\n        \"activeUntil\": null\n      }\n    ],\n    \"credentialTemplateId\": null,\n    \"issuerDesignId\": \"00000000-0000-4000-8000-000000000000\",\n    \"displays\": [\n      {\n        \"locale\": \"en\",\n        \"name\": \"Mobile Driving Licence\",\n        \"description\": \"ISO 18013-5 mobile driving licence\",\n        \"issuerNameOverride\": null,\n        \"preferredRenderVariantIds\": [\n          \"00000000-0000-4000-8000-000000000000\"\n        ]\n      },\n      {\n        \"locale\": \"nl\",\n        \"name\": \"Mobiel Rijbewijs\",\n        \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n        \"issuerNameOverride\": null,\n        \"preferredRenderVariantIds\": [\n          \"00000000-0000-4000-8000-000000000000\"\n        ]\n      }\n    ],\n    \"claims\": [\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"family_name\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Family name\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Achternaam\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 1,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"Doe\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"given_name\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Given name\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Voornaam\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 2,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"Jane\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"birth_date\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Date of birth\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Geboortedatum\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 3,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"1990-01-15\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"issue_date\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issue date\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Datum van uitgifte\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 4,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"2024-01-01\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"expiry_date\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Expiry date\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Vervaldatum\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 5,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"2030-01-01\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"issuing_country\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issuing country\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Land van uitgifte\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 6,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"NL\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"issuing_authority\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issuing authority\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Uitgevende autoriteit\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 7,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"Test Authority\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"document_number\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Document number\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Documentnummer\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 8,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"DOC-102938\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"portrait\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Portrait\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Portret\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 9,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"driving_privileges\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Driving privileges\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Rijbevoegdheden\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 10,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"[{\\\"vehicle_category_code\\\":\\\"B\\\",\\\"issue_date\\\":\\\"2024-01-01\\\",\\\"expiry_date\\\":\\\"2030-01-01\\\"}]\"\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"un_distinguishing_sign\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"UN distinguishing sign\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"VN-onderscheidingsteken\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 11,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": \"NL\"\n      }\n    ],\n    \"renderVariantIds\": [\n      \"00000000-0000-4000-8000-000000000000\"\n    ],\n    \"derivedRenderHintsId\": null,\n    \"sourceSnapshotIds\": [],\n    \"contentHash\": null,\n    \"semanticAttributeSetRef\": {\n      \"bundleId\": \"credential-design:00000000-0000-4000-8000-000000000000\",\n      \"version\": \"00000000-0000-4000-8000-000000000000\"\n    },\n    \"attributeProfileId\": null,\n    \"attributeProfileVersion\": null,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\",\n    \"credentialType\": {\n      \"format\": \"MSO_MDOC\",\n      \"vct\": null,\n      \"docType\": \"org.iso.18013.5.1.mDL\",\n      \"type\": null,\n      \"@context\": null\n    },\n    \"deferral\": null\n  },\n  {\n    \"id\": \"00000000-0000-4000-8000-000000000000\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"alias\": \"eu-pid\",\n    \"hostingMode\": \"LOCAL\",\n    \"bindings\": [\n      {\n        \"vct\": \"EuPid\",\n        \"vctHostingMode\": \"HOSTED\",\n        \"credentialConfigurationId\": \"EuPid\",\n        \"schemaId\": null,\n        \"docType\": null,\n        \"type\": null,\n        \"@context\": null,\n        \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n        \"issuerDid\": null,\n        \"issuerUri\": \"https://acme.example.com\",\n        \"verifierClientId\": null,\n        \"ocaSaid\": null,\n        \"credentialType\": null,\n        \"credentialDesignId\": null,\n        \"credentialDesignVersion\": null,\n        \"activeFrom\": null,\n        \"activeUntil\": null\n      }\n    ],\n    \"credentialTemplateId\": null,\n    \"issuerDesignId\": null,\n    \"displays\": [\n      {\n        \"locale\": \"en\",\n        \"name\": \"EU Personal ID\",\n        \"description\": \"European personal identity credential\",\n        \"issuerNameOverride\": null,\n        \"preferredRenderVariantIds\": [\n          \"00000000-0000-4000-8000-000000000000\"\n        ]\n      },\n      {\n        \"locale\": \"nl\",\n        \"name\": \"EU Persoonlijke ID\",\n        \"description\": \"Europese persoonlijke identiteitscredential\",\n        \"issuerNameOverride\": null,\n        \"preferredRenderVariantIds\": [\n          \"00000000-0000-4000-8000-000000000000\"\n        ]\n      }\n    ],\n    \"claims\": [\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"family_name\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Family name\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Achternaam\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALWAYS\",\n        \"order\": 1,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"given_name\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Given name\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Voornaam\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALWAYS\",\n        \"order\": 2,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"birth_date\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Date of birth\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Geboortedatum\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 3,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"age_over_18\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Age over 18\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Ouder dan 18\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": false,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 4,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"nationality\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Nationality\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Nationaliteit\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 5,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"issuing_authority\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issuing authority\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Uitgevende autoriteit\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 6,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"issuing_country\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issuing country\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Land van uitgifte\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALWAYS\",\n        \"order\": 7,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"document_number\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Document number\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Documentnummer\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": false,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 8,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      }\n    ],\n    \"renderVariantIds\": [\n      \"00000000-0000-4000-8000-000000000000\",\n      \"00000000-0000-4000-8000-000000000000\"\n    ],\n    \"derivedRenderHintsId\": null,\n    \"sourceSnapshotIds\": [],\n    \"contentHash\": null,\n    \"semanticAttributeSetRef\": {\n      \"bundleId\": \"credential-design:00000000-0000-4000-8000-000000000000\",\n      \"version\": \"00000000-0000-4000-8000-000000000000\"\n    },\n    \"attributeProfileId\": null,\n    \"attributeProfileVersion\": null,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\",\n    \"credentialType\": {\n      \"format\": \"SD_JWT_VC\",\n      \"vct\": \"EuPid\",\n      \"docType\": null,\n      \"type\": null,\n      \"@context\": null\n    },\n    \"deferral\": null\n  },\n  {\n    \"id\": \"00000000-0000-4000-8000-000000000000\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"alias\": \"mdl\",\n    \"hostingMode\": \"LOCAL\",\n    \"bindings\": [\n      {\n        \"vct\": null,\n        \"vctHostingMode\": \"NONE\",\n        \"credentialConfigurationId\": \"Mdl\",\n        \"schemaId\": null,\n        \"docType\": \"org.iso.18013.5.1.mDL\",\n        \"type\": null,\n        \"@context\": null,\n        \"issuerId\": \"00000000-0000-4000-8000-000000000000\",\n        \"issuerDid\": null,\n        \"issuerUri\": \"https://acme.example.com\",\n        \"verifierClientId\": null,\n        \"ocaSaid\": null,\n        \"credentialType\": null,\n        \"credentialDesignId\": null,\n        \"credentialDesignVersion\": null,\n        \"activeFrom\": null,\n        \"activeUntil\": null\n      }\n    ],\n    \"credentialTemplateId\": null,\n    \"issuerDesignId\": null,\n    \"displays\": [\n      {\n        \"locale\": \"en\",\n        \"name\": \"Mobile Driving Licence\",\n        \"description\": \"ISO 18013-5 mobile driving licence\",\n        \"issuerNameOverride\": null,\n        \"preferredRenderVariantIds\": [\n          \"00000000-0000-4000-8000-000000000000\"\n        ]\n      },\n      {\n        \"locale\": \"nl\",\n        \"name\": \"Mobiel Rijbewijs\",\n        \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n        \"issuerNameOverride\": null,\n        \"preferredRenderVariantIds\": [\n          \"00000000-0000-4000-8000-000000000000\"\n        ]\n      }\n    ],\n    \"claims\": [\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"family_name\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Family name\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Achternaam\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 1,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"given_name\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Given name\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Voornaam\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 2,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"birth_date\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Date of birth\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Geboortedatum\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 3,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"issue_date\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issue date\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Datum van uitgifte\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 4,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"expiry_date\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Expiry date\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Vervaldatum\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 5,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"issuing_country\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issuing country\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Land van uitgifte\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 6,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"issuing_authority\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Issuing authority\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Uitgevende autoriteit\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 7,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"document_number\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Document number\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Documentnummer\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 8,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"portrait\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Portrait\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Portret\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 9,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"driving_privileges\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"Driving privileges\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"Rijbevoegdheden\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 10,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      },\n      {\n        \"path\": [\n          {\n            \"type\": \"property\",\n            \"name\": \"org.iso.18013.5.1\"\n          },\n          {\n            \"type\": \"property\",\n            \"name\": \"un_distinguishing_sign\"\n          }\n        ],\n        \"labels\": [\n          {\n            \"locale\": \"en\",\n            \"label\": \"UN distinguishing sign\",\n            \"description\": null,\n            \"entryValues\": null\n          },\n          {\n            \"locale\": \"nl\",\n            \"label\": \"VN-onderscheidingsteken\",\n            \"description\": null,\n            \"entryValues\": null\n          }\n        ],\n        \"mandatory\": true,\n        \"sdPolicy\": \"ALLOWED\",\n        \"order\": 11,\n        \"group\": null,\n        \"svgId\": null,\n        \"valueKind\": null,\n        \"widgetHint\": null,\n        \"markdownAllowed\": false,\n        \"entryCodes\": null,\n        \"unit\": null,\n        \"defaultValue\": null,\n        \"exampleValue\": null\n      }\n    ],\n    \"renderVariantIds\": [\n      \"00000000-0000-4000-8000-000000000000\"\n    ],\n    \"derivedRenderHintsId\": null,\n    \"sourceSnapshotIds\": [],\n    \"contentHash\": null,\n    \"semanticAttributeSetRef\": {\n      \"bundleId\": \"credential-design:00000000-0000-4000-8000-000000000000\",\n      \"version\": \"00000000-0000-4000-8000-000000000000\"\n    },\n    \"attributeProfileId\": null,\n    \"attributeProfileVersion\": null,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\",\n    \"credentialType\": {\n      \"format\": \"MSO_MDOC\",\n      \"vct\": null,\n      \"docType\": \"org.iso.18013.5.1.mDL\",\n      \"type\": null,\n      \"@context\": null\n    },\n    \"deferral\": null\n  }\n]",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "12 Status Lists",
          "description": "Creates the EuPid token status list, verifies the hosted status-list token, updates an entry, reactivates it, and reads the resulting entry state.\n\nDocumentation: https://docs.sphereon.com/edk/admin-console/guides/status-lists-and-revocation",
          "item": [
            {
              "name": "00a Resolve EuPid DID signing selection",
              "request": {
                "method": "GET",
                "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{tenantId}}/oid4vci/issuer/instances/{{issuerId}}/credential-config-settings/EuPid",
                "description": "Reads the provisioned EuPid signing configuration so status-list creation selects the exact KMS resource, key, and DID assertionMethod instead of a generic DID method.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('EuPid signing configuration returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const body = pm.response.json();",
                      "const j = body.data || body;",
                      "pm.test('EuPid carries an exact DID signing selection', () => {",
                      "  pm.expect(j.signingKeyMode).to.match(/^did:/);",
                      "  pm.expect(j.kmsResourceHandle).to.match(/^krh_[A-Za-z0-9_-]+$/);",
                      "  pm.expect(j.kmsKeyAlias).to.be.a('string').and.not.empty;",
                      "  pm.expect(j.signingVerificationMethodId).to.match(/^did:[^#]+#.+$/);",
                      "});",
                      "// W3C VCDM credentials and the bitstring status list must both be signed by the tenant's own",
                      "// did:web assertion key. This selection is read from the SD-JWT VC configuration, so pin it to",
                      "// the tenant DID: if that configuration ever moves to another key, fail here rather than sign",
                      "// the bitstring status list with an identity the VCDM credentials do not use.",
                      "pm.test('the DID signing selection belongs to the tenant did:web', () => {",
                      "  const tenantDid = pm.collectionVariables.get('did');",
                      "  pm.expect(tenantDid, 'the tenant DID must be resolved before the status lists').to.be.a('string').and.not.empty;",
                      "  pm.expect(String(j.signingVerificationMethodId).split('#')[0]).to.eql(tenantDid);",
                      "});",
                      "pm.collectionVariables.set('statusListDidKmsResourceHandle', j.kmsResourceHandle);",
                      "pm.collectionVariables.set('statusListDidKmsKeyAlias', j.kmsKeyAlias);",
                      "pm.collectionVariables.set('statusListDidVerificationMethodId', j.signingVerificationMethodId);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://platform.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vci/issuer/instances/00000000-0000-4000-8000-000000000000/credential-config-settings/EuPid",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"EuPid\",\n  \"format\": \"dc+sd-jwt\",\n  \"scope\": \"eu_pid\",\n  \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n  \"cryptographicBindingMethodsSupported\": [\n    \"jwk\",\n    \"did:jwk\",\n    \"did:key\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"did:web:acme.example.com#issuer-assertion-acme\",\n  \"status\": {\n    \"statusListId\": \"eupid-revocation\",\n    \"purpose\": \"revocation\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "00b Resolve mDL X.509 signing selection",
              "request": {
                "method": "GET",
                "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{tenantId}}/oid4vci/issuer/instances/{{issuerId}}/credential-config-settings/Mdl",
                "description": "Reads the provisioned mDL signing configuration and reuses its exact X.509-backed KMS key for the certificate-signed status-list verification case.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('mDL signing configuration returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const body = pm.response.json();",
                      "const j = body.data || body;",
                      "pm.test('mDL carries an exact X.509 signing selection', () => {",
                      "  pm.expect(j.signingKeyMode).to.eql('x5c');",
                      "  pm.expect(j.kmsResourceHandle).to.match(/^krh_[A-Za-z0-9_-]+$/);",
                      "  pm.expect(j.kmsKeyAlias).to.be.a('string').and.not.empty;",
                      "  pm.expect(j.kmsResourceHandle, 'mDL uses the provisioned tenant KMS').to.eql(pm.collectionVariables.get('kmsResourceHandle'));",
                      "  pm.expect(pm.collectionVariables.get('kmsResourceKind'), 'mDL uses the Software KMS').to.eql('SOFTWARE');",
                      "});",
                      "pm.collectionVariables.set('statusListX509KmsResourceHandle', j.kmsResourceHandle);",
                      "pm.collectionVariables.set('statusListX509KmsKeyAlias', j.kmsKeyAlias);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://platform.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vci/issuer/instances/00000000-0000-4000-8000-000000000000/credential-config-settings/Mdl",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"Mdl\",\n  \"format\": \"mso_mdoc\",\n  \"scope\": \"mdl\",\n  \"docType\": \"org.iso.18013.5.1.mDL\",\n  \"cryptographicBindingMethodsSupported\": [\n    \"cose_key\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"x5c\",\n  \"status\": {\n    \"statusListId\": \"mdoc-revocation\",\n    \"purpose\": \"revocation\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "01 Create token status list",
              "request": {
                "method": "POST",
                "url": "{{tenantStatusListApiBaseUrl}}/statuslists",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"correlationId\": \"walkthrough-revocation\",\n  \"spec\": \"token_status_list\",\n  \"proofFormat\": \"jwt\",\n  \"issuer\": \"{{did}}\",\n  \"signingKeyMode\": \"did:web\",\n  \"kmsResourceHandle\": \"{{statusListDidKmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"{{statusListDidKmsKeyAlias}}\",\n  \"signingVerificationMethodId\": \"{{statusListDidVerificationMethodId}}\",\n  \"statusListUri\": \"{{tenantGatewayUrl}}/public/statuslists/walkthrough-revocation\",\n  \"purposes\": [\"revocation\"],\n  \"length\": 131072,\n  \"bitsPerStatus\": 1\n}"
                },
                "description": "Creates the IETF Token Status List referenced by the EuPid configuration with its exact provisioned KMS resource, key alias, and DID assertionMethod. The platform authority owns that selection; the issuer validates it and does not rewrite tenant configuration."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('status list created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "if (j.id) pm.collectionVariables.set('statusListId', j.id);",
                      "if (j.statusListUri) pm.collectionVariables.set('statusListUri', j.statusListUri);",
                      "if (!pm.collectionVariables.get('statusListUri')) pm.collectionVariables.set('statusListUri', pm.variables.get('tenantGatewayUrl') + '/public/statuslists/walkthrough-revocation');",
                      "const decodeJwtPart = (jwt, index) => {",
                      "  const compact = String(jwt || '').split('~')[0];",
                      "  const segment = compact.split('.')[index];",
                      "  pm.expect(segment, 'jwt segment ' + index).to.be.a('string').and.not.empty;",
                      "  const normalized = segment.replace(/-/g, '+').replace(/_/g, '/');",
                      "  const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);",
                      "  return JSON.parse(atob(padded));",
                      "};",
                      "pm.test('status list response matches EuPid revocation contract', () => {",
                      "  pm.expect(j.correlationId).to.eql('walkthrough-revocation');",
                      "  pm.expect(j.spec).to.eql('token_status_list');",
                      "  pm.expect(j.proofFormat).to.eql('jwt');",
                      "  pm.expect(j.bitsPerStatus).to.eql(1);",
                      "  pm.expect(j.statusListUri).to.eql(pm.variables.get('tenantGatewayUrl') + '/public/statuslists/walkthrough-revocation');",
                      "  pm.expect(j.contentType).to.eql('application/statuslist+jwt');",
                      "});",
                      "if (j.signedToken) {",
                      "  const header = decodeJwtPart(j.signedToken, 0);",
                      "  const payload = decodeJwtPart(j.signedToken, 1);",
                      "  pm.test('status list signed token claims match hosted list', () => {",
                      "    pm.expect(header.typ).to.eql('statuslist+jwt');",
                      "    pm.expect(header.kid, 'absolute DID verification-method kid').to.be.a('string').and.not.empty;",
                      "    pm.expect(header.kid.startsWith(pm.variables.get('did') + '#')).to.eql(true);",
                      "    pm.expect(header).not.to.have.property('x5c');",
                      "    pm.expect(payload.iss).to.eql(pm.variables.get('did'));",
                      "    pm.expect(payload.sub).to.eql(pm.collectionVariables.get('statusListUri'));",
                      "    pm.expect(payload.status_list && payload.status_list.bits).to.eql(1);",
                      "    pm.expect(payload.status_list && payload.status_list.lst).to.be.a('string').and.not.empty;",
                      "  });",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/statuslist/v1/statuslists",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"correlationId\": \"walkthrough-revocation\",\n  \"spec\": \"token_status_list\",\n  \"proofFormat\": \"jwt\",\n  \"issuer\": \"did:web:acme.example.com\",\n  \"signingKeyMode\": \"did:web\",\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingVerificationMethodId\": \"did:web:acme.example.com#issuer-assertion-acme\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/walkthrough-revocation\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"length\": 131072,\n  \"bitsPerStatus\": 1\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"correlationId\": \"walkthrough-revocation\",\n  \"spec\": \"token_status_list\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"proofFormat\": \"jwt\",\n  \"hostingMode\": \"hosted\",\n  \"bitsPerStatus\": 1,\n  \"length\": 131072,\n  \"issuer\": \"did:web:acme.example.com\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/walkthrough-revocation\",\n  \"signedToken\": \"eyJ0eXAiOiJzdGF0dXNsaXN0K2p3dCIsImFsZyI6IkVTMjU2Iiwia2lkIjoiZGlkOndlYjphY21lLmV4YW1wbGUuY29tI2lzc3Vlci1hc3NlcnRpb24tYWNtZSJ9.eyJpc3MiOiJkaWQ6d2ViOmFjbWUuZXhhbXBsZS5jb20iLCJzdWIiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL3dhbGt0aHJvdWdoLXJldm9jYXRpb24iLCJpYXQiOjE3NjcyMjU2MDAsInN0YXR1c19saXN0Ijp7ImJpdHMiOjEsImxzdCI6Ijxjb21wcmVzc2VkLXN0YXR1cy1saXN0PiJ9fQ.SIGNATURE-REDACTED\",\n  \"signedToken_decoded\": {\n    \"header\": {\n      \"typ\": \"statuslist+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"did:web:acme.example.com\",\n      \"sub\": \"https://acme.example.com/public/statuslists/walkthrough-revocation\",\n      \"iat\": 1767225600,\n      \"status_list\": {\n        \"bits\": 1,\n        \"lst\": \"<compressed-status-list>\"\n      }\n    }\n  },\n  \"contentType\": \"application/statuslist+jwt\",\n  \"mdocProfile\": null,\n  \"aggregationUri\": null,\n  \"validUntil\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 List status lists",
              "request": {
                "method": "GET",
                "url": "{{tenantStatusListApiBaseUrl}}/statuslists",
                "description": "Lists status lists for the tenant after materializing the EuPid revocation list.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('status lists returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const lists = Array.isArray(j) ? j : (j.data || j.items || []);",
                      "const expectedUri = pm.variables.get('tenantGatewayUrl') + '/public/statuslists/eupid-revocation';",
                      "const statusList = lists.find((entry) => entry.correlationId === 'eupid-revocation' || entry.statusListUri === expectedUri);",
                      "pm.test('EuPid revocation status list visible', () => {",
                      "  pm.expect(statusList, 'eupid-revocation status list').to.be.an('object');",
                      "  pm.expect(statusList.id, 'status list id').to.be.a('string').and.not.empty;",
                      "});",
                      "if (statusList && statusList.id) pm.collectionVariables.set('statusListId', statusList.id);",
                      "if (statusList) pm.collectionVariables.set('statusListUri', statusList.statusListUri || expectedUri);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/statuslist/v1/statuslists",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"data\": [\n    {\n      \"id\": \"00000000-0000-4000-8000-000000000000\",\n      \"correlationId\": \"walkthrough-revocation\",\n      \"spec\": \"token_status_list\",\n      \"purposes\": [\n        \"revocation\"\n      ],\n      \"proofFormat\": \"jwt\",\n      \"hostingMode\": \"hosted\",\n      \"bitsPerStatus\": 1,\n      \"length\": 131072,\n      \"issuedCount\": 0,\n      \"remainingCapacity\": 131072,\n      \"createdAt\": \"2026-01-01T00:00:00Z\",\n      \"updatedAt\": \"2026-01-01T00:00:00Z\",\n      \"mdocProfile\": null,\n      \"aggregationUri\": null\n    },\n    {\n      \"id\": \"00000000-0000-4000-8000-000000000000\",\n      \"correlationId\": \"eupid-revocation\",\n      \"spec\": \"token_status_list\",\n      \"purposes\": [\n        \"revocation\"\n      ],\n      \"proofFormat\": \"jwt\",\n      \"hostingMode\": \"hosted\",\n      \"bitsPerStatus\": 1,\n      \"length\": 131072,\n      \"issuedCount\": 0,\n      \"remainingCapacity\": 131072,\n      \"createdAt\": \"2026-01-01T00:00:00Z\",\n      \"updatedAt\": \"2026-01-01T00:00:00Z\",\n      \"mdocProfile\": null,\n      \"aggregationUri\": null\n    }\n  ],\n  \"pagination\": {\n    \"limit\": 20,\n    \"offset\": 0,\n    \"page\": 0,\n    \"size\": 20,\n    \"total\": 2,\n    \"totalPages\": 1,\n    \"hasMore\": false\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Get token status list",
              "request": {
                "method": "GET",
                "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{statusListId}}",
                "description": "Reads back the created status list through the management API before checking the hosted token.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('status list returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "pm.expect(pm.response.text(), 'created status list id').to.include(pm.collectionVariables.get('statusListId'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/statuslist/v1/statuslists/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"correlationId\": \"eupid-revocation\",\n  \"spec\": \"token_status_list\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"proofFormat\": \"jwt\",\n  \"hostingMode\": \"hosted\",\n  \"bitsPerStatus\": 1,\n  \"length\": 131072,\n  \"issuer\": \"did:web:acme.example.com\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/eupid-revocation\",\n  \"signedToken\": \"eyJ0eXAiOiJzdGF0dXNsaXN0K2p3dCIsImFsZyI6IkVTMjU2Iiwia2lkIjoiZGlkOndlYjphY21lLmV4YW1wbGUuY29tI2lzc3Vlci1hc3NlcnRpb24tYWNtZSJ9.eyJpc3MiOiJkaWQ6d2ViOmFjbWUuZXhhbXBsZS5jb20iLCJzdWIiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL2V1cGlkLXJldm9jYXRpb24iLCJpYXQiOjE3NjcyMjU2MDAsInR0bCI6MzAwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiI8Y29tcHJlc3NlZC1zdGF0dXMtbGlzdD4ifX0.SIGNATURE-REDACTED\",\n  \"signedToken_decoded\": {\n    \"header\": {\n      \"typ\": \"statuslist+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"did:web:acme.example.com\",\n      \"sub\": \"https://acme.example.com/public/statuslists/eupid-revocation\",\n      \"iat\": 1767225600,\n      \"ttl\": 300,\n      \"status_list\": {\n        \"bits\": 1,\n        \"lst\": \"<compressed-status-list>\"\n      }\n    }\n  },\n  \"contentType\": \"application/statuslist+jwt\",\n  \"mdocProfile\": null,\n  \"aggregationUri\": null,\n  \"validUntil\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Fetch hosted status list token",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [],
                "url": "{{statusListUri}}",
                "description": "Fetches the signed status list token from the public hosting surface using the API-returned statusListUri. Verifiers dereference exactly this URL when checking credential status."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('status list hosted', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const decodeJwtPart = (jwt, index) => {",
                      "  const compact = String(jwt || '').split('~')[0];",
                      "  const segment = compact.split('.')[index];",
                      "  pm.expect(segment, 'jwt segment ' + index).to.be.a('string').and.not.empty;",
                      "  const normalized = segment.replace(/-/g, '+').replace(/_/g, '/');",
                      "  const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);",
                      "  return JSON.parse(atob(padded));",
                      "};",
                      "const hostedStatusToken = pm.response.text().trim();",
                      "const hostedHeader = decodeJwtPart(hostedStatusToken, 0);",
                      "const hostedPayload = decodeJwtPart(hostedStatusToken, 1);",
                      "pm.test('hosted status list has statuslist JWT media type and claims', () => {",
                      "  pm.expect(pm.response.headers.get('Content-Type') || '', 'content type').to.include('application/statuslist+jwt');",
                      "  pm.expect(hostedHeader.typ).to.eql('statuslist+jwt');",
                      "  pm.expect(hostedHeader.kid, 'absolute DID verification-method kid').to.be.a('string').and.not.empty;",
                      "  pm.expect(hostedHeader.kid.startsWith(pm.variables.get('did') + '#'), 'kid ' + hostedHeader.kid + ' starts with did ' + pm.variables.get('did')).to.eql(true);",
                      "  pm.expect(hostedHeader).not.to.have.property('x5c');",
                      "  pm.expect(hostedPayload.iss).to.eql(pm.variables.get('did'));",
                      "  const subGatewayOrigin = String(pm.variables.get('tenantGatewayUrl') || '').replace(/\\/$/, '');",
                      "pm.expect(hostedPayload.sub, 'sub is the hosted list URI on the tenant gateway').to.be.a('string');",
                      "pm.expect(hostedPayload.sub.startsWith(subGatewayOrigin), 'sub ' + hostedPayload.sub + ' starts with ' + subGatewayOrigin).to.eql(true);",
                      "pm.expect(hostedPayload.sub.endsWith('/public/statuslists/eupid-revocation'), 'sub ' + hostedPayload.sub + ' names the eupid-revocation list').to.eql(true);",
                      "  pm.expect(hostedPayload.status_list && hostedPayload.status_list.bits).to.eql(1);",
                      "  pm.expect(hostedPayload.status_list && hostedPayload.status_list.lst).to.be.a('string').and.not.empty;",
                      "});",
                      "pm.collectionVariables.set('statusListSignerDid', hostedPayload.iss || '');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/public/statuslists/eupid-revocation",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/statuslist+jwt"
                    }
                  ],
                  "body": "{\n  \"_raw\": \"eyJ0eXAiOiJzdGF0dXNsaXN0K2p3dCIsImFsZyI6IkVTMjU2Iiwia2lkIjoiZGlkOndlYjphY21lLmV4YW1wbGUuY29tI2lzc3Vlci1hc3NlcnRpb24tYWNtZSJ9.eyJpc3MiOiJkaWQ6d2ViOmFjbWUuZXhhbXBsZS5jb20iLCJzdWIiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL2V1cGlkLXJldm9jYXRpb24iLCJpYXQiOjE3NjcyMjU2MDAsInR0bCI6MzAwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiI8Y29tcHJlc3NlZC1zdGF0dXMtbGlzdD4ifX0.SIGNATURE-REDACTED\",\n  \"_decoded\": {\n    \"header\": {\n      \"typ\": \"statuslist+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"did:web:acme.example.com\",\n      \"sub\": \"https://acme.example.com/public/statuslists/eupid-revocation\",\n      \"iat\": 1767225600,\n      \"ttl\": 300,\n      \"status_list\": {\n        \"bits\": 1,\n        \"lst\": \"<compressed-status-list>\"\n      }\n    }\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04a Create X.509 token status list",
              "request": {
                "method": "POST",
                "url": "{{tenantStatusListApiBaseUrl}}/statuslists",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"correlationId\": \"x509-revocation\",\n  \"spec\": \"token_status_list\",\n  \"proofFormat\": \"jwt\",\n  \"issuer\": \"{{tenantGatewayUrl}}\",\n  \"signingKeyMode\": \"x5c\",\n  \"kmsResourceHandle\": \"{{statusListX509KmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"{{statusListX509KmsKeyAlias}}\",\n  \"statusListUri\": \"{{tenantGatewayUrl}}/public/statuslists/x509-revocation\",\n  \"purposes\": [\"revocation\"],\n  \"length\": 131072,\n  \"bitsPerStatus\": 1\n}"
                },
                "description": "Creates a second Token Status List using the X.509 public trust mechanism. The server-owned signing key must carry a certificate chain; the protected JWS header uses x5c and deliberately omits kid."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('X.509 status list created or already provisioned', () => pm.expect([200, 201, 409]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "if (j.id) pm.collectionVariables.set('x5cStatusListId', j.id);",
                      "if (j.statusListUri) pm.collectionVariables.set('x5cStatusListUri', j.statusListUri);",
                      "if (!pm.collectionVariables.get('x5cStatusListUri')) pm.collectionVariables.set('x5cStatusListUri', pm.variables.get('tenantGatewayUrl') + '/public/statuslists/x509-revocation');",
                      "const decodeJwtPart = (jwt, index) => {",
                      "  const compact = String(jwt || '').split('~')[0];",
                      "  const segment = compact.split('.')[index];",
                      "  pm.expect(segment, 'jwt segment ' + index).to.be.a('string').and.not.empty;",
                      "  const normalized = segment.replace(/-/g, '+').replace(/_/g, '/');",
                      "  const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);",
                      "  return JSON.parse(atob(padded));",
                      "};",
                      "if (j.signedToken) {",
                      "  const header = decodeJwtPart(j.signedToken, 0);",
                      "  const payload = decodeJwtPart(j.signedToken, 1);",
                      "  pm.test('X.509 status list response uses x5c without kid', () => {",
                      "    pm.expect(header.typ).to.eql('statuslist+jwt');",
                      "    pm.expect(header.x5c, 'certificate chain').to.be.an('array').and.not.empty;",
                      "    pm.expect(header.x5c[0]).to.be.a('string').and.not.empty;",
                      "    pm.expect(header).not.to.have.property('kid');",
                      "    pm.expect(payload.iss).to.eql(pm.variables.get('tenantGatewayUrl'));",
                      "    pm.expect(payload.sub).to.eql(pm.collectionVariables.get('x5cStatusListUri'));",
                      "  });",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/statuslist/v1/statuslists",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"correlationId\": \"x509-revocation\",\n  \"spec\": \"token_status_list\",\n  \"proofFormat\": \"jwt\",\n  \"issuer\": \"https://acme.example.com\",\n  \"signingKeyMode\": \"x5c\",\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/x509-revocation\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"length\": 131072,\n  \"bitsPerStatus\": 1\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"correlationId\": \"x509-revocation\",\n  \"spec\": \"token_status_list\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"proofFormat\": \"jwt\",\n  \"hostingMode\": \"hosted\",\n  \"bitsPerStatus\": 1,\n  \"length\": 131072,\n  \"issuer\": \"https://acme.example.com\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/x509-revocation\",\n  \"signedToken\": \"eyJ0eXAiOiJzdGF0dXNsaXN0K2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiPHB1YmxpYy1rZXktbWF0ZXJpYWw-IiwieDVjIjpbIjxjZXJ0aWZpY2F0ZT4iXSwieSI6IjxwdWJsaWMta2V5LW1hdGVyaWFsPiJ9LCJ4NWMiOlsiPGNlcnRpZmljYXRlPiJdfQ.eyJpc3MiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20iLCJzdWIiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL3g1MDktcmV2b2NhdGlvbiIsImlhdCI6MTc2NzIyNTYwMCwic3RhdHVzX2xpc3QiOnsiYml0cyI6MSwibHN0IjoiPGNvbXByZXNzZWQtc3RhdHVzLWxpc3Q-In19.SIGNATURE-REDACTED\",\n  \"signedToken_decoded\": {\n    \"header\": {\n      \"typ\": \"statuslist+jwt\",\n      \"alg\": \"ES256\",\n      \"jwk\": {\n        \"crv\": \"P-256\",\n        \"kty\": \"EC\",\n        \"x\": \"<public-key-material>\",\n        \"x5c\": [\n          \"<certificate>\"\n        ],\n        \"y\": \"<public-key-material>\"\n      },\n      \"x5c\": [\n        \"<certificate>\"\n      ]\n    },\n    \"payload\": {\n      \"iss\": \"https://acme.example.com\",\n      \"sub\": \"https://acme.example.com/public/statuslists/x509-revocation\",\n      \"iat\": 1767225600,\n      \"status_list\": {\n        \"bits\": 1,\n        \"lst\": \"<compressed-status-list>\"\n      }\n    }\n  },\n  \"contentType\": \"application/statuslist+jwt\",\n  \"mdocProfile\": null,\n  \"aggregationUri\": null,\n  \"validUntil\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04b Fetch hosted X.509 status list token",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [],
                "url": "{{x5cStatusListUri}}",
                "description": "Fetches the hosted X.509-signed status-list token and verifies its protected signer-identification header independently of the create response."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('X.509 status list hosted', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const decodeJwtPart = (jwt, index) => {",
                      "  const compact = String(jwt || '').split('~')[0];",
                      "  const segment = compact.split('.')[index];",
                      "  pm.expect(segment, 'jwt segment ' + index).to.be.a('string').and.not.empty;",
                      "  const normalized = segment.replace(/-/g, '+').replace(/_/g, '/');",
                      "  const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);",
                      "  return JSON.parse(atob(padded));",
                      "};",
                      "const token = pm.response.text().trim();",
                      "const header = decodeJwtPart(token, 0);",
                      "const payload = decodeJwtPart(token, 1);",
                      "pm.test('hosted X.509 status list uses x5c without kid', () => {",
                      "  pm.expect(pm.response.headers.get('Content-Type') || '', 'content type').to.include('application/statuslist+jwt');",
                      "  pm.expect(header.typ).to.eql('statuslist+jwt');",
                      "  pm.expect(header.x5c, 'certificate chain').to.be.an('array').and.not.empty;",
                      "  pm.expect(header.x5c[0]).to.be.a('string').and.not.empty;",
                      "  pm.expect(header).not.to.have.property('kid');",
                      "  pm.expect(payload.iss).to.eql(pm.variables.get('tenantGatewayUrl'));",
                      "  pm.expect(payload.sub).to.eql(pm.collectionVariables.get('x5cStatusListUri'));",
                      "  pm.expect(payload.status_list && payload.status_list.bits).to.eql(1);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/public/statuslists/x509-revocation",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/statuslist+jwt"
                    }
                  ],
                  "body": "{\n  \"_raw\": \"eyJ0eXAiOiJzdGF0dXNsaXN0K2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7ImNydiI6IlAtMjU2Iiwia3R5IjoiRUMiLCJ4IjoiPHB1YmxpYy1rZXktbWF0ZXJpYWw-IiwieDVjIjpbIjxjZXJ0aWZpY2F0ZT4iXSwieSI6IjxwdWJsaWMta2V5LW1hdGVyaWFsPiJ9LCJ4NWMiOlsiPGNlcnRpZmljYXRlPiJdfQ.eyJpc3MiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20iLCJzdWIiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL3g1MDktcmV2b2NhdGlvbiIsImlhdCI6MTc2NzIyNTYwMCwic3RhdHVzX2xpc3QiOnsiYml0cyI6MSwibHN0IjoiPGNvbXByZXNzZWQtc3RhdHVzLWxpc3Q-In19.SIGNATURE-REDACTED\",\n  \"_decoded\": {\n    \"header\": {\n      \"typ\": \"statuslist+jwt\",\n      \"alg\": \"ES256\",\n      \"jwk\": {\n        \"crv\": \"P-256\",\n        \"kty\": \"EC\",\n        \"x\": \"<public-key-material>\",\n        \"x5c\": [\n          \"<certificate>\"\n        ],\n        \"y\": \"<public-key-material>\"\n      },\n      \"x5c\": [\n        \"<certificate>\"\n      ]\n    },\n    \"payload\": {\n      \"iss\": \"https://acme.example.com\",\n      \"sub\": \"https://acme.example.com/public/statuslists/x509-revocation\",\n      \"iat\": 1767225600,\n      \"status_list\": {\n        \"bits\": 1,\n        \"lst\": \"<compressed-status-list>\"\n      }\n    }\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Revoke a status entry",
              "request": {
                "method": "POST",
                "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{statusListId}}/status",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"statusListIndex\": 42,\n  \"value\": 1\n}"
                },
                "description": "Sets the status bit at an index to 1 (revoked). A status read exposes only the bit value; whether an index is allocated is intentionally not observable."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('entry revoked', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/statuslist/v1/statuslists/00000000-0000-4000-8000-000000000000/status",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"statusListIndex\": 42,\n  \"value\": 1\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n  \"statusListIndex\": 42,\n  \"entryCorrelationId\": null,\n  \"credentialId\": null,\n  \"credentialHash\": null,\n  \"value\": 1,\n  \"purpose\": \"revocation\",\n  \"identifier\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 Reactivate the status entry",
              "request": {
                "method": "POST",
                "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{statusListId}}/status",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"statusListIndex\": 42,\n  \"value\": 0\n}"
                },
                "description": "Sets the same index back to 0 (valid)."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('entry reactivated', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/statuslist/v1/statuslists/00000000-0000-4000-8000-000000000000/status",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"statusListIndex\": 42,\n  \"value\": 0\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n  \"statusListIndex\": 42,\n  \"entryCorrelationId\": null,\n  \"credentialId\": null,\n  \"credentialHash\": null,\n  \"value\": 0,\n  \"purpose\": \"revocation\",\n  \"identifier\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "07 Read status entry",
              "request": {
                "method": "GET",
                "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{statusListId}}/entries/42",
                "description": "Reads the status-list entry that was revoked and reactivated by index. This verifies the non-leaking upsert/read path for allocated and previously unallocated indexes.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('status entry returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const entry = pm.response.json();",
                      "pm.test('reactivated status entry is readable without allocation leak', () => {",
                      "  pm.expect(entry.statusListId).to.eql(pm.collectionVariables.get('statusListId'));",
                      "  pm.expect(entry.statusListIndex).to.eql(42);",
                      "  pm.expect(entry.value).to.eql(0);",
                      "  pm.expect(entry.purpose).to.eql('revocation');",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/statuslist/v1/statuslists/00000000-0000-4000-8000-000000000000/entries/42",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n  \"statusListIndex\": 42,\n  \"entryCorrelationId\": null,\n  \"credentialId\": null,\n  \"credentialHash\": null,\n  \"value\": 0,\n  \"purpose\": \"revocation\",\n  \"identifier\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "CWT mdoc",
              "description": "Creates the CWT-proofed token status list for mdoc credentials with X.509 signing, verifies the hosted representation is an untagged COSE_Sign1 served as application/statuslist+cwt, binds it to the Mdl credential configuration, and runs the revoke, refetch and reactivate cycle. The REST create body has no mdoc profile selector, which is recorded as a gap on the create request.",
              "item": [
                {
                  "name": "01 Create the CWT token status list",
                  "request": {
                    "method": "POST",
                    "url": "{{tenantStatusListApiBaseUrl}}/statuslists",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"correlationId\": \"mdoc-revocation\",\n  \"spec\": \"token_status_list\",\n  \"proofFormat\": \"cwt\",\n  \"hostingMode\": \"hosted\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"issuer\": \"{{tenantGatewayUrl}}\",\n  \"signingKeyMode\": \"x5c\",\n  \"kmsResourceHandle\": \"{{statusListX509KmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"{{statusListX509KmsKeyAlias}}\",\n  \"statusListUri\": \"{{tenantGatewayUrl}}/public/statuslists/mdoc-revocation\",\n  \"length\": 131072,\n  \"bitsPerStatus\": 1,\n  \"mdocProfile\": \"status_list\",\n  \"validUntil\": \"{{cwtStatusListValidUntil}}\",\n  \"ttlSeconds\": 300\n}"
                    },
                    "description": "Creates the CWT-proofed Token Status List that mdoc credentials reference, signed with the certificate chain of the mDL signing key."
                  },
                  "event": [
                    {
                      "listen": "prerequest",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "// The ISO 18013-5 mdoc profile requires an expiry on the list; one year from now keeps the example valid.",
                          "const validUntil = new Date(); validUntil.setUTCFullYear(validUntil.getUTCFullYear() + 1);",
                          "pm.collectionVariables.set('cwtStatusListValidUntil', validUntil.toISOString());"
                        ]
                      }
                    },
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test('CWT status list created or already provisioned', () => pm.expect([200, 201, 409], 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.include(pm.response.code));",
                          "const j = pm.response.json();",
                          "if (j.id) pm.collectionVariables.set('cwtStatusListId', j.id);",
                          "if (j.statusListUri) pm.collectionVariables.set('cwtStatusListUri', j.statusListUri);",
                          "if (!pm.collectionVariables.get('cwtStatusListUri')) pm.collectionVariables.set('cwtStatusListUri', pm.variables.get('tenantGatewayUrl') + '/public/statuslists/mdoc-revocation');",
                          "pm.test('the CWT status list matches the mdoc revocation contract', () => {",
                          "  if (pm.response.code === 409) {",
                          "    pm.expect(j.error && j.error.code).to.eql('STATUSLIST_DUPLICATE_CORRELATION_ID');",
                          "    return;",
                          "  }",
                          "  pm.expect(j.correlationId, 'correlation id').to.eql('mdoc-revocation');",
                          "  pm.expect(j.spec, 'spec').to.eql('token_status_list');",
                          "  pm.expect(j.proofFormat, 'proof format').to.eql('cwt');",
                          "  pm.expect(j.bitsPerStatus, 'bits per status').to.eql(1);",
                          "  pm.expect(j.contentType, 'hosted content type').to.eql('application/statuslist+cwt');",
                          "});",
                          "pm.test('the list declares the ISO 18013-5 mdoc status_list profile', () => {",
                          "  if (pm.response.code === 409) return;",
                          "  pm.expect(j.mdocProfile, 'mdocProfile is echoed by the resource').to.eql('status_list');",
                          "});"
                        ]
                      }
                    }
                  ],
                  "response": [
                    {
                      "name": "Previously captured response (sanitized)",
                      "originalRequest": {
                        "method": "POST",
                        "url": "https://acme.example.com/api/statuslist/v1/statuslists",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json"
                          },
                          {
                            "key": "Authorization",
                            "value": "Bearer <token>"
                          },
                          {
                            "key": "Accept",
                            "value": "*/*"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"correlationId\": \"mdoc-revocation\",\n  \"spec\": \"token_status_list\",\n  \"proofFormat\": \"cwt\",\n  \"hostingMode\": \"hosted\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"issuer\": \"https://acme.example.com\",\n  \"signingKeyMode\": \"x5c\",\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/mdoc-revocation\",\n  \"length\": 131072,\n  \"bitsPerStatus\": 1,\n  \"mdocProfile\": \"status_list\",\n  \"validUntil\": \"2027-01-01T00:00:00Z\",\n  \"ttlSeconds\": 300\n}"
                        }
                      },
                      "status": "Created",
                      "code": 201,
                      "header": [
                        {
                          "key": "Content-Type",
                          "value": "application/json"
                        }
                      ],
                      "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"correlationId\": \"mdoc-revocation\",\n  \"spec\": \"token_status_list\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"proofFormat\": \"cwt\",\n  \"hostingMode\": \"hosted\",\n  \"bitsPerStatus\": 1,\n  \"length\": 131072,\n  \"issuer\": \"https://acme.example.com\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/mdoc-revocation\",\n  \"signedToken\": \"<base64 payload omitted>\",\n  \"contentType\": \"application/statuslist+cwt\",\n  \"mdocProfile\": \"status_list\",\n  \"aggregationUri\": null,\n  \"validUntil\": \"2027-01-01T00:00:00Z\"\n}",
                      "_postman_previewlanguage": "json"
                    }
                  ]
                },
                {
                  "name": "02 Fetch the hosted CWT status list",
                  "request": {
                    "auth": {
                      "type": "noauth"
                    },
                    "method": "GET",
                    "url": "{{cwtStatusListUri}}",
                    "header": [],
                    "description": "Fetches the hosted CWT status list from the unversioned public hosting surface. The body is an untagged COSE_Sign1, that is a bare four element CBOR array, so it starts with the CBOR major-type byte 0x84 and carries no COSE_Sign1 tag."
                  },
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test('CWT status list hosted', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 120)).to.eql(200));",
                          "const bytes = pm.response.stream ? Array.from(pm.response.stream.toJSON ? pm.response.stream.toJSON().data : pm.response.stream) : [];",
                          "pm.test('the hosted CWT list is an untagged COSE_Sign1 with the statuslist CWT media type', () => {",
                          "  pm.expect(pm.response.headers.get('Content-Type') || '', 'content type').to.include('application/statuslist+cwt');",
                          "  pm.expect(bytes.length, 'response bytes').to.be.greaterThan(0);",
                          "  pm.expect(bytes[0], 'first byte is the four element CBOR array header 0x84').to.eql(0x84);",
                          "  pm.expect(bytes[0], 'the list is not wrapped in CBOR tag 18').to.not.eql(0xd2);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "response": [
                    {
                      "name": "Previously captured response (sanitized)",
                      "originalRequest": {
                        "method": "GET",
                        "url": "https://acme.example.com/public/statuslists/mdoc-revocation",
                        "header": [
                          {
                            "key": "Accept",
                            "value": "*/*"
                          }
                        ]
                      },
                      "status": "OK",
                      "code": 200,
                      "header": [
                        {
                          "key": "Content-Type",
                          "value": "application/statuslist+cwt"
                        }
                      ],
                      "body": "<CWT status-list payload omitted>",
                      "_postman_previewlanguage": "json"
                    }
                  ]
                }
              ],
              "event": []
            },
            {
              "name": "Bitstring VCDM",
              "description": "Creates the W3C bitstring status list the VCDM credential configurations bind to, with the VC-JWT proof format, both the revocation and the suspension purpose, and two bits per status. It then walks a single entry through suspended, valid and revoked, asserting every transition through the entry read.",
              "item": [
                {
                  "name": "01 Create the bitstring status list",
                  "request": {
                    "method": "POST",
                    "url": "{{tenantStatusListApiBaseUrl}}/statuslists",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"correlationId\": \"status-bitstring\",\n  \"spec\": \"bitstring_status_list\",\n  \"proofFormat\": \"vc+jwt\",\n  \"hostingMode\": \"hosted\",\n  \"purposes\": [\n    \"revocation\",\n    \"suspension\"\n  ],\n  \"issuer\": \"{{did}}\",\n  \"signingKeyMode\": \"did:web\",\n  \"kmsResourceHandle\": \"{{statusListDidKmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"{{statusListDidKmsKeyAlias}}\",\n  \"signingVerificationMethodId\": \"{{statusListDidVerificationMethodId}}\",\n  \"statusListUri\": \"{{tenantGatewayUrl}}/public/statuslists/status-bitstring\",\n  \"length\": 131072,\n  \"bitsPerStatus\": 2,\n  \"ttlSeconds\": 300\n}"
                    },
                    "description": "Creates the W3C bitstring status list that the VCDM credential configurations reference. Two bits per status carry more than a single revoked flag, so the same list serves both the revocation and the suspension purpose. The hosted representation is a VC-JWT."
                  },
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test('bitstring status list created or already provisioned', () => pm.expect([200, 201, 409], 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.include(pm.response.code));",
                          "const j = pm.response.json();",
                          "if (j.id) pm.collectionVariables.set('bitstringStatusListId', j.id);",
                          "if (j.statusListUri) pm.collectionVariables.set('bitstringStatusListUri', j.statusListUri);",
                          "if (!pm.collectionVariables.get('bitstringStatusListUri')) pm.collectionVariables.set('bitstringStatusListUri', pm.variables.get('tenantGatewayUrl') + '/public/statuslists/status-bitstring');",
                          "pm.test('the bitstring list serves revocation and suspension with two bits per status', () => {",
                          "  if (pm.response.code === 409) {",
                          "    pm.expect(j.error && j.error.code).to.eql('STATUSLIST_DUPLICATE_CORRELATION_ID');",
                          "    return;",
                          "  }",
                          "  pm.expect(j.correlationId, 'correlation id').to.eql('status-bitstring');",
                          "  pm.expect(j.spec, 'spec').to.eql('bitstring_status_list');",
                          "  pm.expect(j.proofFormat, 'proof format').to.eql('vc+jwt');",
                          "  pm.expect(j.bitsPerStatus, 'bits per status').to.eql(2);",
                          "  pm.expect(j.purposes, 'purposes').to.have.members(['revocation', 'suspension']);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "response": [
                    {
                      "name": "Previously captured response (sanitized)",
                      "originalRequest": {
                        "method": "POST",
                        "url": "https://acme.example.com/api/statuslist/v1/statuslists",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json"
                          },
                          {
                            "key": "Authorization",
                            "value": "Bearer <token>"
                          },
                          {
                            "key": "Accept",
                            "value": "*/*"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"correlationId\": \"status-bitstring\",\n  \"spec\": \"bitstring_status_list\",\n  \"proofFormat\": \"vc+jwt\",\n  \"hostingMode\": \"hosted\",\n  \"purposes\": [\n    \"revocation\",\n    \"suspension\"\n  ],\n  \"issuer\": \"did:web:acme.example.com\",\n  \"signingKeyMode\": \"did:web\",\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingVerificationMethodId\": \"did:web:acme.example.com#issuer-assertion-acme\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/status-bitstring\",\n  \"length\": 131072,\n  \"bitsPerStatus\": 2,\n  \"ttlSeconds\": 300\n}"
                        }
                      },
                      "status": "Created",
                      "code": 201,
                      "header": [
                        {
                          "key": "Content-Type",
                          "value": "application/json"
                        }
                      ],
                      "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"correlationId\": \"status-bitstring\",\n  \"spec\": \"bitstring_status_list\",\n  \"purposes\": [\n    \"revocation\",\n    \"suspension\"\n  ],\n  \"proofFormat\": \"vc+jwt\",\n  \"hostingMode\": \"hosted\",\n  \"bitsPerStatus\": 2,\n  \"length\": 131072,\n  \"issuer\": \"did:web:acme.example.com\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/status-bitstring\",\n  \"signedToken\": \"eyJ0eXAiOiJ2Yytqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDp3ZWI6YWNtZS5leGFtcGxlLmNvbSNpc3N1ZXItYXNzZXJ0aW9uLWFjbWUifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvc3RhdHVzL3YxIl0sImlkIjoiaHR0cHM6Ly9hY21lLmV4YW1wbGUuY29tL3B1YmxpYy9zdGF0dXNsaXN0cy9zdGF0dXMtYml0c3RyaW5nIiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJpdHN0cmluZ1N0YXR1c0xpc3RDcmVkZW50aWFsIl0sImlzc3VlciI6ImRpZDp3ZWI6YWNtZS5leGFtcGxlLmNvbSIsInZhbGlkRnJvbSI6IjIwMjYtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL3N0YXR1cy1iaXRzdHJpbmcjbGlzdCIsInR5cGUiOiJCaXRzdHJpbmdTdGF0dXNMaXN0Iiwic3RhdHVzUHVycG9zZSI6InJldm9jYXRpb24iLCJlbmNvZGVkTGlzdCI6InVINHNJQUFBQUFBQUFfLTNCQVFFQUFBQ0FrUDZ2N2dnS0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQmltX0I4QkFJQUFBQSIsInN0YXR1c1NpemUiOjIsInN0YXR1c01lc3NhZ2UiOlt7InN0YXR1cyI6IjB4MCIsIm1lc3NhZ2UiOiJ2YWxpZCJ9LHsic3RhdHVzIjoiMHgxIiwibWVzc2FnZSI6ImludmFsaWQifSx7InN0YXR1cyI6IjB4MiIsIm1lc3NhZ2UiOiJzdXNwZW5kZWQifSx7InN0YXR1cyI6IjB4MyIsIm1lc3NhZ2UiOiJhcHBsaWNhdGlvbl9zcGVjaWZpYyJ9XSwidHRsIjozMDAwMDB9fQ.SIGNATURE-REDACTED\",\n  \"signedToken_decoded\": {\n    \"header\": {\n      \"typ\": \"vc+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\"\n    },\n    \"payload\": {\n      \"@context\": [\n        \"https://www.w3.org/ns/credentials/v2\",\n        \"https://www.w3.org/ns/credentials/status/v1\"\n      ],\n      \"id\": \"https://acme.example.com/public/statuslists/status-bitstring\",\n      \"type\": [\n        \"VerifiableCredential\",\n        \"BitstringStatusListCredential\"\n      ],\n      \"issuer\": \"did:web:acme.example.com\",\n      \"validFrom\": \"2026-01-01T00:00:00Z\",\n      \"credentialSubject\": {\n        \"id\": \"https://acme.example.com/public/statuslists/status-bitstring#list\",\n        \"type\": \"BitstringStatusList\",\n        \"statusPurpose\": \"revocation\",\n        \"encodedList\": \"uH4sIAAAAAAAA_-3BAQEAAACAkP6v7ggKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABim_B8BAIAAAA\",\n        \"statusSize\": 2,\n        \"statusMessage\": [\n          {\n            \"status\": \"0x0\",\n            \"message\": \"valid\"\n          },\n          {\n            \"status\": \"0x1\",\n            \"message\": \"invalid\"\n          },\n          {\n            \"status\": \"0x2\",\n            \"message\": \"suspended\"\n          },\n          {\n            \"status\": \"0x3\",\n            \"message\": \"application_specific\"\n          }\n        ],\n        \"ttl\": 300000\n      }\n    }\n  },\n  \"contentType\": \"application/vc+jwt\",\n  \"mdocProfile\": null,\n  \"aggregationUri\": null,\n  \"validUntil\": null\n}",
                      "_postman_previewlanguage": "json"
                    }
                  ]
                },
                {
                  "name": "02 Get the bitstring status list",
                  "request": {
                    "method": "GET",
                    "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{bitstringStatusListId}}",
                    "header": [],
                    "description": "Reads the list back through the management API before entries are written, so the entry updates that follow act on a known shape."
                  },
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test('bitstring status list returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                          "const j = pm.response.json();",
                          "pm.test('the persisted list keeps both purposes and two bits per status', () => {",
                          "  pm.expect(j.id, 'status list id').to.eql(pm.collectionVariables.get('bitstringStatusListId'));",
                          "  pm.expect(j.bitsPerStatus, 'bits per status').to.eql(2);",
                          "  pm.expect(j.purposes, 'purposes').to.have.members(['revocation', 'suspension']);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "response": [
                    {
                      "name": "Previously captured response (sanitized)",
                      "originalRequest": {
                        "method": "GET",
                        "url": "https://acme.example.com/api/statuslist/v1/statuslists/00000000-0000-4000-8000-000000000000",
                        "header": [
                          {
                            "key": "Authorization",
                            "value": "Bearer <token>"
                          },
                          {
                            "key": "Accept",
                            "value": "*/*"
                          }
                        ]
                      },
                      "status": "OK",
                      "code": 200,
                      "header": [
                        {
                          "key": "Content-Type",
                          "value": "application/json"
                        }
                      ],
                      "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"correlationId\": \"status-bitstring\",\n  \"spec\": \"bitstring_status_list\",\n  \"purposes\": [\n    \"revocation\",\n    \"suspension\"\n  ],\n  \"proofFormat\": \"vc+jwt\",\n  \"hostingMode\": \"hosted\",\n  \"bitsPerStatus\": 2,\n  \"length\": 131072,\n  \"issuer\": \"did:web:acme.example.com\",\n  \"statusListUri\": \"https://acme.example.com/public/statuslists/status-bitstring\",\n  \"signedToken\": \"eyJ0eXAiOiJ2Yytqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDp3ZWI6YWNtZS5leGFtcGxlLmNvbSNpc3N1ZXItYXNzZXJ0aW9uLWFjbWUifQ.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiLCJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvc3RhdHVzL3YxIl0sImlkIjoiaHR0cHM6Ly9hY21lLmV4YW1wbGUuY29tL3B1YmxpYy9zdGF0dXNsaXN0cy9zdGF0dXMtYml0c3RyaW5nIiwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIkJpdHN0cmluZ1N0YXR1c0xpc3RDcmVkZW50aWFsIl0sImlzc3VlciI6ImRpZDp3ZWI6YWNtZS5leGFtcGxlLmNvbSIsInZhbGlkRnJvbSI6IjIwMjYtMDEtMDFUMDA6MDA6MDBaIiwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL3N0YXR1cy1iaXRzdHJpbmcjbGlzdCIsInR5cGUiOiJCaXRzdHJpbmdTdGF0dXNMaXN0Iiwic3RhdHVzUHVycG9zZSI6InJldm9jYXRpb24iLCJlbmNvZGVkTGlzdCI6InVINHNJQUFBQUFBQUFfLTNCQVFFQUFBQ0FrUDZ2N2dnS0FBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQmltX0I4QkFJQUFBQSIsInN0YXR1c1NpemUiOjIsInN0YXR1c01lc3NhZ2UiOlt7InN0YXR1cyI6IjB4MCIsIm1lc3NhZ2UiOiJ2YWxpZCJ9LHsic3RhdHVzIjoiMHgxIiwibWVzc2FnZSI6ImludmFsaWQifSx7InN0YXR1cyI6IjB4MiIsIm1lc3NhZ2UiOiJzdXNwZW5kZWQifSx7InN0YXR1cyI6IjB4MyIsIm1lc3NhZ2UiOiJhcHBsaWNhdGlvbl9zcGVjaWZpYyJ9XSwidHRsIjozMDAwMDB9fQ.SIGNATURE-REDACTED\",\n  \"signedToken_decoded\": {\n    \"header\": {\n      \"typ\": \"vc+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\"\n    },\n    \"payload\": {\n      \"@context\": [\n        \"https://www.w3.org/ns/credentials/v2\",\n        \"https://www.w3.org/ns/credentials/status/v1\"\n      ],\n      \"id\": \"https://acme.example.com/public/statuslists/status-bitstring\",\n      \"type\": [\n        \"VerifiableCredential\",\n        \"BitstringStatusListCredential\"\n      ],\n      \"issuer\": \"did:web:acme.example.com\",\n      \"validFrom\": \"2026-01-01T00:00:00Z\",\n      \"credentialSubject\": {\n        \"id\": \"https://acme.example.com/public/statuslists/status-bitstring#list\",\n        \"type\": \"BitstringStatusList\",\n        \"statusPurpose\": \"revocation\",\n        \"encodedList\": \"uH4sIAAAAAAAA_-3BAQEAAACAkP6v7ggKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABim_B8BAIAAAA\",\n        \"statusSize\": 2,\n        \"statusMessage\": [\n          {\n            \"status\": \"0x0\",\n            \"message\": \"valid\"\n          },\n          {\n            \"status\": \"0x1\",\n            \"message\": \"invalid\"\n          },\n          {\n            \"status\": \"0x2\",\n            \"message\": \"suspended\"\n          },\n          {\n            \"status\": \"0x3\",\n            \"message\": \"application_specific\"\n          }\n        ],\n        \"ttl\": 300000\n      }\n    }\n  },\n  \"contentType\": \"application/vc+jwt\",\n  \"mdocProfile\": null,\n  \"aggregationUri\": null,\n  \"validUntil\": null\n}",
                      "_postman_previewlanguage": "json"
                    }
                  ]
                },
                {
                  "name": "03 Suspend a bitstring status entry",
                  "request": {
                    "method": "POST",
                    "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{bitstringStatusListId}}/status",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"statusListIndex\": 11,\n  \"value\": 2\n}"
                    },
                    "description": "Sets the two-bit entry to 2 (suspended). The update body carries the value and exactly one selector; the purpose is a property of the list, not of the update."
                  },
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test('entry suspended', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));"
                        ]
                      }
                    }
                  ],
                  "response": [
                    {
                      "name": "Previously captured response (sanitized)",
                      "originalRequest": {
                        "method": "POST",
                        "url": "https://acme.example.com/api/statuslist/v1/statuslists/00000000-0000-4000-8000-000000000000/status",
                        "header": [
                          {
                            "key": "Content-Type",
                            "value": "application/json"
                          },
                          {
                            "key": "Authorization",
                            "value": "Bearer <token>"
                          },
                          {
                            "key": "Accept",
                            "value": "*/*"
                          }
                        ],
                        "body": {
                          "mode": "raw",
                          "raw": "{\n  \"statusListIndex\": 11,\n  \"value\": 2\n}"
                        }
                      },
                      "status": "OK",
                      "code": 200,
                      "header": [
                        {
                          "key": "Content-Type",
                          "value": "application/json"
                        }
                      ],
                      "body": "{\n  \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n  \"statusListIndex\": 11,\n  \"entryCorrelationId\": null,\n  \"credentialId\": null,\n  \"credentialHash\": null,\n  \"value\": 2,\n  \"purpose\": \"revocation\",\n  \"identifier\": null\n}",
                      "_postman_previewlanguage": "json"
                    }
                  ]
                },
                {
                  "name": "04 Read the suspended entry",
                  "request": {
                    "method": "GET",
                    "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{bitstringStatusListId}}/entries/11",
                    "header": [],
                    "description": "Reads the entry and confirms the suspended value survived the write. A single-bit list could not represent this state."
                  },
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test('bitstring status entry returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                          "const entry = pm.response.json();",
                          "pm.test('the entry reads back as suspended', () => {",
                          "  pm.expect(entry.statusListId, 'status list id').to.eql(pm.collectionVariables.get('bitstringStatusListId'));",
                          "  pm.expect(entry.statusListIndex, 'index').to.eql(11);",
                          "  pm.expect(entry.value, 'value').to.eql(2);",
                          "});"
                        ]
                      }
                    }
                  ],
                  "response": [
                    {
                      "name": "Previously captured response (sanitized)",
                      "originalRequest": {
                        "method": "GET",
                        "url": "https://acme.example.com/api/statuslist/v1/statuslists/00000000-0000-4000-8000-000000000000/entries/11",
                        "header": [
                          {
                            "key": "Authorization",
                            "value": "Bearer <token>"
                          },
                          {
                            "key": "Accept",
                            "value": "*/*"
                          }
                        ]
                      },
                      "status": "OK",
                      "code": 200,
                      "header": [
                        {
                          "key": "Content-Type",
                          "value": "application/json"
                        }
                      ],
                      "body": "{\n  \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n  \"statusListIndex\": 11,\n  \"entryCorrelationId\": null,\n  \"credentialId\": null,\n  \"credentialHash\": null,\n  \"value\": 2,\n  \"purpose\": \"revocation\",\n  \"identifier\": null\n}",
                      "_postman_previewlanguage": "json"
                    }
                  ]
                }
              ],
              "event": []
            }
          ],
          "event": []
        },
        {
          "name": "13 Credential Configurations",
          "description": "How per-credential configuration is expressed on an issuer instance: the signing key (kmsResourceHandle and kmsKeyAlias), the public trust mechanism (signingKeyMode did:web or x5c), the validity period, the OAuth scope and the status list binding. Reads show the provisioned defaults; the registrations add VCDM 1.1 and 2.0 configurations; the last request binds the CWT status list to the mdoc configuration.\n\nDocumentation: https://docs.sphereon.com/edk/admin-console/console-reference/protocols/issuer/credentials",
          "item": [
            {
              "name": "01 Read the EuPid credential configuration",
              "request": {
                "method": "GET",
                "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{tenantId}}/oid4vci/issuer/instances/{{issuerId}}/credential-config-settings/EuPid",
                "description": "Reads the EuPid settings that already reference the shared list, so the second credential configuration is registered with the same signing selection rather than a new one.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('EuPid credential configuration returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const body = pm.response.json();",
                      "const j = body.data || body;",
                      "pm.test('EuPid already references the shared list', () => {",
                      "  pm.expect(j.status && j.status.statusListId, 'bound status list').to.eql('eupid-revocation');",
                      "});",
                      "pm.collectionVariables.set('sharedListScope', j.scope || 'eu.europa.ec.eudi.pid.1');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://platform.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vci/issuer/instances/00000000-0000-4000-8000-000000000000/credential-config-settings/EuPid",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"EuPid\",\n  \"format\": \"dc+sd-jwt\",\n  \"scope\": \"eu_pid\",\n  \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n  \"cryptographicBindingMethodsSupported\": [\n    \"jwk\",\n    \"did:jwk\",\n    \"did:key\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"did:web:acme.example.com#issuer-assertion-acme\",\n  \"status\": {\n    \"statusListId\": \"eupid-revocation\",\n    \"purpose\": \"revocation\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Read the Mdl credential configuration",
              "request": {
                "method": "GET",
                "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{tenantId}}/oid4vci/issuer/instances/{{issuerId}}/credential-config-settings/Mdl",
                "description": "Reads the mDL credential configuration before the CWT status list is bound to it. The immutable `resourceId` of the configuration is reused by the write so the binding updates the existing resource instead of creating a second one.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Mdl credential configuration returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const body = pm.response.json();",
                      "const j = body.data || body;",
                      "pm.expect(j.resourceId, 'immutable resource id').to.be.a('string').and.not.empty;",
                      "pm.collectionVariables.set('mdlSettingsResourceId', j.resourceId);",
                      "pm.collectionVariables.set('mdlSettingsScope', j.scope || 'org.iso.18013.5.1.mDL');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://platform.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vci/issuer/instances/00000000-0000-4000-8000-000000000000/credential-config-settings/Mdl",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"Mdl\",\n  \"format\": \"mso_mdoc\",\n  \"scope\": \"mdl\",\n  \"docType\": \"org.iso.18013.5.1.mDL\",\n  \"cryptographicBindingMethodsSupported\": [\n    \"cose_key\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"x5c\",\n  \"status\": {\n    \"statusListId\": \"mdoc-revocation\",\n    \"purpose\": \"revocation\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Register the EmployeeBadge configuration (VCDM 1.1)",
              "request": {
                "method": "PUT",
                "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{tenantId}}/oid4vci/issuer/instances/{{issuerId}}/credential-config-settings/EmployeeBadge",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"resourceId\": \"7f1c2d34-1111-4a2b-9c3d-0000000000b1\",\n  \"credentialConfigurationId\": \"EmployeeBadge\",\n  \"format\": \"jwt_vc_json\",\n  \"scope\": \"employeebadge\",\n  \"credentialDefinitionTypes\": [\n    \"VerifiableCredential\",\n    \"EmployeeBadgeCredential\"\n  ],\n  \"cryptographicBindingMethodsSupported\": [\n    \"jwk\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"{{statusListDidKmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"{{statusListDidKmsKeyAlias}}\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"{{statusListDidVerificationMethodId}}\",\n  \"validityPeriod\": \"P365D\",\n  \"status\": {\n    \"statusListId\": \"{{bitstringStatusListId}}\",\n    \"purpose\": \"revocation\",\n    \"revokeAtExpiry\": false\n  }\n}"
                },
                "description": "Registers the VCDM 1.1 credential configuration with the `jwt_vc_json` format and binds it to the bitstring status list created in folder 09c. `credentialDefinitionTypes` carries the W3C credential types; the signing selection is the same exact DID assertionMethod the status list uses."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('EmployeeBadge credential configuration registered', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200, 201]));",
                      "const body = pm.response.json();",
                      "const j = body.data || body;",
                      "pm.test('EmployeeBadge is a VCDM 1.1 configuration bound to the bitstring list', () => {",
                      "  pm.expect(j.credentialConfigurationId, 'credential configuration id').to.eql('EmployeeBadge');",
                      "  pm.expect(j.format, 'format').to.eql('jwt_vc_json');",
                      "  pm.expect(j.credentialDefinitionTypes, 'credential types').to.include('EmployeeBadgeCredential');",
                      "  pm.expect(j.status && j.status.statusListId, 'bound status list').to.eql(pm.collectionVariables.get('bitstringStatusListId'));",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://platform.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vci/issuer/instances/00000000-0000-4000-8000-000000000000/credential-config-settings/EmployeeBadge",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"EmployeeBadge\",\n  \"format\": \"jwt_vc_json\",\n  \"scope\": \"employeebadge\",\n  \"credentialDefinitionTypes\": [\n    \"VerifiableCredential\",\n    \"EmployeeBadgeCredential\"\n  ],\n  \"cryptographicBindingMethodsSupported\": [\n    \"jwk\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"did:web:acme.example.com#issuer-assertion-acme\",\n  \"validityPeriod\": \"P365D\",\n  \"status\": {\n    \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n    \"purpose\": \"revocation\",\n    \"revokeAtExpiry\": false\n  }\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"EmployeeBadge\",\n  \"format\": \"jwt_vc_json\",\n  \"scope\": \"employeebadge\",\n  \"credentialDefinitionTypes\": [\n    \"VerifiableCredential\",\n    \"EmployeeBadgeCredential\"\n  ],\n  \"cryptographicBindingMethodsSupported\": [\n    \"jwk\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"did:web:acme.example.com#issuer-assertion-acme\",\n  \"validityPeriod\": \"P365D\",\n  \"status\": {\n    \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n    \"purpose\": \"revocation\",\n    \"revokeAtExpiry\": false\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Register the Membership configuration (VCDM 2.0)",
              "request": {
                "method": "PUT",
                "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{tenantId}}/oid4vci/issuer/instances/{{issuerId}}/credential-config-settings/Membership",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"resourceId\": \"7f1c2d34-1111-4a2b-9c3d-0000000000b2\",\n  \"credentialConfigurationId\": \"Membership\",\n  \"format\": \"jwt_vc_json-ld\",\n  \"scope\": \"membership\",\n  \"credentialDefinitionTypes\": [\n    \"VerifiableCredential\",\n    \"MembershipCredential\"\n  ],\n  \"cryptographicBindingMethodsSupported\": [\n    \"jwk\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"{{statusListDidKmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"{{statusListDidKmsKeyAlias}}\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"{{statusListDidVerificationMethodId}}\",\n  \"validityPeriod\": \"P365D\",\n  \"status\": {\n    \"statusListId\": \"{{bitstringStatusListId}}\",\n    \"purpose\": \"revocation\",\n    \"revokeAtExpiry\": false\n  }\n}"
                },
                "description": "Registers the VCDM 2.0 credential configuration with the `jwt_vc_json-ld` format and binds it to the bitstring status list created in folder 09c. `credentialDefinitionTypes` carries the W3C credential types; the signing selection is the same exact DID assertionMethod the status list uses."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Membership credential configuration registered', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200, 201]));",
                      "const body = pm.response.json();",
                      "const j = body.data || body;",
                      "pm.test('Membership is a VCDM 2.0 configuration bound to the bitstring list', () => {",
                      "  pm.expect(j.credentialConfigurationId, 'credential configuration id').to.eql('Membership');",
                      "  pm.expect(j.format, 'format').to.eql('jwt_vc_json-ld');",
                      "  pm.expect(j.credentialDefinitionTypes, 'credential types').to.include('MembershipCredential');",
                      "  pm.expect(j.status && j.status.statusListId, 'bound status list').to.eql(pm.collectionVariables.get('bitstringStatusListId'));",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://platform.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vci/issuer/instances/00000000-0000-4000-8000-000000000000/credential-config-settings/Membership",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"Membership\",\n  \"format\": \"jwt_vc_json-ld\",\n  \"scope\": \"membership\",\n  \"credentialDefinitionTypes\": [\n    \"VerifiableCredential\",\n    \"MembershipCredential\"\n  ],\n  \"cryptographicBindingMethodsSupported\": [\n    \"jwk\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"did:web:acme.example.com#issuer-assertion-acme\",\n  \"validityPeriod\": \"P365D\",\n  \"status\": {\n    \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n    \"purpose\": \"revocation\",\n    \"revokeAtExpiry\": false\n  }\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"Membership\",\n  \"format\": \"jwt_vc_json-ld\",\n  \"scope\": \"membership\",\n  \"credentialDefinitionTypes\": [\n    \"VerifiableCredential\",\n    \"MembershipCredential\"\n  ],\n  \"cryptographicBindingMethodsSupported\": [\n    \"jwk\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"did:web:acme.example.com#issuer-assertion-acme\",\n  \"validityPeriod\": \"P365D\",\n  \"status\": {\n    \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n    \"purpose\": \"revocation\",\n    \"revokeAtExpiry\": false\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Bind the CWT status list to the Mdl configuration",
              "request": {
                "method": "PUT",
                "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{tenantId}}/oid4vci/issuer/instances/{{issuerId}}/credential-config-settings/Mdl",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"resourceId\": \"{{mdlSettingsResourceId}}\",\n  \"credentialConfigurationId\": \"Mdl\",\n  \"format\": \"mso_mdoc\",\n  \"scope\": \"{{mdlSettingsScope}}\",\n  \"docType\": \"org.iso.18013.5.1.mDL\",\n  \"cryptographicBindingMethodsSupported\": [\n    \"cose_key\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"{{statusListX509KmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"{{statusListX509KmsKeyAlias}}\",\n  \"signingKeyMode\": \"x5c\",\n  \"validityPeriod\": \"P365D\",\n  \"status\": {\n    \"statusListId\": \"mdoc-revocation\",\n    \"purpose\": \"revocation\",\n    \"revokeAtExpiry\": false\n  }\n}"
                },
                "description": "Binds the CWT list to the mDL credential configuration. The binding references the list by its correlation id. Issued mdoc credentials do not yet carry a status entry, so this binding is configuration-visible while the issued MSO stays unchanged."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('CWT status list bound to Mdl', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200, 201]));",
                      "const body = pm.response.json();",
                      "const j = body.data || body;",
                      "pm.test('the mDL configuration references the CWT list by correlation id', () => {",
                      "  pm.expect(j.status, 'status binding').to.be.an('object');",
                      "  pm.expect(j.status.statusListId, 'bound status list').to.eql('mdoc-revocation');",
                      "  pm.expect(j.status.purpose, 'status purpose').to.eql('revocation');",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://platform.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vci/issuer/instances/00000000-0000-4000-8000-000000000000/credential-config-settings/Mdl",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"Mdl\",\n  \"format\": \"mso_mdoc\",\n  \"scope\": \"mdl\",\n  \"docType\": \"org.iso.18013.5.1.mDL\",\n  \"cryptographicBindingMethodsSupported\": [\n    \"cose_key\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"x5c\",\n  \"validityPeriod\": \"P365D\",\n  \"status\": {\n    \"statusListId\": \"mdoc-revocation\",\n    \"purpose\": \"revocation\",\n    \"revokeAtExpiry\": false\n  }\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"resourceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"credentialConfigurationId\": \"Mdl\",\n  \"format\": \"mso_mdoc\",\n  \"scope\": \"mdl\",\n  \"docType\": \"org.iso.18013.5.1.mDL\",\n  \"cryptographicBindingMethodsSupported\": [\n    \"cose_key\"\n  ],\n  \"credentialSigningAlgValuesSupported\": [\n    \"ES256\"\n  ],\n  \"proofTypesSupported\": {\n    \"jwt\": {\n      \"proofSigningAlgValuesSupported\": [\n        \"ES256\"\n      ]\n    }\n  },\n  \"kmsResourceHandle\": \"krh_<opaque>\",\n  \"kmsKeyAlias\": \"issuer-signing-acme\",\n  \"signingKeyMode\": \"x5c\",\n  \"validityPeriod\": \"P365D\",\n  \"status\": {\n    \"statusListId\": \"mdoc-revocation\",\n    \"purpose\": \"revocation\",\n    \"revokeAtExpiry\": false\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "14 Hosted Branding Verification",
          "description": "Fetches the public VC type metadata, issuer metadata, and content-addressed branding asset without a bearer token. These checks verify what wallets and verifiers can read publicly.",
          "item": [
            {
              "name": "01 Fetch hosted VCT metadata",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{tenantGatewayUrl}}/public/schema/vct/EuPid",
                "header": [],
                "description": "Public SD-JWT VC Type Metadata for EuPid. Asserts localized displays (en/nl with lang), rendering.simple logo + colors, content-addressed uri#integrity when hosted, and lowercase claims[].sd."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.collectionVariables.set('brandingAssetsHosted', 'true');",
                      "pm.test('vct metadata served', () => pm.response.to.have.status(200));",
                      "const j = pm.response.json();",
                      "pm.test('vct present', () => pm.expect(j.vct, 'vct').to.be.a('string'));",
                      "const displays = j.display || [];",
                      "pm.test('display has en and nl entries', () => {",
                      "  const locales = displays.map((d) => d.locale);",
                      "  pm.expect(locales, 'display[].locale').to.include('en');",
                      "  pm.expect(locales, 'display[].locale').to.include('nl');",
                      "});",
                      "// Current SD-JWT VC Type Metadata uses `locale`; older drafts used `lang`.",
                      "pm.test('display entries use locale (not legacy lang)', () => {",
                      "  displays.forEach((d) => {",
                      "    pm.expect(d, 'display entry').to.have.property('locale');",
                      "    pm.expect(d, 'display entry').to.not.have.property('lang');",
                      "  });",
                      "});",
                      "const withSimple = displays.filter((d) => d.rendering && d.rendering.simple);",
                      "pm.test('display has rendering.simple', () => pm.expect(withSimple.length, 'display[].rendering.simple count').to.be.above(0));",
                      "const simpleLogos = withSimple.map((d) => d.rendering.simple.logo).filter(Boolean);",
                      "pm.test('rendering.simple has logo with uri under asset base', () => {",
                      "  pm.expect(simpleLogos.length, \"logos\").to.be.above(0);",
                      "  simpleLogos.forEach((logo) => {",
                      "    pm.expect(logo.uri, 'logo.uri').to.be.a('string');",
                      "  });",
                      "});",
                      "// Once binary assets are uploaded the uri is content-addressed under /public/assets/design/",
                      "// and carries a Subresource-Integrity sibling keyed literally as 'uri#integrity' (sha256-...).",
                      "const hostedLogos = simpleLogos.filter((l) => typeof l.uri === 'string' && l.uri.includes('/public/assets/design/'));",
                      "if (hostedLogos.length) {",
                      "  pm.test('hosted logo uri is content-addressed', () => {",
                      "    hostedLogos.forEach((l) => pm.expect(l.uri).to.include(\"/public/assets/design/\"));",
                      "  });",
                      "  pm.test('hosted logo carries uri#integrity sha256', () => {",
                      "    hostedLogos.forEach((l) => {",
                      "      pm.expect(l, \"logo\").to.have.property(\"uri#integrity\");",
                      "      pm.expect(l[\"uri#integrity\"], \"uri#integrity\").to.be.a(\"string\").and.to.match(/^sha256-/);",
                      "    });",
                      "  });",
                      "  // Same bytes -> same content-addressed url across en and nl displays (dedup).",
                      "  const enLogo = (displays.find((d) => d.locale === \"en\") || {}).rendering;",
                      "  const nlLogo = (displays.find((d) => d.locale === \"nl\") || {}).rendering;",
                      "  if (enLogo && enLogo.simple && enLogo.simple.logo && nlLogo && nlLogo.simple && nlLogo.simple.logo) {",
                      "    pm.test('en and nl displays share the same content-addressed logo uri', () =>",
                      "      pm.expect(enLogo.simple.logo.uri).to.eql(nlLogo.simple.logo.uri));",
                      "  }",
                      "  // Capture the hash leaf (last path segment) for the asset GET below.",
                      "  const leaf = String(hostedLogos[0].uri).split(\"/\").pop();",
                      "  if (leaf) pm.collectionVariables.set(\"eupidLogoHashLeaf\", leaf);",
                      "} else {",
                      "  pm.test('hosted (content-addressed) logo uri present in VCT', () => pm.expect(hostedLogos.length, 'hosted logos under /public/assets/design/').to.be.above(0));",
                      "  console.log('No /public/assets/design/ logo uri found in VCT - binary branding expected to be content-addressed.');",
                      "}",
                      "pm.test('rendering.simple has background_color and text_color', () => {",
                      "  withSimple.forEach((d) => {",
                      "    pm.expect(d.rendering.simple, 'rendering.simple').to.have.property('background_color');",
                      "    pm.expect(d.rendering.simple, 'rendering.simple').to.have.property('text_color');",
                      "  });",
                      "});",
                      "const claims = j.claims || [];",
                      "pm.test('claims carry localized display labels (en and nl)', () => {",
                      "  pm.expect(claims.length, \"claims\").to.be.above(0);",
                      "  const claimDisplays = claims.flatMap((cl) => cl.display || []);",
                      "  const claimLocales = claimDisplays.map((d) => d.locale);",
                      "  pm.expect(claimLocales, 'claims[].display[].locale').to.include('en');",
                      "  pm.expect(claimLocales, 'claims[].display[].locale').to.include('nl');",
                      "});",
                      "pm.test('claims[].sd is lowercase', () => {",
                      "  claims.forEach((cl) => {",
                      "    if (Object.prototype.hasOwnProperty.call(cl, 'sd')) {",
                      "      pm.expect([\"always\", \"allowed\", \"never\"], \"claims[].sd\").to.include(cl.sd);",
                      "    }",
                      "  });",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/public/schema/vct/EuPid",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n  \"display\": [\n    {\n      \"locale\": \"en\",\n      \"name\": \"EU Personal ID\",\n      \"description\": \"European personal identity credential\",\n      \"rendering\": {\n        \"simple\": {\n          \"logo\": {\n            \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n            \"uri#integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n            \"alt_text\": \"EU PID logo\"\n          },\n          \"background_color\": \"#0B5FFF\",\n          \"text_color\": \"#FFFFFF\"\n        }\n      }\n    },\n    {\n      \"locale\": \"nl\",\n      \"name\": \"EU Persoonlijke ID\",\n      \"description\": \"Europese persoonlijke identiteitscredential\",\n      \"rendering\": {\n        \"simple\": {\n          \"logo\": {\n            \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n            \"uri#integrity\": \"sha256-KzWC9QWgUrj4wBHq5sEM7MWQzy85Qajb7NGB5Mnw6GM=\",\n            \"alt_text\": \"EU PID logo\"\n          },\n          \"background_color\": \"#0B5FFF\",\n          \"text_color\": \"#FFFFFF\"\n        }\n      }\n    }\n  ],\n  \"claims\": [\n    {\n      \"path\": [\n        \"family_name\"\n      ],\n      \"display\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Family name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Achternaam\"\n        }\n      ],\n      \"sd\": \"never\"\n    },\n    {\n      \"path\": [\n        \"given_name\"\n      ],\n      \"display\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Given name\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Voornaam\"\n        }\n      ],\n      \"sd\": \"never\"\n    },\n    {\n      \"path\": [\n        \"birth_date\"\n      ],\n      \"display\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Date of birth\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Geboortedatum\"\n        }\n      ],\n      \"sd\": \"never\"\n    },\n    {\n      \"path\": [\n        \"age_over_18\"\n      ],\n      \"display\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Age over 18\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Ouder dan 18\"\n        }\n      ]\n    },\n    {\n      \"path\": [\n        \"nationality\"\n      ],\n      \"display\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Nationality\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Nationaliteit\"\n        }\n      ],\n      \"sd\": \"never\"\n    },\n    {\n      \"path\": [\n        \"issuing_authority\"\n      ],\n      \"display\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing authority\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Uitgevende autoriteit\"\n        }\n      ],\n      \"sd\": \"never\"\n    },\n    {\n      \"path\": [\n        \"issuing_country\"\n      ],\n      \"display\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Issuing country\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Land van uitgifte\"\n        }\n      ],\n      \"sd\": \"never\"\n    },\n    {\n      \"path\": [\n        \"document_number\"\n      ],\n      \"display\": [\n        {\n          \"locale\": \"en\",\n          \"label\": \"Document number\"\n        },\n        {\n          \"locale\": \"nl\",\n          \"label\": \"Documentnummer\"\n        }\n      ]\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Fetch issuer well-known metadata",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{tenantGatewayUrl}}/.well-known/openid-credential-issuer",
                "header": [],
                "description": "Public OID4VCI issuer metadata. Asserts top-level issuer display (name + logo, en/nl) and the EuPid configuration credential_metadata display (logo, colors, claims) using the locale key."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('issuer metadata served', () => pm.response.to.have.status(200));",
                      "const j = pm.response.json();",
                      "const display = j.display || [];",
                      "pm.test('top-level display has issuer name and logo (en and nl)', () => {",
                      "  pm.expect(display.length, \"display\").to.be.above(0);",
                      "  const locales = display.map((d) => d.locale);",
                      "  pm.expect(locales, 'display[].locale').to.include('en');",
                      "  pm.expect(locales, 'display[].locale').to.include('nl');",
                      "  display.forEach((d) => {",
                      "    pm.expect(d, 'display entry').to.have.property('name');",
                      "    pm.expect(d, 'display entry').to.have.property('logo');",
                      "    pm.expect(d.logo, 'display.logo').to.have.property('uri');",
                      "  });",
                      "});",
                      "pm.test('issuer metadata uses locale key (not lang)', () => {",
                      "  display.forEach((d) => pm.expect(d, 'display entry').to.not.have.property('lang'));",
                      "});",
                      "const cfgs = j.credential_configurations_supported || {};",
                      "pm.test('EuPid configuration present with branding metadata', () => {",
                      "  const eupid = cfgs.EuPid;",
                      "  pm.expect(eupid, 'credential_configurations_supported.EuPid').to.be.an('object');",
                      "  const meta = eupid.credential_metadata || eupid;",
                      "  const md = meta.display || eupid.display || [];",
                      "  pm.expect(md.length, 'EuPid display').to.be.above(0);",
                      "  const withLogo = md.filter((d) => d.logo && d.logo.uri);",
                      "  pm.expect(withLogo.length, 'EuPid display[].logo.uri').to.be.above(0);",
                      "  const withColors = md.filter((d) => Object.prototype.hasOwnProperty.call(d, \"background_color\"));",
                      "  pm.expect(withColors.length, 'EuPid display[].background_color').to.be.above(0);",
                      "  const claims = meta.claims || [];",
                      "  pm.expect(claims.length, 'EuPid credential_metadata.claims').to.be.above(0);",
                      "  const claimLocales = claims.flatMap((cl) => cl.display || []).map((d) => d.locale);",
                      "  pm.expect(claimLocales, 'EuPid claims[].display[].locale').to.include('en');",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/.well-known/openid-credential-issuer",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"authorization_servers\": [\n    \"https://acme.example.com/as/acme\"\n  ],\n  \"credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/credential\",\n  \"deferred_credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/deferredCredential\",\n  \"notification_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/notification\",\n  \"nonce_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/nonce\",\n  \"credential_configurations_supported\": {\n    \"EuPid\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu_pid\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\",\n        \"did:jwk\",\n        \"did:key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"EU Personal ID\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"European personal identity credential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"EU Persoonlijke ID\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"Europese persoonlijke identiteitscredential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"age_over_18\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Age over 18\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Ouder dan 18\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"nationality\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Nationality\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Nationaliteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"document_number\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"Mdl\": {\n      \"format\": \"mso_mdoc\",\n      \"scope\": \"mdl\",\n      \"cryptographic_binding_methods_supported\": [\n        \"cose_key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        -7\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"doctype\": \"org.iso.18013.5.1.mDL\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"Mobile Driving Licence\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobile driving licence\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"Mobiel Rijbewijs\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issue_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issue date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Datum van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"expiry_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Expiry date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Vervaldatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"document_number\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"portrait\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Portrait\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Portret\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"driving_privileges\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Driving privileges\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Rijbevoegdheden\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"un_distinguishing_sign\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"UN distinguishing sign\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"VN-onderscheidingsteken\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"EmployeeBadge\": {\n      \"format\": \"jwt_vc_json\",\n      \"scope\": \"employeebadge\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"EmployeeBadgeCredential\"\n        ]\n      }\n    },\n    \"Membership\": {\n      \"format\": \"jwt_vc_json-ld\",\n      \"scope\": \"membership\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"MembershipCredential\"\n        ]\n      }\n    },\n    \"EuPidShared\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu.europa.ec.eudi.pid.shared\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"urn:eudi:pid:shared\"\n    }\n  },\n  \"display\": [\n    {\n      \"name\": \"Acme Corporation Authority\",\n      \"locale\": \"en\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    },\n    {\n      \"name\": \"Acme Corporation Autoriteit\",\n      \"locale\": \"nl\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Fetch content-addressed asset",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{tenantGatewayUrl}}/public/assets/design/{{eupidLogoHashLeaf}}",
                "header": [],
                "description": "Fetches the public branding asset by its content-addressed path. This verifies that wallet-facing metadata points to a reachable image."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "if (pm.collectionVariables.get('brandingAssetsHosted') === 'false' || !pm.collectionVariables.get('eupidLogoHashLeaf')) {",
                      "  pm.test.skip('asset GET skipped (external-URI branding; binary upload not wired)');",
                      "} else {",
                      "  pm.test('content-addressed asset served', () => pm.response.to.have.status(200));",
                      "  pm.test('asset has an image content-type', () => {",
                      "    const ct = pm.response.headers.get('Content-Type') || '';",
                      "    pm.expect(ct, 'Content-Type').to.match(/^image\\//);",
                      "  });",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "image/png"
                    }
                  ],
                  "body": "�PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0000�\u0000\u0000\u0000�\b\u0006\u0000\u0000\u0000��g-\u0000\u0000\u0006\u0006IDATx��=kTA\u0014��\n��\b\u0004B\u0002)6�\u0010H\nI��.�B�\n��\u0011@��Z�\u0014V�@�����Hc)XY�S�7�\u001ca�\"ww�9�q�<\u0007^\b\u001b1�3O�w��{G#� \b� \b� \b� \n�����T��?���5;�\u00106\u0013+�k�SЎ�.o\u001f<z:A�%c=\u0005S��\u001dt;ル���\u001b`�C2\u00172'Mø��u\"uLxݒ9��j\n<V;���i\u0010e9\u001f�\u001f_3��%sh.5Kq��h˴�qЬzm��U�\\j=\u001f�au)Y~!R���\\\r��\u0007����A\b|�(�\u0018\u000e4kL�jA>�hdC�\u0001G]J�YM݇�փ�^T,\u0015Kg\u0004\u0003��(I\u0017\r�\u0017\u0015sŬ~��*H'3\n�Vs�\f(\n��#��U\u0018L\u0014\"a\u0007��\u0011�/*��9vCE��p���\u001b��\u0017i�\u000f\u0007\u0003�\u0000\"\rQ�!{u \u0000\"\u0000D~\u0001�\u0001��N\u0018\u0000\u0011\u0000\u0006��\u0017����6%�&\u00004\u0002߯�&��\\�U\b�\u0000�*|�!t\u0003����&��\\#\u0000\u0002\u001f\u0010\u0002��޼�0�\u0016r�\u0000X��!z\r�v\u0000,,�\u0001�\u0000\b�\u0000\b�\u0000\b�\u0000\b�\u0000\b�\u0000\u0018\u0014�����'��\u0001\u0010\u0000���O�;���3�\u001e\u0000\u0002`�s�g�_-�>�7�η\u0001\u0010\u0000��\u000f|�\u0010\u0002 \u0000\u0016=����\u0001\u0010\u0000�4\u0012�[\u0005\u0001\u0010\u0000\u00079]�k\u0005@\u0000��L��r\u0006�\u0000�+4:���0\u0000\u0002`��)R0\u0000\u0006m4��{\u0004@\u0000��:?�x\u000e\u0000\u00010��X�\u0007\b�\u0000��t���\u0000\u0000\u00010��\u0010�iFh\u0018@����>�\t�����d\u000f��\u0000\u0014�\u001a\u0001�X\u0018s�\u000e\u00004\f`��\u0018z���V%n�\u0007@#\u0000\u000e�ˆB��x��l\u00004\u0000`H\u0013@�ndmӱ��\u000f\u0000\r\u00038��sh*�t�!O�\u0002@\u0003\u0000j7\u0000�0\u001d���\u0003��\u0001�����2���ZO�\u0002��\u0001��4MG쓽\u0000��\u0014��NCk�\u0014O�\u0002��MH�3.m:\u0000��6Lji=�\u001a\u0000\u001b܈��8a\u00004t\u0014���S��\u0001�A\u0000�4\u0010�~́��k,-�\u000184�i6\rh����\u0001��)-�ĥz���\rO\u0000X �圼T�0�)�\u0015(&����/б�ڮ�_T\u0013��R:��0)U�\u0002��*��\u0019����h@\\\u0000\u0018��h�&9��i��s\u0001���%n(j}\u0003�\u0015�\u001a'\f\u001a�8�[;�l��\u0002P��Im�^�XÑ\"\u0000&L}!\u0013�\u000b>+�o.\u0001�zo�Pg��th?y\u0001\u0000+��\u000baN�,���\u0005P3\u0015ʄ/�\t�{�೶��\u0016�\u0014� \u0002ٴ\u001d_$_�\u0004�j��\u0016�ԧ\u0010%�u\r`���am�\u000f\u00003�����J�\u000b\u0000\u0016ڛ�x\u0000`���z�\u0005@��ܩ���w\u000f��z���\u000f\u0000\r׃-�}\u0000�𬘳^\u0000��_�C�=\u00006\u0006a��\u0001`��y\u000f�\u0000h�\u0019��x\u0001�\u0010�\u001e�\u0003�J!�\u0002\u001f\u0000V\b�'�\u0000�2wܲ�\u0005��!�\b\u001f\u0000V\u0002�W�\u0000������v\u00010#�1�d�]u\u0000\b��\u001c�7�\u000b�\u0015Յ��=5\u00007��.\u0018���\\-�S�JX\u0002@�{��R�|f��]\u00004V\u0017Φd��zO\u0019@\t\u0006oyJ&�.�(4��.o\u0019@\u0014#a(\u0018@�0* \u0003Q��Obeum�AD1\u0012�F1qxz~�@�\u0010\t;���\u0019\u001f\\1�(D�N4��aT,��Q\u0011���ol�0�h����f`FPV��*��Y��1�?�f��\"\t#�T!���a���W��r<��\u001e���Q��\u0017W���^�ATM�\u0007��:��\u0010���\u0007��WM�/�1�a8���-\u001a�Z�\nِ$%��r�m2k�dV�6V��Sn�.\u001ajC��^���R �Ym���)�R�ܬªX�j'sb:Ն�(ŭ��aZ�\n\u0019s\u0019{w��q�S� �x͎)�\u0011\u0004A\u0010\u0004A\u0010\u0004A\u0010D��\u000b�,9���a�\u0000\u0000\u0000\u0000IEND�B`�",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "15 Issue SD-JWT VC and mdoc",
          "description": "Issues EuPid and Mdl credentials with subject data supplied directly at offer creation, then follows the wallet-facing offer, token, proof, and credential request steps. The folder pre-request script owns an ephemeral collection-local P-256 holder fixture; its private scalar remains in the runner sandbox and only the public JWK enters proof JWTs.\n\nDocumentation: https://docs.sphereon.com/edk/admin-console/guides/issue-credentials",
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// Minimal collection-local P-256 holder fixture for Postman/Newman.",
                  "// The private scalar stays in a runtime collection variable and is never sent or logged.",
                  "const CURVE_P = BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff');",
                  "const CURVE_A = CURVE_P - 3n;",
                  "const CURVE_N = BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551');",
                  "const CURVE_G = {",
                  "  x: BigInt('0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296'),",
                  "  y: BigInt('0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5')",
                  "};",
                  "const mod = (value, modulus) => {",
                  "  const result = value % modulus;",
                  "  return result >= 0n ? result : result + modulus;",
                  "};",
                  "const inverse = (value, modulus) => {",
                  "  let low = mod(value, modulus);",
                  "  let high = modulus;",
                  "  let lowCoefficient = 1n;",
                  "  let highCoefficient = 0n;",
                  "  while (low > 1n) {",
                  "    const ratio = high / low;",
                  "    const next = high - low * ratio;",
                  "    const nextCoefficient = highCoefficient - lowCoefficient * ratio;",
                  "    high = low;",
                  "    low = next;",
                  "    highCoefficient = lowCoefficient;",
                  "    lowCoefficient = nextCoefficient;",
                  "  }",
                  "  if (low !== 1n) throw new Error('P-256 modular inverse does not exist');",
                  "  return mod(lowCoefficient, modulus);",
                  "};",
                  "const pointAdd = (left, right) => {",
                  "  if (!left) return right;",
                  "  if (!right) return left;",
                  "  let slope;",
                  "  if (left.x === right.x) {",
                  "    if (mod(left.y + right.y, CURVE_P) === 0n) return null;",
                  "    slope = mod((3n * left.x * left.x + CURVE_A) * inverse(2n * left.y, CURVE_P), CURVE_P);",
                  "  } else {",
                  "    slope = mod((right.y - left.y) * inverse(right.x - left.x, CURVE_P), CURVE_P);",
                  "  }",
                  "  const x = mod(slope * slope - left.x - right.x, CURVE_P);",
                  "  return { x: x, y: mod(slope * (left.x - x) - left.y, CURVE_P) };",
                  "};",
                  "const scalarMultiply = (scalar, point) => {",
                  "  let remaining = scalar;",
                  "  let result = null;",
                  "  let addend = point;",
                  "  while (remaining > 0n) {",
                  "    if ((remaining & 1n) === 1n) result = pointAdd(result, addend);",
                  "    addend = pointAdd(addend, addend);",
                  "    remaining >>= 1n;",
                  "  }",
                  "  return result;",
                  "};",
                  "const randomScalar = () => {",
                  "  while (true) {",
                  "    const candidateHex = CryptoJS.lib.WordArray.random(32).toString(CryptoJS.enc.Hex);",
                  "    const candidate = BigInt('0x' + candidateHex);",
                  "    if (candidate > 0n && candidate < CURVE_N) return candidate;",
                  "  }",
                  "};",
                  "const hex32 = (value) => value.toString(16).padStart(64, '0');",
                  "const base64Url = (wordArray) => CryptoJS.enc.Base64.stringify(wordArray).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');",
                  "const base64UrlHex = (hex) => base64Url(CryptoJS.enc.Hex.parse(hex));",
                  "const base64UrlJson = (value) => base64Url(CryptoJS.enc.Utf8.parse(JSON.stringify(value)));",
                  "if (pm.info.requestName === '01 Create EuPid offer') {",
                  "  pm.collectionVariables.unset('holderWalletPrivateScalar');",
                  "  pm.collectionVariables.unset('holderWalletPublicJwk');",
                  "  pm.collectionVariables.unset('proofJwt');",
                  "}",
                  "let holderPrivateHex = String(pm.collectionVariables.get('holderWalletPrivateScalar') || '');",
                  "let holderPublicJwkText = String(pm.collectionVariables.get('holderWalletPublicJwk') || '');",
                  "let holderPublicJwk;",
                  "try { holderPublicJwk = JSON.parse(holderPublicJwkText); } catch (_) { holderPublicJwk = null; }",
                  "if (!/^[0-9a-f]{64}$/.test(holderPrivateHex) || !holderPublicJwk || holderPublicJwk.kty !== 'EC' || holderPublicJwk.crv !== 'P-256') {",
                  "  const holderPrivate = randomScalar();",
                  "  const holderPublic = scalarMultiply(holderPrivate, CURVE_G);",
                  "  holderPrivateHex = hex32(holderPrivate);",
                  "  holderPublicJwk = { kty: 'EC', crv: 'P-256', x: base64UrlHex(hex32(holderPublic.x)), y: base64UrlHex(hex32(holderPublic.y)) };",
                  "  holderPublicJwkText = JSON.stringify(holderPublicJwk);",
                  "  pm.collectionVariables.set('holderWalletPrivateScalar', holderPrivateHex);",
                  "  pm.collectionVariables.set('holderWalletPublicJwk', holderPublicJwkText);",
                  "}",
                  "const signEs256 = (signingInput) => {",
                  "  const privateScalar = BigInt('0x' + holderPrivateHex);",
                  "  const digest = BigInt('0x' + CryptoJS.SHA256(signingInput).toString(CryptoJS.enc.Hex));",
                  "  while (true) {",
                  "    const ephemeral = randomScalar();",
                  "    const point = scalarMultiply(ephemeral, CURVE_G);",
                  "    const r = mod(point.x, CURVE_N);",
                  "    if (r === 0n) continue;",
                  "    let s = mod(inverse(ephemeral, CURVE_N) * (digest + r * privateScalar), CURVE_N);",
                  "    if (s === 0n) continue;",
                  "    if (s > CURVE_N / 2n) s = CURVE_N - s;",
                  "    return base64UrlHex(hex32(r) + hex32(s));",
                  "  }",
                  "};",
                  "const buildHolderProof = (nonce) => {",
                  "  const header = { alg: 'ES256', typ: 'openid4vci-proof+jwt', jwk: holderPublicJwk };",
                  "  const payload = {",
                  "    aud: pm.collectionVariables.get('credentialIssuer') || pm.variables.get('tenantGatewayUrl'),",
                  "    iat: Math.floor(Date.now() / 1000)",
                  "  };",
                  "  if (nonce) payload.nonce = nonce;",
                  "  const signingInput = base64UrlJson(header) + '.' + base64UrlJson(payload);",
                  "  pm.collectionVariables.set('proofJwt', signingInput + '.' + signEs256(signingInput));",
                  "};",
                  "if (pm.info.requestName === '05 Request EuPid credential' || pm.info.requestName === '10 Request Mdl credential') {",
                  "  const nonceEndpoint = pm.collectionVariables.get('nonceEndpoint');",
                  "  if (nonceEndpoint) {",
                  "    pm.sendRequest({ url: nonceEndpoint, method: 'POST', header: { 'Host': pm.variables.get('tenantHost') } }, (error, response) => {",
                  "      if (error) throw new Error('OID4VCI nonce fetch failed: ' + error.message);",
                  "      const nonce = response.json().c_nonce;",
                  "      if (!nonce) throw new Error('OID4VCI nonce response did not contain c_nonce');",
                  "      pm.collectionVariables.set(pm.info.requestName === '05 Request EuPid credential' ? 'euPidNonce' : 'mdlNonce', nonce);",
                  "      buildHolderProof(nonce);",
                  "    });",
                  "  } else {",
                  "    buildHolderProof(undefined);",
                  "  }",
                  "}"
                ]
              }
            }
          ],
          "item": [
            {
              "name": "01 Create EuPid offer",
              "request": {
                "method": "POST",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_configuration_ids\": [\"EuPid\"],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"family_name\": \"Mustermann\",\n    \"given_name\": \"Erika\",\n    \"birth_date\": \"1964-08-12\",\n    \"age_over_18\": true,\n    \"nationality\": \"DE\",\n    \"issuing_authority\": \"DE\",\n    \"issuing_country\": \"DE\",\n    \"document_number\": \"1234567890\"\n  },\n  \"correlation_id\": \"e2e-eupid-001\"\n}"
                },
                "description": "Creates a pre-authorized credential offer with the subject data supplied inline. The response carries the offer URI a wallet would scan."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "console.log('DBG-offer-create', String(pm.response.code), String(pm.response.text() || '').slice(0, 900));",
                      "pm.test('offer created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url, base) => {",
                      "  const publicHost = pm.variables.get('tenantHost');",
                      "  const gatewayBase = trimBase(base || pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && publicHost && m[2] === publicHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "if (j.offer_uri) {",
                      "  pm.collectionVariables.set('offerUri', j.offer_uri);",
                      "  const m = j.offer_uri.match(/credential_offer_uri=([^&]+)/);",
                      "  if (m) pm.collectionVariables.set('credentialOfferUri', rewritePublicUrl(decodeURIComponent(m[1]), pm.variables.get('tenantGatewayUrl')));",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/credential/offers",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_configuration_ids\": [\n    \"EuPid\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"family_name\": \"Mustermann\",\n    \"given_name\": \"Erika\",\n    \"birth_date\": \"1964-08-12\",\n    \"age_over_18\": true,\n    \"nationality\": \"DE\",\n    \"issuing_authority\": \"DE\",\n    \"issuing_country\": \"DE\",\n    \"document_number\": \"1234567890\"\n  },\n  \"correlation_id\": \"e2e-eupid-001\"\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"e2e-eupid-001\",\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"offer_uri\": \"openid-credential-offer://?credential_offer_uri=https%3A%2F%2Facme.example.com%2Foid4vci%2Facme%2Foid4vci%2Fcredentials%2Foffers%2F00000000-0000-4000-8000-000000000000\",\n  \"status_uri\": \"https://acme.example.com/api/oid4vci/v1/backend/credential/offers/e2e-eupid-001\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Resolve credential offer",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [],
                "url": "{{credentialOfferUri}}",
                "description": "Resolves the offer exactly as a wallet does and extracts the pre-authorized code."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "console.log('DBG-offer-resolve', String(pm.response.code), String(pm.response.text() || '').slice(0, 900));",
                      "pm.test('offer resolved', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url, base) => {",
                      "  const publicHost = pm.variables.get('tenantHost');",
                      "  const gatewayBase = trimBase(base || pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && publicHost && m[2] === publicHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "const j = pm.response.json();",
                      "pm.test('resolved EuPid offer carries exact credential configuration id', () => {",
                      "  // Every hosted instance publishes under its own path, so the credential issuer identifier is the tenant origin plus that path, never the bare origin.",
                      "  const gw = trimBase(pm.variables.get('tenantGatewayUrl'));",
                      "  pm.expect(j.credential_issuer, 'credential issuer identifier').to.be.a('string').and.to.satisfy((v) => v === gw || v.indexOf(gw + '/') === 0);",
                      "  pm.expect(j.credential_configuration_ids).to.eql(['EuPid']);",
                      "});",
                      "const grant = j.grants && (j.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'] || j.grants.pre_authorized_code);",
                      "if (grant && grant['pre-authorized_code']) pm.collectionVariables.set('preAuthCode', grant['pre-authorized_code']);",
                      "// OID4VCI 1.0: for a path-bearing issuer identifier the metadata URL inserts",
                      "// the well-known segment between host and path.",
                      "if (j.credential_issuer) {",
                      "  pm.collectionVariables.set('credentialIssuerPublic', j.credential_issuer);",
                      "  pm.collectionVariables.set('credentialIssuer', j.credential_issuer);",
                      "  const m = j.credential_issuer.match(/^(https?:\\/\\/[^/]+)(\\/.*)?$/);",
                      "  if (m) pm.collectionVariables.set('issuerMetadataUrl', rewritePublicUrl(m[1] + '/.well-known/openid-credential-issuer' + (m[2] || ''), pm.variables.get('tenantGatewayUrl')));",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credentials/offers/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"credential_configuration_ids\": [\n    \"EuPid\"\n  ],\n  \"grants\": {\n    \"urn:ietf:params:oauth:grant-type:pre-authorized_code\": {\n      \"pre-authorized_code\": \"<code>\"\n    }\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Fetch OID4VCI metadata",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [],
                "url": "{{issuerMetadataUrl}}",
                "description": "OID4VCI metadata: credential configurations, endpoints, and authorization-server references served through the tenant gateway. The URL derives from the offer's credential_issuer per OID4VCI 1.0 (the well-known segment goes between host and issuer path)."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('OID4VCI metadata served', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url, base) => {",
                      "  const issuerHost = pm.variables.get('tenantHost');",
                      "  const asHost = pm.variables.get('tenantHost') || issuerHost;",
                      "  const gatewayBase = trimBase(base || pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && issuerHost && m[2] === issuerHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  if (m && asHost && m[2] === asHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "const j = pm.response.json();",
                      "const configurations = j.credential_configurations_supported || {};",
                      "const eupidConfiguration = configurations.EuPid;",
                      "const mdlConfiguration = configurations.Mdl;",
                      "pm.test('sample credential metadata separates PID and mdoc contracts', () => {",
                      "  pm.expect(eupidConfiguration).to.be.an('object');",
                      "  pm.expect(eupidConfiguration.format).to.eql('dc+sd-jwt');",
                      "  pm.expect(mdlConfiguration).to.be.an('object');",
                      "  pm.expect(mdlConfiguration.format).to.eql('mso_mdoc');",
                      "  pm.expect(mdlConfiguration.cryptographic_binding_methods_supported).to.eql(['cose_key']);",
                      "  pm.expect(mdlConfiguration).not.to.have.property('status');",
                      "});",
                      "if (j.credential_endpoint) pm.collectionVariables.set('credentialEndpoint', rewritePublicUrl(j.credential_endpoint, pm.variables.get('tenantGatewayUrl')));",
                      "const advertisedAs = Array.isArray(j.authorization_servers) && j.authorization_servers.length ? j.authorization_servers[0] : null;",
                      "pm.expect(advertisedAs || j.token_endpoint, 'issuer metadata advertises an authorization server or token endpoint').to.be.a('string');",
                      "const tokenEndpoint = rewritePublicUrl(j.token_endpoint || (advertisedAs.replace(/\\/$/, '') + '/token'), pm.variables.get('tenantGatewayUrl'));",
                      "pm.collectionVariables.set('tokenEndpoint', tokenEndpoint);",
                      "if (j.nonce_endpoint) pm.collectionVariables.set('nonceEndpoint', rewritePublicUrl(j.nonce_endpoint, pm.variables.get('tenantGatewayUrl')));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/.well-known/openid-credential-issuer/oid4vci/acme",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"authorization_servers\": [\n    \"https://acme.example.com/as/acme\"\n  ],\n  \"credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/credential\",\n  \"deferred_credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/deferredCredential\",\n  \"notification_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/notification\",\n  \"nonce_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/nonce\",\n  \"credential_configurations_supported\": {\n    \"EuPid\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu_pid\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\",\n        \"did:jwk\",\n        \"did:key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"EU Personal ID\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"European personal identity credential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"EU Persoonlijke ID\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"Europese persoonlijke identiteitscredential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"age_over_18\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Age over 18\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Ouder dan 18\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"nationality\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Nationality\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Nationaliteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"document_number\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"Mdl\": {\n      \"format\": \"mso_mdoc\",\n      \"scope\": \"mdl\",\n      \"cryptographic_binding_methods_supported\": [\n        \"cose_key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        -7\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"doctype\": \"org.iso.18013.5.1.mDL\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"Mobile Driving Licence\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobile driving licence\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"Mobiel Rijbewijs\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issue_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issue date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Datum van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"expiry_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Expiry date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Vervaldatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"document_number\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"portrait\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Portrait\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Portret\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"driving_privileges\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Driving privileges\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Rijbevoegdheden\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"un_distinguishing_sign\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"UN distinguishing sign\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"VN-onderscheidingsteken\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"EmployeeBadge\": {\n      \"format\": \"jwt_vc_json\",\n      \"scope\": \"employeebadge\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"EmployeeBadgeCredential\"\n        ]\n      }\n    },\n    \"Membership\": {\n      \"format\": \"jwt_vc_json-ld\",\n      \"scope\": \"membership\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"MembershipCredential\"\n        ]\n      }\n    },\n    \"EuPidShared\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu.europa.ec.eudi.pid.shared\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"urn:eudi:pid:shared\"\n    }\n  },\n  \"display\": [\n    {\n      \"name\": \"Acme Corporation Authority\",\n      \"locale\": \"en\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    },\n    {\n      \"name\": \"Acme Corporation Autoriteit\",\n      \"locale\": \"nl\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Exchange pre-authorized code for token",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "url": "{{tokenEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/x-www-form-urlencoded"
                  }
                ],
                "body": {
                  "mode": "urlencoded",
                  "urlencoded": [
                    {
                      "key": "grant_type",
                      "value": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
                    },
                    {
                      "key": "pre-authorized_code",
                      "value": "{{preAuthCode}}"
                    }
                  ]
                },
                "description": "Token request with the pre-authorized code grant. The response carries the access token for the credential endpoint and a nonce for the proof of possession."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "console.log('DBG-token-exchange', String(pm.response.code), String(pm.response.text() || '').slice(0, 900));",
                      "pm.test('token issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const credentialAuthorization = Array.isArray(j.authorization_details) ? j.authorization_details.find((detail) => detail && detail.credential_configuration_id === 'EuPid') : undefined;",
                      "const credentialIdentifiers = credentialAuthorization && credentialAuthorization.credential_identifiers;",
                      "pm.test('pre-authorized token returns an opaque EuPid credential identifier distinct from its configuration id', () => {",
                      "  pm.expect(credentialAuthorization).to.be.an('object');",
                      "  pm.expect(credentialAuthorization.type).to.eql('openid_credential');",
                      "  pm.expect(credentialIdentifiers).to.be.an('array').with.lengthOf(1);",
                      "  pm.expect(credentialIdentifiers[0]).to.be.a('string').and.not.empty;",
                      "  pm.expect(credentialIdentifiers[0]).not.to.eql(credentialAuthorization.credential_configuration_id);",
                      "});",
                      "pm.collectionVariables.set('credentialIdentifier', credentialIdentifiers ? credentialIdentifiers[0] : '');",
                      "if (j.access_token) pm.collectionVariables.set('walletAccessToken', j.access_token);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/as/acme/token",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/x-www-form-urlencoded"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "\"grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code&pre-authorized_code=%3Credacted%3E\""
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"access_token\": \"eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6Im9hdXRoMi1hcy1hY21lIn0.eyJpc3MiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vYXMvYWNtZSIsInN1YiI6IiIsImNsaWVudF9pZCI6IiIsImlhdCI6MTc2NzIyNTYwMCwiZXhwIjoxNzk4NzYxNjAwLCJqdGkiOiI8anRpPiIsImF6cCI6IiIsImF1ZCI6Imh0dHBzOi8vYWNtZS5leGFtcGxlLmNvbS9vaWQ0dmNpL2FjbWUiLCJhdXRob3JpemF0aW9uX2RldGFpbHMiOlt7InR5cGUiOiJvcGVuaWRfY3JlZGVudGlhbCIsImNyZWRlbnRpYWxfY29uZmlndXJhdGlvbl9pZCI6IkV1UGlkIiwiY3JlZGVudGlhbF9pZGVudGlmaWVycyI6WyJ1cm46dmR4Om9pZDR2Y2k6Y3JlZGVudGlhbDowMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDA6MDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAwIl19XSwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAwIn0.SIGNATURE-REDACTED\",\n  \"access_token_decoded\": {\n    \"header\": {\n      \"typ\": \"at+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"oauth2-as-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"https://acme.example.com/as/acme\",\n      \"sub\": \"\",\n      \"client_id\": \"\",\n      \"iat\": 1767225600,\n      \"exp\": 1798761600,\n      \"jti\": \"<jti>\",\n      \"azp\": \"\",\n      \"aud\": \"https://acme.example.com/oid4vci/acme\",\n      \"authorization_details\": [\n        {\n          \"type\": \"openid_credential\",\n          \"credential_configuration_id\": \"EuPid\",\n          \"credential_identifiers\": [\n            \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n          ]\n        }\n      ],\n      \"tenant_id\": \"00000000-0000-4000-8000-000000000000\"\n    }\n  },\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 3600,\n  \"authorization_details\": [\n    {\n      \"type\": \"openid_credential\",\n      \"credential_configuration_id\": \"EuPid\",\n      \"credential_identifiers\": [\n        \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n      ]\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Request EuPid credential",
              "request": {
                "auth": {
                  "type": "bearer",
                  "bearer": [
                    {
                      "key": "token",
                      "value": "{{walletAccessToken}}",
                      "type": "string"
                    }
                  ]
                },
                "method": "POST",
                "url": "{{credentialEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_identifier\": \"{{credentialIdentifier}}\",\n  \"proofs\": {\n    \"jwt\": [\"{{proofJwt}}\"]\n  }\n}"
                },
                "description": "OpenID4VCI 1.0 Final credential request selecting the EuPid credential_identifier returned in the token response and carrying an ES256 proof of possession (typ openid4vci-proof+jwt) signed by the collection-local holder fixture. The private scalar remains in the Postman/Newman sandbox; only its public JWK is sent. The response carries the SD-JWT credential including the status claim that references the hosted status list."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('eupid credential issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const cred = (j.credentials && j.credentials[0] && j.credentials[0].credential) || j.credential;",
                      "if (cred) pm.collectionVariables.set('eupidCredential', cred);",
                      "const decodeJwtPart = (jwt, index) => {",
                      "  const compact = String(jwt || '').split('~')[0];",
                      "  const segment = compact.split('.')[index];",
                      "  pm.expect(segment, 'jwt segment ' + index).to.be.a('string').and.not.empty;",
                      "  const normalized = segment.replace(/-/g, '+').replace(/_/g, '/');",
                      "  const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);",
                      "  return JSON.parse(atob(padded));",
                      "};",
                      "const eupidHeader = decodeJwtPart(cred, 0);",
                      "const eupidPayload = decodeJwtPart(cred, 1);",
                      "pm.test('EuPid credential carries expected VCT and status-list reference', () => {",
                      "  const vctValue = String(eupidPayload.vct || '');",
                      "pm.expect(vctValue, 'vct actual=' + vctValue).to.eql(String(pm.variables.get('tenantGatewayUrl')).replace(new RegExp('/+$'), '') + '/public/schema/vct/EuPid');",
                      "  const statusUriValue = String((eupidPayload.status && eupidPayload.status.status_list && eupidPayload.status.status_list.uri) || '');",
                      "pm.expect(statusUriValue, 'status list actual=' + statusUriValue).to.eql(String(pm.variables.get('tenantGatewayUrl')).replace(new RegExp('/+$'), '') + '/public/statuslists/eupid-revocation');",
                      "  pm.expect(eupidPayload.status.status_list.idx).to.be.a('number');",
                      "});",
                      "pm.test('EuPid credential and status list use the same did:web signer identity', () => {",
                      "  pm.expect(eupidPayload.iss).to.eql(pm.variables.get('did'));",
                      "  pm.expect(eupidPayload.iss).to.eql(pm.collectionVariables.get('statusListSignerDid'));",
                      "  pm.expect(eupidHeader.kid, 'EuPid DID verification-method kid').to.be.a('string').and.not.empty;",
                      "  pm.expect(eupidHeader.kid.startsWith(eupidPayload.iss + '#')).to.eql(true);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credential",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_identifier\": \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\",\n  \"proofs\": {\n    \"jwt\": [\n      \"eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiPHB1YmxpYy1rZXktbWF0ZXJpYWw-IiwieSI6IjxwdWJsaWMta2V5LW1hdGVyaWFsPiJ9fQ.eyJhdWQiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vb2lkNHZjaS9hY21lIiwiaWF0IjoxNzY3MjI1NjAwLCJub25jZSI6Ijxub25jZT4ifQ.SIGNATURE-REDACTED\"\n    ]\n  }\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credentials\": [\n    {\n      \"credential\": \"eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDp3ZWI6YWNtZS5leGFtcGxlLmNvbSNpc3N1ZXItYXNzZXJ0aW9uLWFjbWUifQ.eyJpc3MiOiJkaWQ6d2ViOmFjbWUuZXhhbXBsZS5jb20iLCJ2Y3QiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3NjaGVtYS92Y3QvRXVQaWQiLCJqdGkiOiI8anRpPiIsImlhdCI6MTc2NzIyNTYwMCwiZXhwIjoxNzk4NzYxNjAwLCJzdGF0dXMiOnsic3RhdHVzX2xpc3QiOnsiaWR4IjoxMDAzLCJ1cmkiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL2V1cGlkLXJldm9jYXRpb24ifX0sImNuZiI6eyJqd2siOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiI8cHVibGljLWtleS1tYXRlcmlhbD4iLCJ5IjoiPHB1YmxpYy1rZXktbWF0ZXJpYWw-In19LCJfc2QiOlsiPGRpZ2VzdD4iLCI8ZGlnZXN0PiIsIjxkaWdlc3Q-IiwiPGRpZ2VzdD4iLCI8ZGlnZXN0PiIsIjxkaWdlc3Q-IiwiPGRpZ2VzdD4iLCI8ZGlnZXN0PiJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.SIGNATURE-REDACTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~\",\n      \"credential_decoded\": {\n        \"header\": {\n          \"typ\": \"dc+sd-jwt\",\n          \"alg\": \"ES256\",\n          \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\"\n        },\n        \"payload\": {\n          \"iss\": \"did:web:acme.example.com\",\n          \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n          \"jti\": \"<jti>\",\n          \"iat\": 1767225600,\n          \"exp\": 1798761600,\n          \"status\": {\n            \"status_list\": {\n              \"idx\": 1003,\n              \"uri\": \"https://acme.example.com/public/statuslists/eupid-revocation\"\n            }\n          },\n          \"cnf\": {\n            \"jwk\": {\n              \"kty\": \"EC\",\n              \"crv\": \"P-256\",\n              \"x\": \"<public-key-material>\",\n              \"y\": \"<public-key-material>\"\n            }\n          },\n          \"_sd\": [\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\"\n          ],\n          \"_sd_alg\": \"sha-256\"\n        },\n        \"disclosures\": [\n          [\n            \"<salt>\",\n            \"family_name\",\n            \"Mustermann\"\n          ],\n          [\n            \"<salt>\",\n            \"given_name\",\n            \"Erika\"\n          ],\n          [\n            \"<salt>\",\n            \"birth_date\",\n            \"1964-08-12\"\n          ],\n          [\n            \"<salt>\",\n            \"age_over_18\",\n            true\n          ],\n          [\n            \"<salt>\",\n            \"nationality\",\n            \"DE\"\n          ],\n          [\n            \"<salt>\",\n            \"issuing_authority\",\n            \"DE\"\n          ],\n          [\n            \"<salt>\",\n            \"issuing_country\",\n            \"DE\"\n          ],\n          [\n            \"<salt>\",\n            \"document_number\",\n            \"1234567890\"\n          ]\n        ]\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 Check EuPid offer status",
              "request": {
                "method": "GET",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers/e2e-eupid-001",
                "description": "Backend session status after issuance: the lifecycle ends in credential_issued.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('session tracked', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/credential/offers/e2e-eupid-001",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"e2e-eupid-001\",\n  \"status\": \"credential_issued\",\n  \"last_updated\": 1767225600000,\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"offer_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"issuance_session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"created_at\": 1767225600000,\n  \"expires_at\": 1798761600000,\n  \"error\": null,\n  \"issuance_data\": {\n    \"credential_configuration_ids\": [\n      \"EuPid\"\n    ],\n    \"credential_identifiers\": null\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "07 Create Mdl offer",
              "request": {
                "method": "POST",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_configuration_ids\": [\"Mdl\"],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"org.iso.18013.5.1.family_name\": \"Mustermann\",\n    \"org.iso.18013.5.1.given_name\": \"Erika\",\n    \"org.iso.18013.5.1.birth_date\": \"1964-08-12\",\n    \"org.iso.18013.5.1.issue_date\": \"2026-01-15\",\n    \"org.iso.18013.5.1.expiry_date\": \"2031-01-15\",\n    \"org.iso.18013.5.1.issuing_country\": \"DE\",\n    \"org.iso.18013.5.1.issuing_authority\": \"DE\",\n    \"org.iso.18013.5.1.document_number\": \"D123456789\",\n    \"org.iso.18013.5.1.portrait\": \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n    \"org.iso.18013.5.1.driving_privileges\": [\n      {\n        \"vehicle_category_code\": \"B\",\n        \"issue_date\": \"2010-03-01\",\n        \"expiry_date\": \"2031-01-15\"\n      }\n    ],\n    \"org.iso.18013.5.1.un_distinguishing_sign\": \"D\"\n  },\n  \"correlation_id\": \"e2e-mdl-001\"\n}"
                },
                "description": "Pre-authorized offer for the mdoc credential with namespace-qualified subject data."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('mdl offer created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url, base) => {",
                      "  const publicHost = pm.variables.get('tenantHost');",
                      "  const gatewayBase = trimBase(base || pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && publicHost && m[2] === publicHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "if (j.offer_uri) {",
                      "  const m = j.offer_uri.match(/credential_offer_uri=([^&]+)/);",
                      "  if (m) pm.collectionVariables.set('mdlCredentialOfferUri', rewritePublicUrl(decodeURIComponent(m[1]), pm.variables.get('tenantGatewayUrl')));",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/credential/offers",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_configuration_ids\": [\n    \"Mdl\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"org.iso.18013.5.1.family_name\": \"Mustermann\",\n    \"org.iso.18013.5.1.given_name\": \"Erika\",\n    \"org.iso.18013.5.1.birth_date\": \"1964-08-12\",\n    \"org.iso.18013.5.1.issue_date\": \"2026-01-15\",\n    \"org.iso.18013.5.1.expiry_date\": \"2031-01-15\",\n    \"org.iso.18013.5.1.issuing_country\": \"DE\",\n    \"org.iso.18013.5.1.issuing_authority\": \"DE\",\n    \"org.iso.18013.5.1.document_number\": \"D123456789\",\n    \"org.iso.18013.5.1.portrait\": \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==\",\n    \"org.iso.18013.5.1.driving_privileges\": [\n      {\n        \"vehicle_category_code\": \"B\",\n        \"issue_date\": \"2010-03-01\",\n        \"expiry_date\": \"2031-01-15\"\n      }\n    ],\n    \"org.iso.18013.5.1.un_distinguishing_sign\": \"D\"\n  },\n  \"correlation_id\": \"e2e-mdl-001\"\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"e2e-mdl-001\",\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"offer_uri\": \"openid-credential-offer://?credential_offer_uri=https%3A%2F%2Facme.example.com%2Foid4vci%2Facme%2Foid4vci%2Fcredentials%2Foffers%2F00000000-0000-4000-8000-000000000000\",\n  \"status_uri\": \"https://acme.example.com/api/oid4vci/v1/backend/credential/offers/e2e-mdl-001\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "08 Resolve Mdl offer",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "header": [],
                "url": "{{mdlCredentialOfferUri}}",
                "description": "Resolves the Mdl offer and extracts the pre-authorized code."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "pm.test('mdl offer resolved', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "pm.test('resolved mDL offer carries exact credential configuration id', () => {",
                      "  // Every hosted instance publishes under its own path, so the credential issuer identifier is the tenant origin plus that path, never the bare origin.",
                      "  const gw = trimBase(pm.variables.get('tenantGatewayUrl'));",
                      "  pm.expect(j.credential_issuer, 'credential issuer identifier').to.be.a('string').and.to.satisfy((v) => v === gw || v.indexOf(gw + '/') === 0);",
                      "  pm.expect(j.credential_configuration_ids).to.eql(['Mdl']);",
                      "});",
                      "const grant = j.grants && (j.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'] || j.grants.pre_authorized_code);",
                      "if (grant && grant['pre-authorized_code']) pm.collectionVariables.set('mdlPreAuthCode', grant['pre-authorized_code']);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credentials/offers/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"credential_configuration_ids\": [\n    \"Mdl\"\n  ],\n  \"grants\": {\n    \"urn:ietf:params:oauth:grant-type:pre-authorized_code\": {\n      \"pre-authorized_code\": \"<code>\"\n    }\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "09 Exchange Mdl code for token",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "url": "{{tokenEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/x-www-form-urlencoded"
                  }
                ],
                "body": {
                  "mode": "urlencoded",
                  "urlencoded": [
                    {
                      "key": "grant_type",
                      "value": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
                    },
                    {
                      "key": "pre-authorized_code",
                      "value": "{{mdlPreAuthCode}}"
                    }
                  ]
                },
                "description": "Token request for the Mdl issuance session."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('mdl token issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const credentialAuthorization = Array.isArray(j.authorization_details) ? j.authorization_details.find((detail) => detail && detail.credential_configuration_id === 'Mdl') : undefined;",
                      "const credentialIdentifiers = credentialAuthorization && credentialAuthorization.credential_identifiers;",
                      "pm.test('pre-authorized token returns an opaque Mdl credential identifier distinct from its configuration id', () => {",
                      "  pm.expect(credentialAuthorization).to.be.an('object');",
                      "  pm.expect(credentialAuthorization.type).to.eql('openid_credential');",
                      "  pm.expect(credentialIdentifiers).to.be.an('array').with.lengthOf(1);",
                      "  pm.expect(credentialIdentifiers[0]).to.be.a('string').and.not.empty;",
                      "  pm.expect(credentialIdentifiers[0]).not.to.eql(credentialAuthorization.credential_configuration_id);",
                      "});",
                      "pm.collectionVariables.set('mdlCredentialIdentifier', credentialIdentifiers ? credentialIdentifiers[0] : '');",
                      "if (j.access_token) pm.collectionVariables.set('walletAccessToken', j.access_token);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/as/acme/token",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/x-www-form-urlencoded"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "\"grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code&pre-authorized_code=%3Credacted%3E\""
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"access_token\": \"eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6Im9hdXRoMi1hcy1hY21lIn0.eyJpc3MiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vYXMvYWNtZSIsInN1YiI6IiIsImNsaWVudF9pZCI6IiIsImlhdCI6MTc2NzIyNTYwMCwiZXhwIjoxNzk4NzYxNjAwLCJqdGkiOiI8anRpPiIsImF6cCI6IiIsImF1ZCI6Imh0dHBzOi8vYWNtZS5leGFtcGxlLmNvbS9vaWQ0dmNpL2FjbWUiLCJhdXRob3JpemF0aW9uX2RldGFpbHMiOlt7InR5cGUiOiJvcGVuaWRfY3JlZGVudGlhbCIsImNyZWRlbnRpYWxfY29uZmlndXJhdGlvbl9pZCI6Ik1kbCIsImNyZWRlbnRpYWxfaWRlbnRpZmllcnMiOlsidXJuOnZkeDpvaWQ0dmNpOmNyZWRlbnRpYWw6MDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAwOjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMCJdfV0sInRlbmFudF9pZCI6IjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMCJ9.SIGNATURE-REDACTED\",\n  \"access_token_decoded\": {\n    \"header\": {\n      \"typ\": \"at+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"oauth2-as-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"https://acme.example.com/as/acme\",\n      \"sub\": \"\",\n      \"client_id\": \"\",\n      \"iat\": 1767225600,\n      \"exp\": 1798761600,\n      \"jti\": \"<jti>\",\n      \"azp\": \"\",\n      \"aud\": \"https://acme.example.com/oid4vci/acme\",\n      \"authorization_details\": [\n        {\n          \"type\": \"openid_credential\",\n          \"credential_configuration_id\": \"Mdl\",\n          \"credential_identifiers\": [\n            \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n          ]\n        }\n      ],\n      \"tenant_id\": \"00000000-0000-4000-8000-000000000000\"\n    }\n  },\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 3600,\n  \"authorization_details\": [\n    {\n      \"type\": \"openid_credential\",\n      \"credential_configuration_id\": \"Mdl\",\n      \"credential_identifiers\": [\n        \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n      ]\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "10 Request Mdl credential",
              "request": {
                "auth": {
                  "type": "bearer",
                  "bearer": [
                    {
                      "key": "token",
                      "value": "{{walletAccessToken}}",
                      "type": "string"
                    }
                  ]
                },
                "method": "POST",
                "url": "{{credentialEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_identifier\": \"{{mdlCredentialIdentifier}}\",\n  \"proofs\": {\n    \"jwt\": [\"{{proofJwt}}\"]\n  }\n}"
                },
                "description": "OpenID4VCI 1.0 Final credential request selecting the Mdl credential_identifier returned in the token response and using a proof signed by the same collection-local holder fixture. The response carries the base64url-encoded ISO 18013-5 mdoc bound to the holder public key (cose_key binding)."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('mdl credential issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "try {",
                      "const j = pm.response.json();",
                      "const cred = (j.credentials && j.credentials[0] && j.credentials[0].credential) || j.credential;",
                      "pm.test('mDL credential response contains an opaque mdoc payload', () => pm.expect(cred).to.be.a('string').and.not.empty);",
                      "if (cred) pm.collectionVariables.set('mdlCredential', cred);",
                      "} finally {",
                      "pm.collectionVariables.unset('holderWalletPrivateScalar');",
                      "pm.collectionVariables.unset('holderWalletPublicJwk');",
                      "pm.collectionVariables.unset('proofJwt');",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credential",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_identifier\": \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\",\n  \"proofs\": {\n    \"jwt\": [\n      \"eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiPHB1YmxpYy1rZXktbWF0ZXJpYWw-IiwieSI6IjxwdWJsaWMta2V5LW1hdGVyaWFsPiJ9fQ.eyJhdWQiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vb2lkNHZjaS9hY21lIiwiaWF0IjoxNzY3MjI1NjAwLCJub25jZSI6Ijxub25jZT4ifQ.SIGNATURE-REDACTED\"\n    ]\n  }\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credentials\": [\n    {\n      \"credential\": \"<base64 payload omitted>\"\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ]
        },
        {
          "name": "16 Issue with Transaction Code",
          "description": "Sequential customer proof of OID4VCI transaction-code issuance through the tenant gateway. Wrong transaction codes do not consume the pre-authorized code; the same correct code succeeds once, replay and expiry fail with OAuth errors, and the credential/status reference plus correlation identity are checked. Each protocol step is an explicit sequential request.",
          "item": [
            {
              "name": "01 Create transaction-code EuPid offer",
              "request": {
                "method": "POST",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_configuration_ids\": [\"EuPid\"],\n  \"grants\": {\n    \"pre_authorized_code\": {\n      \"tx_code\": {\"input_mode\": \"numeric\", \"length\": 6}\n    }\n  },\n  \"ttl_seconds\": 120,\n  \"credential_subject_data\": {\"family_name\": \"Example\", \"given_name\": \"Transaction\", \"birth_date\": \"1964-08-12\", \"age_over_18\": true, \"nationality\": \"DE\", \"issuing_authority\": \"DE\", \"issuing_country\": \"DE\", \"document_number\": \"TX-EUPID-001\"},\n  \"correlation_id\": \"{{transactionCorrelationId}}\"\n}"
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const correlationId = 'tx-eupid-' + pm.variables.replaceIn('{{$randomUUID}}');",
                      "pm.collectionVariables.set('transactionCorrelationId', correlationId);"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "console.log('DBG-tx-offer-create', String(pm.response.code), String(pm.response.text() || '').slice(0, 900));",
                      "pm.test('transaction-code offer created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.expect(j.offer_uri, 'offer URI').to.be.a('string').and.not.empty;",
                      "pm.expect(j.tx_code, 'actual transaction code').to.match(/^\\d{6}$/);",
                      "pm.expect(j.session_id, 'actual session id').to.be.a('string').and.not.empty;",
                      "pm.expect(j.status_uri, 'actual status URI').to.be.a('string').and.not.empty;",
                      "const parseUrl = (value, relativeTo) => { const u = require('url'); const href = relativeTo ? u.resolve(String(relativeTo), String(value)) : String(value); const p = u.parse(href); const auth = p.auth ? String(p.auth).split(':') : []; return { protocol: p.protocol, host: p.host, origin: p.protocol + '//' + p.host, username: auth[0] || '', password: auth[1] || '', href, toString: () => href }; }; const tenantGatewayBaseUrl = String(pm.variables.get('tenantGatewayUrl') || '').trim().replace(/\\/+$/, '');",
                      "const base = parseUrl(tenantGatewayBaseUrl);",
                      "const requireTenantGatewayHttpsUrl = (value, label) => {",
                      "  const target = parseUrl(String(value));",
                      "  if (base.protocol !== 'https:' || base.username || base.password || target.protocol !== 'https:' || target.username || target.password || target.origin !== base.origin) throw new Error(`${label} must be an HTTPS URL on the exact tenant gateway origin`);",
                      "  return target.toString();",
                      "};",
                      "const gateway = base;",
                      "const offerMatch = String(j.offer_uri).match(/credential_offer_uri=([^&]+)/);",
                      "const offerUrl = parseUrl(decodeURIComponent(offerMatch ? offerMatch[1] : j.offer_uri), gateway.href);",
                      "const statusUrl = requireTenantGatewayHttpsUrl(j.status_uri, 'status_uri');",
                      "pm.expect(statusUrl, 'validated status URI').to.be.a('string').and.not.empty;",
                      "pm.expect(offerUrl.origin, 'offer endpoint origin').to.eql(gateway.origin);",
                      "pm.collectionVariables.set('transactionOfferUri', offerUrl.toString());",
                      "pm.collectionVariables.set('transactionCode', j.tx_code);",
                      "pm.collectionVariables.set('transactionSessionId', j.session_id);",
                      "pm.collectionVariables.set('transactionStatusUri', statusUrl);",
                      "pm.expect(j.correlation_id || j.correlationId).to.eql(pm.collectionVariables.get('transactionCorrelationId'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/credential/offers",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_configuration_ids\": [\n    \"EuPid\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {\n      \"tx_code\": {\n        \"input_mode\": \"numeric\",\n        \"length\": 6\n      }\n    }\n  },\n  \"ttl_seconds\": 120,\n  \"credential_subject_data\": {\n    \"family_name\": \"Example\",\n    \"given_name\": \"Transaction\",\n    \"birth_date\": \"1964-08-12\",\n    \"age_over_18\": true,\n    \"nationality\": \"DE\",\n    \"issuing_authority\": \"DE\",\n    \"issuing_country\": \"DE\",\n    \"document_number\": \"TX-EUPID-001\"\n  },\n  \"correlation_id\": \"tx-eupid-00000000-0000-4000-8000-000000000000\"\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"tx-eupid-00000000-0000-4000-8000-000000000000\",\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"offer_uri\": \"openid-credential-offer://?credential_offer_uri=https%3A%2F%2Facme.example.com%2Foid4vci%2Facme%2Foid4vci%2Fcredentials%2Foffers%2F00000000-0000-4000-8000-000000000000\",\n  \"status_uri\": \"https://acme.example.com/api/oid4vci/v1/backend/credential/offers/tx-eupid-00000000-0000-4000-8000-000000000000\",\n  \"tx_code\": \"<transaction-code>\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Resolve transaction-code EuPid offer",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{transactionOfferUri}}",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "console.log('DBG-tx-offer-resolve', String(pm.response.code), String(pm.response.text() || '').slice(0, 900));",
                      "pm.test('transaction-code offer resolved', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const gatewayOrigin = String(pm.variables.get('tenantGatewayUrl') || '').replace(/\\/$/, '');",
                      "pm.expect(j.credential_issuer, 'credential issuer sits on the tenant gateway origin').to.be.a('string');",
                      "pm.expect(j.credential_issuer.startsWith(gatewayOrigin)).to.eql(true);",
                      "pm.expect(j.credential_configuration_ids).to.eql(['EuPid']);",
                      "const grant = j.grants && (j.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'] || (j.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'] || j.grants.pre_authorized_code));",
                      "pm.expect(grant && grant['pre-authorized_code'], 'pre-authorized code').to.be.a('string').and.not.empty;",
                      "pm.expect(grant && grant.tx_code, 'transaction code challenge').to.be.an('object');",
                      "pm.expect(pm.collectionVariables.get('transactionCode'), 'actual transaction code from create response').to.match(/^\\d{6}$/);",
                      "const actual = pm.collectionVariables.get('transactionCode');",
                      "pm.collectionVariables.set('transactionWrongCode', actual === '000000' ? '000001' : '000000');",
                      "pm.collectionVariables.set('transactionPreAuthCode', grant['pre-authorized_code']);",
                      "pm.collectionVariables.set('transactionIssuerMetadataUrl', j.credential_issuer.replace(/\\/$/, '') + '/.well-known/openid-credential-issuer');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credentials/offers/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"credential_configuration_ids\": [\n    \"EuPid\"\n  ],\n  \"grants\": {\n    \"urn:ietf:params:oauth:grant-type:pre-authorized_code\": {\n      \"pre-authorized_code\": \"<code>\",\n      \"tx_code\": {\n        \"length\": 6\n      }\n    }\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Fetch transaction-code OID4VCI metadata",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{transactionIssuerMetadataUrl}}",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('transaction-code metadata served', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const parseUrl = (value, relativeTo) => { const u = require('url'); const href = relativeTo ? u.resolve(String(relativeTo), String(value)) : String(value); const p = u.parse(href); const auth = p.auth ? String(p.auth).split(':') : []; return { protocol: p.protocol, host: p.host, origin: p.protocol + '//' + p.host, username: auth[0] || '', password: auth[1] || '', href, toString: () => href }; }; const tenantGatewayBaseUrl = String(pm.variables.get('tenantGatewayUrl') || '').trim().replace(/\\/+$/, '');",
                      "const gateway = parseUrl(tenantGatewayBaseUrl);",
                      "const endpointOnGateway = (value, label) => { const endpoint = parseUrl(value, gateway.href); if (gateway.protocol !== 'https:' || gateway.username || gateway.password || endpoint.protocol !== 'https:' || endpoint.username || endpoint.password || endpoint.origin !== gateway.origin) throw new Error(label + ' must be an HTTPS URL on the exact tenant gateway origin'); return endpoint.toString(); };",
                      "pm.expect(j.credential_endpoint, 'credential endpoint').to.be.a('string').and.not.empty;",
                      "const txAdvertisedAs = Array.isArray(j.authorization_servers) && j.authorization_servers.length ? j.authorization_servers[0] : null;",
                      "const txTokenEndpoint = j.token_endpoint || (txAdvertisedAs && txAdvertisedAs.replace(new RegExp('/+$'), '') + '/token');",
                      "pm.expect(txTokenEndpoint, 'token endpoint').to.be.a('string').and.not.empty;",
                      "pm.collectionVariables.set('transactionTokenEndpoint', endpointOnGateway(txTokenEndpoint, 'token endpoint'));",
                      "pm.collectionVariables.set('transactionCredentialEndpoint', endpointOnGateway(j.credential_endpoint, 'credential endpoint'));",
                      "pm.expect(j.nonce_endpoint, 'nonce endpoint').to.be.a('string').and.not.empty;",
                      "pm.collectionVariables.set('nonceEndpoint', endpointOnGateway(j.nonce_endpoint, 'nonce endpoint'));",
                      "pm.expect(pm.collectionVariables.get('transactionTokenEndpoint')).to.match(/\\/token(?:$|\\?)/);",
                      "pm.expect(pm.collectionVariables.get('transactionCredentialEndpoint')).to.match(/\\/credential(?:$|\\?)/);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/oid4vci/acme/.well-known/openid-credential-issuer",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"authorization_servers\": [\n    \"https://acme.example.com/as/acme\"\n  ],\n  \"credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/credential\",\n  \"deferred_credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/deferredCredential\",\n  \"notification_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/notification\",\n  \"nonce_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/nonce\",\n  \"credential_configurations_supported\": {\n    \"EuPid\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu_pid\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\",\n        \"did:jwk\",\n        \"did:key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"EU Personal ID\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"European personal identity credential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"EU Persoonlijke ID\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"Europese persoonlijke identiteitscredential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"age_over_18\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Age over 18\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Ouder dan 18\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"nationality\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Nationality\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Nationaliteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"document_number\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"Mdl\": {\n      \"format\": \"mso_mdoc\",\n      \"scope\": \"mdl\",\n      \"cryptographic_binding_methods_supported\": [\n        \"cose_key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        -7\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"doctype\": \"org.iso.18013.5.1.mDL\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"Mobile Driving Licence\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobile driving licence\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"Mobiel Rijbewijs\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issue_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issue date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Datum van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"expiry_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Expiry date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Vervaldatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"document_number\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"portrait\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Portrait\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Portret\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"driving_privileges\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Driving privileges\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Rijbevoegdheden\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"un_distinguishing_sign\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"UN distinguishing sign\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"VN-onderscheidingsteken\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"EmployeeBadge\": {\n      \"format\": \"jwt_vc_json\",\n      \"scope\": \"employeebadge\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"EmployeeBadgeCredential\"\n        ]\n      }\n    },\n    \"Membership\": {\n      \"format\": \"jwt_vc_json-ld\",\n      \"scope\": \"membership\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"MembershipCredential\"\n        ]\n      }\n    },\n    \"EuPidShared\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu.europa.ec.eudi.pid.shared\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"urn:eudi:pid:shared\"\n    }\n  },\n  \"display\": [\n    {\n      \"name\": \"Acme Corporation Authority\",\n      \"locale\": \"en\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    },\n    {\n      \"name\": \"Acme Corporation Autoriteit\",\n      \"locale\": \"nl\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Exchange transaction code for token",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "url": "{{transactionTokenEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/x-www-form-urlencoded"
                  }
                ],
                "body": {
                  "mode": "urlencoded",
                  "urlencoded": [
                    {
                      "key": "grant_type",
                      "value": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
                    },
                    {
                      "key": "pre-authorized_code",
                      "value": "{{transactionPreAuthCode}}"
                    },
                    {
                      "key": "tx_code",
                      "value": "{{transactionCode}}"
                    }
                  ]
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('correct transaction code succeeds after wrong attempt', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "pm.expect(j.access_token, 'access token').to.be.a('string').and.not.empty;",
                      "const auth = (j.authorization_details || []).find((d) => d.credential_configuration_id === 'EuPid');",
                      "pm.expect(auth && auth.credential_identifiers && auth.credential_identifiers[0], 'opaque credential_identifier').to.be.a('string').and.not.eql('EuPid');",
                      "pm.collectionVariables.set('walletAccessToken', j.access_token);",
                      "pm.collectionVariables.set('transactionCredentialIdentifier', auth.credential_identifiers[0]);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/as/acme/token",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/x-www-form-urlencoded"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "\"grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code&pre-authorized_code=%3Credacted%3E&tx_code=%3Credacted%3E\""
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"access_token\": \"eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6Im9hdXRoMi1hcy1hY21lIn0.eyJpc3MiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vYXMvYWNtZSIsInN1YiI6IiIsImNsaWVudF9pZCI6IiIsImlhdCI6MTc2NzIyNTYwMCwiZXhwIjoxNzk4NzYxNjAwLCJqdGkiOiI8anRpPiIsImF6cCI6IiIsImF1ZCI6Imh0dHBzOi8vYWNtZS5leGFtcGxlLmNvbS9vaWQ0dmNpL2FjbWUiLCJhdXRob3JpemF0aW9uX2RldGFpbHMiOlt7InR5cGUiOiJvcGVuaWRfY3JlZGVudGlhbCIsImNyZWRlbnRpYWxfY29uZmlndXJhdGlvbl9pZCI6IkV1UGlkIiwiY3JlZGVudGlhbF9pZGVudGlmaWVycyI6WyJ1cm46dmR4Om9pZDR2Y2k6Y3JlZGVudGlhbDowMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDA6MDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAwIl19XSwidGVuYW50X2lkIjoiMDAwMDAwMDAtMDAwMC00MDAwLTgwMDAtMDAwMDAwMDAwMDAwIn0.SIGNATURE-REDACTED\",\n  \"access_token_decoded\": {\n    \"header\": {\n      \"typ\": \"at+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"oauth2-as-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"https://acme.example.com/as/acme\",\n      \"sub\": \"\",\n      \"client_id\": \"\",\n      \"iat\": 1767225600,\n      \"exp\": 1798761600,\n      \"jti\": \"<jti>\",\n      \"azp\": \"\",\n      \"aud\": \"https://acme.example.com/oid4vci/acme\",\n      \"authorization_details\": [\n        {\n          \"type\": \"openid_credential\",\n          \"credential_configuration_id\": \"EuPid\",\n          \"credential_identifiers\": [\n            \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n          ]\n        }\n      ],\n      \"tenant_id\": \"00000000-0000-4000-8000-000000000000\"\n    }\n  },\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 3600,\n  \"authorization_details\": [\n    {\n      \"type\": \"openid_credential\",\n      \"credential_configuration_id\": \"EuPid\",\n      \"credential_identifiers\": [\n        \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n      ]\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05a Fetch credential nonce",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "header": [],
                "url": {
                  "raw": "{{nonceEndpoint}}",
                  "host": [
                    "{{nonceEndpoint}}"
                  ]
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('credential nonce issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "pm.expect(j.c_nonce, 'c_nonce').to.be.a('string').and.not.empty;",
                      "pm.collectionVariables.set('transactionNonce', j.c_nonce);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/nonce",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"c_nonce\": \"<nonce>\",\n  \"c_nonce_expires_in\": 300\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 Issue transaction-code EuPid credential",
              "request": {
                "auth": {
                  "type": "bearer",
                  "bearer": [
                    {
                      "key": "token",
                      "value": "{{walletAccessToken}}",
                      "type": "string"
                    }
                  ]
                },
                "method": "POST",
                "url": "{{transactionCredentialEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_identifier\": \"{{transactionCredentialIdentifier}}\",\n  \"proofs\": {\"jwt\": [\"{{proofJwt}}\"]}\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('transaction-code credential issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const credential = (j.credentials && j.credentials[0] && j.credentials[0].credential) || j.credential;",
                      "pm.expect(credential, 'credential').to.be.a('string').and.not.empty;",
                      "const payload = JSON.parse(atob(String(credential).split('~')[0].split('.')[1].replace(/-/g, '+').replace(/_/g, '/')));",
                      "const status = payload.status && payload.status.status_list;",
                      "pm.expect(status && status.uri, 'credential status reference').to.be.a('string').and.not.empty;",
                      "const parseUrl = (value, relativeTo) => { const u = require('url'); const href = relativeTo ? u.resolve(String(relativeTo), String(value)) : String(value); const p = u.parse(href); const auth = p.auth ? String(p.auth).split(':') : []; return { protocol: p.protocol, host: p.host, origin: p.protocol + '//' + p.host, username: auth[0] || '', password: auth[1] || '', href, toString: () => href }; }; const tenantGatewayBaseUrl = String(pm.variables.get('tenantGatewayUrl') || '').trim().replace(/\\/+$/, '');",
                      "const base = parseUrl(tenantGatewayBaseUrl);",
                      "const requireTenantGatewayHttpsUrl = (value, label) => {",
                      "  const target = parseUrl(String(value));",
                      "  if (base.protocol !== 'https:' || base.username || base.password || target.protocol !== 'https:' || target.username || target.password || target.origin !== base.origin) throw new Error(`${label} must be an HTTPS URL on the exact tenant gateway origin`);",
                      "  return target.toString();",
                      "};",
                      "const validatedStatusUri = requireTenantGatewayHttpsUrl(status.uri, 'credential status URI');",
                      "pm.collectionVariables.set('transactionCredentialStatusUri', validatedStatusUri);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credential",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_identifier\": \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\",\n  \"proofs\": {\n    \"jwt\": [\n      \"eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiPHB1YmxpYy1rZXktbWF0ZXJpYWw-IiwieSI6IjxwdWJsaWMta2V5LW1hdGVyaWFsPiJ9fQ.eyJhdWQiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vb2lkNHZjaS9hY21lIiwiaWF0IjoxNzY3MjI1NjAwLCJub25jZSI6Ijxub25jZT4ifQ.SIGNATURE-REDACTED\"\n    ]\n  }\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credentials\": [\n    {\n      \"credential\": \"eyJ0eXAiOiJkYytzZC1qd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDp3ZWI6YWNtZS5leGFtcGxlLmNvbSNpc3N1ZXItYXNzZXJ0aW9uLWFjbWUifQ.eyJpc3MiOiJkaWQ6d2ViOmFjbWUuZXhhbXBsZS5jb20iLCJ2Y3QiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3NjaGVtYS92Y3QvRXVQaWQiLCJqdGkiOiI8anRpPiIsImlhdCI6MTc2NzIyNTYwMCwiZXhwIjoxNzk4NzYxNjAwLCJzdGF0dXMiOnsic3RhdHVzX2xpc3QiOnsiaWR4IjoxMDA0LCJ1cmkiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL2V1cGlkLXJldm9jYXRpb24ifX0sImNuZiI6eyJqd2siOnsia3R5IjoiRUMiLCJjcnYiOiJQLTI1NiIsIngiOiI8cHVibGljLWtleS1tYXRlcmlhbD4iLCJ5IjoiPHB1YmxpYy1rZXktbWF0ZXJpYWw-In19LCJfc2QiOlsiPGRpZ2VzdD4iLCI8ZGlnZXN0PiIsIjxkaWdlc3Q-IiwiPGRpZ2VzdD4iLCI8ZGlnZXN0PiIsIjxkaWdlc3Q-IiwiPGRpZ2VzdD4iLCI8ZGlnZXN0PiJdLCJfc2RfYWxnIjoic2hhLTI1NiJ9.SIGNATURE-REDACTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~DISCLOSURE-OMITTED~\",\n      \"credential_decoded\": {\n        \"header\": {\n          \"typ\": \"dc+sd-jwt\",\n          \"alg\": \"ES256\",\n          \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\"\n        },\n        \"payload\": {\n          \"iss\": \"did:web:acme.example.com\",\n          \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n          \"jti\": \"<jti>\",\n          \"iat\": 1767225600,\n          \"exp\": 1798761600,\n          \"status\": {\n            \"status_list\": {\n              \"idx\": 1004,\n              \"uri\": \"https://acme.example.com/public/statuslists/eupid-revocation\"\n            }\n          },\n          \"cnf\": {\n            \"jwk\": {\n              \"kty\": \"EC\",\n              \"crv\": \"P-256\",\n              \"x\": \"<public-key-material>\",\n              \"y\": \"<public-key-material>\"\n            }\n          },\n          \"_sd\": [\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\",\n            \"<digest>\"\n          ],\n          \"_sd_alg\": \"sha-256\"\n        },\n        \"disclosures\": [\n          [\n            \"<salt>\",\n            \"family_name\",\n            \"Example\"\n          ],\n          [\n            \"<salt>\",\n            \"given_name\",\n            \"Transaction\"\n          ],\n          [\n            \"<salt>\",\n            \"birth_date\",\n            \"1964-08-12\"\n          ],\n          [\n            \"<salt>\",\n            \"age_over_18\",\n            true\n          ],\n          [\n            \"<salt>\",\n            \"nationality\",\n            \"DE\"\n          ],\n          [\n            \"<salt>\",\n            \"issuing_authority\",\n            \"DE\"\n          ],\n          [\n            \"<salt>\",\n            \"issuing_country\",\n            \"DE\"\n          ],\n          [\n            \"<salt>\",\n            \"document_number\",\n            \"TX-EUPID-001\"\n          ]\n        ]\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "07 Assert transaction-code offer status correlation",
              "request": {
                "method": "GET",
                "url": "{{transactionStatusUri}}",
                "header": []
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const parseUrl = (value, relativeTo) => { const u = require('url'); const href = relativeTo ? u.resolve(String(relativeTo), String(value)) : String(value); const p = u.parse(href); const auth = p.auth ? String(p.auth).split(':') : []; return { protocol: p.protocol, host: p.host, origin: p.protocol + '//' + p.host, username: auth[0] || '', password: auth[1] || '', href, toString: () => href }; }; const tenantGatewayBaseUrl = String(pm.variables.get('tenantGatewayUrl') || '').trim().replace(/\\/+$/, '');",
                      "const base = parseUrl(tenantGatewayBaseUrl);",
                      "const target = parseUrl(String(pm.collectionVariables.get('transactionStatusUri') || ''));",
                      "if (base.protocol !== 'https:' || base.username || base.password || target.protocol !== 'https:' || target.username || target.password || target.origin !== base.origin) throw new Error('transaction status URI must be an HTTPS URL on the exact tenant gateway origin');"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('transaction-code offer status is readable', () => pm.expect([200, 204]).to.include(pm.response.code));",
                      "pm.expect(pm.collectionVariables.get('transactionSessionId'), 'create response session id').to.be.a('string').and.not.empty;",
                      "if (pm.response.code === 200) { const j = pm.response.json(); pm.expect(j.correlation_id || j.correlationId, 'status/session correlation identity').to.eql(pm.collectionVariables.get('transactionCorrelationId')); }"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/credential/offers/tx-eupid-00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"tx-eupid-00000000-0000-4000-8000-000000000000\",\n  \"status\": \"credential_issued\",\n  \"last_updated\": 1767225600000,\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"offer_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"issuance_session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"created_at\": 1767225600000,\n  \"expires_at\": 1798761600000,\n  \"error\": null,\n  \"issuance_data\": {\n    \"credential_configuration_ids\": [\n      \"EuPid\"\n    ],\n    \"credential_identifiers\": null\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "09 Dereference transaction-code credential status",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{transactionCredentialStatusUri}}",
                "header": []
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const parseUrl = (value, relativeTo) => { const u = require('url'); const href = relativeTo ? u.resolve(String(relativeTo), String(value)) : String(value); const p = u.parse(href); const auth = p.auth ? String(p.auth).split(':') : []; return { protocol: p.protocol, host: p.host, origin: p.protocol + '//' + p.host, username: auth[0] || '', password: auth[1] || '', href, toString: () => href }; }; const tenantGatewayBaseUrl = String(pm.variables.get('tenantGatewayUrl') || '').trim().replace(/\\/+$/, '');",
                      "const base = parseUrl(tenantGatewayBaseUrl);",
                      "const target = parseUrl(String(pm.collectionVariables.get('transactionCredentialStatusUri') || ''));",
                      "if (base.protocol !== 'https:' || base.username || base.password || target.protocol !== 'https:' || target.username || target.password || target.origin !== base.origin) throw new Error('credential status URI must be an HTTPS URL on the exact tenant gateway origin');"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('credential status reference dereferenced', () => pm.expect([200, 204]).to.include(pm.response.code));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/public/statuslists/eupid-revocation",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/statuslist+jwt"
                    }
                  ],
                  "body": "{\n  \"_raw\": \"eyJ0eXAiOiJzdGF0dXNsaXN0K2p3dCIsImFsZyI6IkVTMjU2Iiwia2lkIjoiZGlkOndlYjphY21lLmV4YW1wbGUuY29tI2lzc3Vlci1hc3NlcnRpb24tYWNtZSJ9.eyJpc3MiOiJkaWQ6d2ViOmFjbWUuZXhhbXBsZS5jb20iLCJzdWIiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL2V1cGlkLXJldm9jYXRpb24iLCJpYXQiOjE3NjcyMjU2MDAsInR0bCI6MzAwLCJzdGF0dXNfbGlzdCI6eyJiaXRzIjoxLCJsc3QiOiI8Y29tcHJlc3NlZC1zdGF0dXMtbGlzdD4ifX0.SIGNATURE-REDACTED\",\n  \"_decoded\": {\n    \"header\": {\n      \"typ\": \"statuslist+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"did:web:acme.example.com\",\n      \"sub\": \"https://acme.example.com/public/statuslists/eupid-revocation\",\n      \"iat\": 1767225600,\n      \"ttl\": 300,\n      \"status_list\": {\n        \"bits\": 1,\n        \"lst\": \"<compressed-status-list>\"\n      }\n    }\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "17 Issue W3C VCDM 1.1",
          "description": "Registers the EmployeeBadge credential configuration in the VCDM 1.1 JWT VC format, binds it to the bitstring status list of folder 09c, and issues one pre-authorized credential. The test decodes the returned JWT and asserts the VCDM 1.1 context, the credential type and a BitstringStatusListEntry status entry.",
          "item": [
            {
              "name": "02 Create the EmployeeBadge offer",
              "request": {
                "method": "POST",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_configuration_ids\": [\n    \"EmployeeBadge\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"id\": \"did:example:employee-0001\",\n    \"type\": \"EmployeeBadgeCredential\",\n    \"name\": \"Erika Mustermann\",\n    \"employeeId\": \"ACME-4711\",\n    \"jobTitle\": \"Field Engineer\",\n    \"department\": \"Operations\"\n  },\n  \"correlation_id\": \"e2e-employeebadge-001\"\n}"
                },
                "description": "Creates a pre-authorized offer for the VCDM 1.1 credential with the subject data supplied inline."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('EmployeeBadge offer created', () => pm.expect([200, 201], 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url) => {",
                      "  const publicHost = pm.variables.get('tenantHost');",
                      "  const gatewayBase = trimBase(pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && publicHost && m[2] === publicHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "pm.expect(j.offer_uri, 'offer uri').to.be.a('string').and.not.empty;",
                      "const m = String(j.offer_uri).match(/credential_offer_uri=([^&]+)/);",
                      "pm.expect(m, 'offer uri carries credential_offer_uri').to.not.eql(null);",
                      "pm.collectionVariables.set('employeeBadgeOfferUri', rewritePublicUrl(decodeURIComponent(m[1])));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/credential/offers",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_configuration_ids\": [\n    \"EmployeeBadge\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"id\": \"did:example:employee-0001\",\n    \"type\": \"EmployeeBadgeCredential\",\n    \"name\": \"Erika Mustermann\",\n    \"employeeId\": \"ACME-4711\",\n    \"jobTitle\": \"Field Engineer\",\n    \"department\": \"Operations\"\n  },\n  \"correlation_id\": \"e2e-employeebadge-001\"\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"e2e-employeebadge-001\",\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"offer_uri\": \"openid-credential-offer://?credential_offer_uri=https%3A%2F%2Facme.example.com%2Foid4vci%2Facme%2Foid4vci%2Fcredentials%2Foffers%2F00000000-0000-4000-8000-000000000000\",\n  \"status_uri\": \"https://acme.example.com/api/oid4vci/v1/backend/credential/offers/e2e-employeebadge-001\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Resolve the EmployeeBadge offer",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{employeeBadgeOfferUri}}",
                "header": [],
                "description": "Resolves the offer as a wallet does and reads the pre-authorized code."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('EmployeeBadge offer resolved', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url) => {",
                      "  const publicHost = pm.variables.get('tenantHost');",
                      "  const gatewayBase = trimBase(pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && publicHost && m[2] === publicHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "pm.expect(j.credential_configuration_ids, 'offered configurations').to.eql(['EmployeeBadge']);",
                      "const grant = j.grants && (j.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'] || j.grants.pre_authorized_code);",
                      "pm.expect(grant && grant['pre-authorized_code'], 'pre-authorized code').to.be.a('string').and.not.empty;",
                      "pm.collectionVariables.set('employeeBadgePreAuthCode', grant['pre-authorized_code']);",
                      "pm.collectionVariables.set('credentialIssuer', j.credential_issuer);",
                      "const parsed = String(j.credential_issuer).match(/^(https?:\\/\\/[^/]+)(\\/.*)?$/);",
                      "pm.collectionVariables.set('employeeBadgeMetadataUrl', rewritePublicUrl(parsed[1] + '/.well-known/openid-credential-issuer' + (parsed[2] || '')));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credentials/offers/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"credential_configuration_ids\": [\n    \"EmployeeBadge\"\n  ],\n  \"grants\": {\n    \"urn:ietf:params:oauth:grant-type:pre-authorized_code\": {\n      \"pre-authorized_code\": \"<code>\"\n    }\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Fetch the VCDM 1.1 OID4VCI metadata",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{employeeBadgeMetadataUrl}}",
                "header": [],
                "description": "Reads the issuer metadata and confirms the VCDM 1.1 credential is advertised with the `jwt_vc_json` format."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('VCDM 1.1 metadata served', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url) => {",
                      "  const publicHost = pm.variables.get('tenantHost');",
                      "  const gatewayBase = trimBase(pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && publicHost && m[2] === publicHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "const configuration = (j.credential_configurations_supported || {})['EmployeeBadge'];",
                      "pm.test('the issuer advertises EmployeeBadge as jwt_vc_json', () => {",
                      "  pm.expect(configuration, 'credential configuration').to.be.an('object');",
                      "  pm.expect(configuration.format, 'format').to.eql('jwt_vc_json');",
                      "});",
                      "pm.collectionVariables.set('employeeBadgeCredentialEndpoint', rewritePublicUrl(j.credential_endpoint));",
                      "const advertisedAs = Array.isArray(j.authorization_servers) && j.authorization_servers.length ? j.authorization_servers[0] : null;",
                      "pm.collectionVariables.set('employeeBadgeTokenEndpoint', rewritePublicUrl(j.token_endpoint || (String(advertisedAs).replace(/\\/$/, '') + '/token')));",
                      "if (j.nonce_endpoint) pm.collectionVariables.set('nonceEndpoint', rewritePublicUrl(j.nonce_endpoint));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/.well-known/openid-credential-issuer/oid4vci/acme",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"authorization_servers\": [\n    \"https://acme.example.com/as/acme\"\n  ],\n  \"credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/credential\",\n  \"deferred_credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/deferredCredential\",\n  \"notification_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/notification\",\n  \"nonce_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/nonce\",\n  \"credential_configurations_supported\": {\n    \"EuPid\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu_pid\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\",\n        \"did:jwk\",\n        \"did:key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"EU Personal ID\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"European personal identity credential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"EU Persoonlijke ID\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"Europese persoonlijke identiteitscredential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"age_over_18\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Age over 18\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Ouder dan 18\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"nationality\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Nationality\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Nationaliteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"document_number\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"Mdl\": {\n      \"format\": \"mso_mdoc\",\n      \"scope\": \"mdl\",\n      \"cryptographic_binding_methods_supported\": [\n        \"cose_key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        -7\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"doctype\": \"org.iso.18013.5.1.mDL\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"Mobile Driving Licence\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobile driving licence\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"Mobiel Rijbewijs\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issue_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issue date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Datum van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"expiry_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Expiry date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Vervaldatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"document_number\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"portrait\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Portrait\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Portret\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"driving_privileges\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Driving privileges\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Rijbevoegdheden\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"un_distinguishing_sign\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"UN distinguishing sign\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"VN-onderscheidingsteken\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"EmployeeBadge\": {\n      \"format\": \"jwt_vc_json\",\n      \"scope\": \"employeebadge\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"EmployeeBadgeCredential\"\n        ]\n      }\n    },\n    \"Membership\": {\n      \"format\": \"jwt_vc_json-ld\",\n      \"scope\": \"membership\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"MembershipCredential\"\n        ]\n      }\n    },\n    \"EuPidShared\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu.europa.ec.eudi.pid.shared\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"urn:eudi:pid:shared\"\n    }\n  },\n  \"display\": [\n    {\n      \"name\": \"Acme Corporation Authority\",\n      \"locale\": \"en\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    },\n    {\n      \"name\": \"Acme Corporation Autoriteit\",\n      \"locale\": \"nl\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Exchange the EmployeeBadge pre-authorized code",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "url": "{{employeeBadgeTokenEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/x-www-form-urlencoded"
                  }
                ],
                "body": {
                  "mode": "urlencoded",
                  "urlencoded": [
                    {
                      "key": "grant_type",
                      "value": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
                    },
                    {
                      "key": "pre-authorized_code",
                      "value": "{{employeeBadgePreAuthCode}}"
                    }
                  ]
                },
                "description": "Exchanges the pre-authorized code for the wallet access token and the opaque credential identifier."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('EmployeeBadge token issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const authorization = Array.isArray(j.authorization_details) ? j.authorization_details.find((detail) => detail && detail.credential_configuration_id === 'EmployeeBadge') : undefined;",
                      "const identifiers = authorization && authorization.credential_identifiers;",
                      "pm.test('the token returns an opaque EmployeeBadge credential identifier', () => {",
                      "  pm.expect(identifiers, 'credential identifiers').to.be.an('array').with.lengthOf(1);",
                      "  pm.expect(identifiers[0], 'credential identifier').to.not.eql('EmployeeBadge');",
                      "});",
                      "pm.collectionVariables.set('employeeBadgeCredentialIdentifier', identifiers ? identifiers[0] : '');",
                      "pm.collectionVariables.set('walletAccessToken', j.access_token);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/as/acme/token",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/x-www-form-urlencoded"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "\"grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code&pre-authorized_code=%3Credacted%3E\""
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"access_token\": \"eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6Im9hdXRoMi1hcy1hY21lIn0.eyJpc3MiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vYXMvYWNtZSIsInN1YiI6IiIsImNsaWVudF9pZCI6IiIsImlhdCI6MTc2NzIyNTYwMCwiZXhwIjoxNzk4NzYxNjAwLCJqdGkiOiI8anRpPiIsImF6cCI6IiIsImF1ZCI6Imh0dHBzOi8vYWNtZS5leGFtcGxlLmNvbS9vaWQ0dmNpL2FjbWUiLCJhdXRob3JpemF0aW9uX2RldGFpbHMiOlt7InR5cGUiOiJvcGVuaWRfY3JlZGVudGlhbCIsImNyZWRlbnRpYWxfY29uZmlndXJhdGlvbl9pZCI6IkVtcGxveWVlQmFkZ2UiLCJjcmVkZW50aWFsX2lkZW50aWZpZXJzIjpbInVybjp2ZHg6b2lkNHZjaTpjcmVkZW50aWFsOjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMDowMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDAiXX1dLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDAifQ.SIGNATURE-REDACTED\",\n  \"access_token_decoded\": {\n    \"header\": {\n      \"typ\": \"at+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"oauth2-as-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"https://acme.example.com/as/acme\",\n      \"sub\": \"\",\n      \"client_id\": \"\",\n      \"iat\": 1767225600,\n      \"exp\": 1798761600,\n      \"jti\": \"<jti>\",\n      \"azp\": \"\",\n      \"aud\": \"https://acme.example.com/oid4vci/acme\",\n      \"authorization_details\": [\n        {\n          \"type\": \"openid_credential\",\n          \"credential_configuration_id\": \"EmployeeBadge\",\n          \"credential_identifiers\": [\n            \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n          ]\n        }\n      ],\n      \"tenant_id\": \"00000000-0000-4000-8000-000000000000\"\n    }\n  },\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 3600,\n  \"authorization_details\": [\n    {\n      \"type\": \"openid_credential\",\n      \"credential_configuration_id\": \"EmployeeBadge\",\n      \"credential_identifiers\": [\n        \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n      ]\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 Request the EmployeeBadge credential",
              "request": {
                "auth": {
                  "type": "bearer",
                  "bearer": [
                    {
                      "key": "token",
                      "value": "{{walletAccessToken}}",
                      "type": "string"
                    }
                  ]
                },
                "method": "POST",
                "url": "{{employeeBadgeCredentialEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_identifier\": \"{{employeeBadgeCredentialIdentifier}}\",\n  \"proofs\": {\n    \"jwt\": [\"{{proofJwt}}\"]\n  }\n}"
                },
                "description": "Issues the VCDM 1.1 credential as a VC-JWT with an ES256 proof of possession. The test decodes the returned JWT and checks the VCDM context, the credential type and the status entry. `credentialStatus.type` is `BitstringStatusListEntry` for VCDM 1.1 as well as VCDM 2.0."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "try {",
                      "  pm.test('EmployeeBadge credential issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "  const j = pm.response.json();",
                      "  const credential = (j.credentials && j.credentials[0] && j.credentials[0].credential) || j.credential;",
                      "  pm.expect(credential, 'credential').to.be.a('string').and.not.empty;",
                      "  const decodeJwtPart = (jwt, index) => {",
                      "    const compact = String(jwt || '').split('~')[0];",
                      "    const segment = compact.split('.')[index];",
                      "    pm.expect(segment, 'jwt segment ' + index).to.be.a('string').and.not.empty;",
                      "    const normalized = segment.replace(/-/g, '+').replace(/_/g, '/');",
                      "    const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);",
                      "    return JSON.parse(atob(padded));",
                      "  };",
                      "  const payload = decodeJwtPart(credential, 1);",
                      "  // VCDM 1.1 VC-JWT nests the credential under 'vc'; the VCDM 2.0 JOSE form carries it at the top.",
                      "  const vc = payload.vc || payload;",
                      "  const contexts = [].concat(vc['@context'] || []);",
                      "  const types = [].concat(vc.type || []);",
                      "  const credentialStatus = [].concat(vc.credentialStatus || [])[0] || {};",
                      "  pm.test('the credential is a VCDM 1.1 verifiable credential of type EmployeeBadgeCredential', () => {",
                      "    pm.expect(contexts, 'JSON-LD context').to.include('https://www.w3.org/2018/credentials/v1');",
                      "    pm.expect(types, 'credential types').to.include('VerifiableCredential');",
                      "    pm.expect(types, 'credential types').to.include('EmployeeBadgeCredential');",
                      "  });",
                      "  pm.test('the credential status entry is a BitstringStatusListEntry on the bitstring list', () => {",
                      "    pm.expect(credentialStatus.type, 'credentialStatus.type').to.eql('BitstringStatusListEntry');",
                      "    pm.expect(String(credentialStatus.statusListCredential || credentialStatus.id || ''), 'status list reference').to.contain('/public/statuslists/status-bitstring');",
                      "    pm.expect(String(credentialStatus.statusListIndex || ''), 'allocated index').to.not.be.empty;",
                      "  });",
                      "  pm.collectionVariables.set('employeeBadgeStatusIndex', String(credentialStatus.statusListIndex || ''));",
                      "} finally {",
                      "  pm.collectionVariables.unset('holderWalletPrivateScalar');",
                      "  pm.collectionVariables.unset('holderWalletPublicJwk');",
                      "  pm.collectionVariables.unset('proofJwt');",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credential",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_identifier\": \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\",\n  \"proofs\": {\n    \"jwt\": [\n      \"eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiPHB1YmxpYy1rZXktbWF0ZXJpYWw-IiwieSI6IjxwdWJsaWMta2V5LW1hdGVyaWFsPiJ9fQ.eyJhdWQiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vb2lkNHZjaS9hY21lIiwiaWF0IjoxNzY3MjI1NjAwLCJub25jZSI6Ijxub25jZT4ifQ.SIGNATURE-REDACTED\"\n    ]\n  }\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credentials\": [\n    {\n      \"credential\": \"eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDp3ZWI6YWNtZS5leGFtcGxlLmNvbSNpc3N1ZXItYXNzZXJ0aW9uLWFjbWUifQ.eyJ2YyI6eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvMjAxOC9jcmVkZW50aWFscy92MSJdLCJ0eXBlIjpbIlZlcmlmaWFibGVDcmVkZW50aWFsIiwiRW1wbG95ZWVCYWRnZUNyZWRlbnRpYWwiXSwiaXNzdWVyIjoiaHR0cHM6Ly9hY21lLmV4YW1wbGUuY29tL29pZDR2Y2kvYWNtZSIsImlzc3VhbmNlRGF0ZSI6IjIwMjYtMDEtMDFUMDA6MDA6MDBaIiwiZXhwaXJhdGlvbkRhdGUiOiIyMDI3LTAxLTAxVDAwOjAwOjAwWiIsImlkIjoiPGp0aT4iLCJjcmVkZW50aWFsU3RhdHVzIjp7ImlkIjoiaHR0cHM6Ly9hY21lLmV4YW1wbGUuY29tL3B1YmxpYy9zdGF0dXNsaXN0cy9zdGF0dXMtYml0c3RyaW5nIzEwMDUiLCJ0eXBlIjoiQml0c3RyaW5nU3RhdHVzTGlzdEVudHJ5Iiwic3RhdHVzUHVycG9zZSI6InJldm9jYXRpb24iLCJzdGF0dXNMaXN0SW5kZXgiOiIxMDA1Iiwic3RhdHVzTGlzdENyZWRlbnRpYWwiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL3N0YXR1cy1iaXRzdHJpbmcifSwiY3JlZGVudGlhbFN1YmplY3QiOnsiaWQiOiJkaWQ6ZXhhbXBsZTplbXBsb3llZS0wMDAxIiwidHlwZSI6IkVtcGxveWVlQmFkZ2VDcmVkZW50aWFsIiwibmFtZSI6IkVyaWthIE11c3Rlcm1hbm4iLCJlbXBsb3llZUlkIjoiQUNNRS00NzExIiwiam9iVGl0bGUiOiJGaWVsZCBFbmdpbmVlciIsImRlcGFydG1lbnQiOiJPcGVyYXRpb25zIn19LCJpc3MiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vb2lkNHZjaS9hY21lIiwibmJmIjoxNzY3MjI1NjAwLCJqdGkiOiI8anRpPiIsInN1YiI6ImRpZDpleGFtcGxlOmVtcGxveWVlLTAwMDEiLCJpYXQiOjE3NjcyMjU2MDAsImV4cCI6MTc5ODc2MTYwMCwiY25mIjp7Imp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IjxwdWJsaWMta2V5LW1hdGVyaWFsPiIsInkiOiI8cHVibGljLWtleS1tYXRlcmlhbD4ifX19.SIGNATURE-REDACTED\",\n      \"credential_decoded\": {\n        \"header\": {\n          \"typ\": \"JWT\",\n          \"alg\": \"ES256\",\n          \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\"\n        },\n        \"payload\": {\n          \"vc\": {\n            \"@context\": [\n              \"https://www.w3.org/2018/credentials/v1\"\n            ],\n            \"type\": [\n              \"VerifiableCredential\",\n              \"EmployeeBadgeCredential\"\n            ],\n            \"issuer\": \"https://acme.example.com/oid4vci/acme\",\n            \"issuanceDate\": \"2026-01-01T00:00:00Z\",\n            \"expirationDate\": \"2027-01-01T00:00:00Z\",\n            \"id\": \"<jti>\",\n            \"credentialStatus\": {\n              \"id\": \"https://acme.example.com/public/statuslists/status-bitstring#1005\",\n              \"type\": \"BitstringStatusListEntry\",\n              \"statusPurpose\": \"revocation\",\n              \"statusListIndex\": \"1005\",\n              \"statusListCredential\": \"https://acme.example.com/public/statuslists/status-bitstring\"\n            },\n            \"credentialSubject\": {\n              \"id\": \"did:example:employee-0001\",\n              \"type\": \"EmployeeBadgeCredential\",\n              \"name\": \"Erika Mustermann\",\n              \"employeeId\": \"ACME-4711\",\n              \"jobTitle\": \"Field Engineer\",\n              \"department\": \"Operations\"\n            }\n          },\n          \"iss\": \"https://acme.example.com/oid4vci/acme\",\n          \"nbf\": 1767225600,\n          \"jti\": \"<jti>\",\n          \"sub\": \"did:example:employee-0001\",\n          \"iat\": 1767225600,\n          \"exp\": 1798761600,\n          \"cnf\": {\n            \"jwk\": {\n              \"kty\": \"EC\",\n              \"crv\": \"P-256\",\n              \"x\": \"<public-key-material>\",\n              \"y\": \"<public-key-material>\"\n            }\n          }\n        }\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "07 Check the EmployeeBadge offer status",
              "request": {
                "method": "GET",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers/e2e-employeebadge-001",
                "header": [],
                "description": "Reads the backend session by its business key. The lifecycle ends in credential_issued."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('EmployeeBadge session tracked', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/credential/offers/e2e-employeebadge-001",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"e2e-employeebadge-001\",\n  \"status\": \"credential_issued\",\n  \"last_updated\": 1767225600000,\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"offer_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"issuance_session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"created_at\": 1767225600000,\n  \"expires_at\": 1798761600000,\n  \"error\": null,\n  \"issuance_data\": {\n    \"credential_configuration_ids\": [\n      \"EmployeeBadge\"\n    ],\n    \"credential_identifiers\": null\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "08 Read the EmployeeBadge status entry",
              "request": {
                "method": "GET",
                "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{bitstringStatusListId}}/entries/{{employeeBadgeStatusIndex}}",
                "header": [],
                "description": "Reads the bitstring entry the issued credential points at. A freshly issued credential is valid, so the entry reads 0."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('EmployeeBadge status entry returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const entry = pm.response.json();",
                      "pm.test('the freshly issued VCDM 1.1 credential is valid', () => {",
                      "  pm.expect(entry.statusListIndex, 'index').to.eql(Number(pm.collectionVariables.get('employeeBadgeStatusIndex')));",
                      "  pm.expect(entry.value, 'value').to.eql(0);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/statuslist/v1/statuslists/00000000-0000-4000-8000-000000000000/entries/1005",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n  \"statusListIndex\": 1005,\n  \"entryCorrelationId\": \"\",\n  \"credentialId\": \"<jti>\",\n  \"credentialHash\": null,\n  \"value\": 0,\n  \"purpose\": \"revocation\",\n  \"identifier\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// Minimal collection-local P-256 holder fixture for Postman/Newman.",
                  "// The private scalar stays in a runtime collection variable and is never sent or logged.",
                  "const CURVE_P = BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff');",
                  "const CURVE_A = CURVE_P - 3n;",
                  "const CURVE_N = BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551');",
                  "const CURVE_G = {",
                  "  x: BigInt('0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296'),",
                  "  y: BigInt('0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5')",
                  "};",
                  "const mod = (value, modulus) => {",
                  "  const result = value % modulus;",
                  "  return result >= 0n ? result : result + modulus;",
                  "};",
                  "const inverse = (value, modulus) => {",
                  "  let low = mod(value, modulus);",
                  "  let high = modulus;",
                  "  let lowCoefficient = 1n;",
                  "  let highCoefficient = 0n;",
                  "  while (low > 1n) {",
                  "    const ratio = high / low;",
                  "    const next = high - low * ratio;",
                  "    const nextCoefficient = highCoefficient - lowCoefficient * ratio;",
                  "    high = low;",
                  "    low = next;",
                  "    highCoefficient = lowCoefficient;",
                  "    lowCoefficient = nextCoefficient;",
                  "  }",
                  "  if (low !== 1n) throw new Error('P-256 modular inverse does not exist');",
                  "  return mod(lowCoefficient, modulus);",
                  "};",
                  "const pointAdd = (left, right) => {",
                  "  if (!left) return right;",
                  "  if (!right) return left;",
                  "  let slope;",
                  "  if (left.x === right.x) {",
                  "    if (mod(left.y + right.y, CURVE_P) === 0n) return null;",
                  "    slope = mod((3n * left.x * left.x + CURVE_A) * inverse(2n * left.y, CURVE_P), CURVE_P);",
                  "  } else {",
                  "    slope = mod((right.y - left.y) * inverse(right.x - left.x, CURVE_P), CURVE_P);",
                  "  }",
                  "  const x = mod(slope * slope - left.x - right.x, CURVE_P);",
                  "  return { x: x, y: mod(slope * (left.x - x) - left.y, CURVE_P) };",
                  "};",
                  "const scalarMultiply = (scalar, point) => {",
                  "  let remaining = scalar;",
                  "  let result = null;",
                  "  let addend = point;",
                  "  while (remaining > 0n) {",
                  "    if ((remaining & 1n) === 1n) result = pointAdd(result, addend);",
                  "    addend = pointAdd(addend, addend);",
                  "    remaining >>= 1n;",
                  "  }",
                  "  return result;",
                  "};",
                  "const randomScalar = () => {",
                  "  while (true) {",
                  "    const candidateHex = CryptoJS.lib.WordArray.random(32).toString(CryptoJS.enc.Hex);",
                  "    const candidate = BigInt('0x' + candidateHex);",
                  "    if (candidate > 0n && candidate < CURVE_N) return candidate;",
                  "  }",
                  "};",
                  "const hex32 = (value) => value.toString(16).padStart(64, '0');",
                  "const base64Url = (wordArray) => CryptoJS.enc.Base64.stringify(wordArray).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');",
                  "const base64UrlHex = (hex) => base64Url(CryptoJS.enc.Hex.parse(hex));",
                  "const base64UrlJson = (value) => base64Url(CryptoJS.enc.Utf8.parse(JSON.stringify(value)));",
                  "if (pm.info.requestName === '01 Create EuPid offer') {",
                  "  pm.collectionVariables.unset('holderWalletPrivateScalar');",
                  "  pm.collectionVariables.unset('holderWalletPublicJwk');",
                  "  pm.collectionVariables.unset('proofJwt');",
                  "}",
                  "let holderPrivateHex = String(pm.collectionVariables.get('holderWalletPrivateScalar') || '');",
                  "let holderPublicJwkText = String(pm.collectionVariables.get('holderWalletPublicJwk') || '');",
                  "let holderPublicJwk;",
                  "try { holderPublicJwk = JSON.parse(holderPublicJwkText); } catch (_) { holderPublicJwk = null; }",
                  "if (!/^[0-9a-f]{64}$/.test(holderPrivateHex) || !holderPublicJwk || holderPublicJwk.kty !== 'EC' || holderPublicJwk.crv !== 'P-256') {",
                  "  const holderPrivate = randomScalar();",
                  "  const holderPublic = scalarMultiply(holderPrivate, CURVE_G);",
                  "  holderPrivateHex = hex32(holderPrivate);",
                  "  holderPublicJwk = { kty: 'EC', crv: 'P-256', x: base64UrlHex(hex32(holderPublic.x)), y: base64UrlHex(hex32(holderPublic.y)) };",
                  "  holderPublicJwkText = JSON.stringify(holderPublicJwk);",
                  "  pm.collectionVariables.set('holderWalletPrivateScalar', holderPrivateHex);",
                  "  pm.collectionVariables.set('holderWalletPublicJwk', holderPublicJwkText);",
                  "}",
                  "const signEs256 = (signingInput) => {",
                  "  const privateScalar = BigInt('0x' + holderPrivateHex);",
                  "  const digest = BigInt('0x' + CryptoJS.SHA256(signingInput).toString(CryptoJS.enc.Hex));",
                  "  while (true) {",
                  "    const ephemeral = randomScalar();",
                  "    const point = scalarMultiply(ephemeral, CURVE_G);",
                  "    const r = mod(point.x, CURVE_N);",
                  "    if (r === 0n) continue;",
                  "    let s = mod(inverse(ephemeral, CURVE_N) * (digest + r * privateScalar), CURVE_N);",
                  "    if (s === 0n) continue;",
                  "    if (s > CURVE_N / 2n) s = CURVE_N - s;",
                  "    return base64UrlHex(hex32(r) + hex32(s));",
                  "  }",
                  "};",
                  "const buildHolderProof = (nonce) => {",
                  "  const header = { alg: 'ES256', typ: 'openid4vci-proof+jwt', jwk: holderPublicJwk };",
                  "  const payload = {",
                  "    aud: pm.collectionVariables.get('credentialIssuer') || pm.variables.get('tenantGatewayUrl'),",
                  "    iat: Math.floor(Date.now() / 1000)",
                  "  };",
                  "  if (nonce) payload.nonce = nonce;",
                  "  const signingInput = base64UrlJson(header) + '.' + base64UrlJson(payload);",
                  "  pm.collectionVariables.set('proofJwt', signingInput + '.' + signEs256(signingInput));",
                  "};",
                  "if (pm.info.requestName === '06 Request the EmployeeBadge credential') {",
                  "  const nonceEndpoint = String(pm.collectionVariables.get('nonceEndpoint') || '').trim();",
                  "  if (nonceEndpoint) {",
                  "    pm.sendRequest({ url: nonceEndpoint, method: 'POST', header: { 'Host': pm.variables.get('tenantHost') } }, (error, response) => {",
                  "      if (error) throw new Error('OID4VCI nonce fetch failed: ' + error.message);",
                  "      const nonce = response.json().c_nonce;",
                  "      if (!nonce) throw new Error('OID4VCI nonce response did not contain c_nonce');",
                  "      pm.collectionVariables.set('employeeBadgeNonce', nonce);",
                  "      buildHolderProof(nonce);",
                  "    });",
                  "  } else {",
                  "    buildHolderProof(undefined);",
                  "  }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "18 Issue W3C VCDM 2.0",
          "description": "Registers the Membership credential configuration in the VCDM 2.0 JSON-LD JWT VC format, binds it to the same bitstring status list, and issues one pre-authorized credential. The status entry type is BitstringStatusListEntry here too: VCDM 2.0 changes the context and the envelope, not the status entry type this deployment writes.",
          "item": [
            {
              "name": "02 Create the Membership offer",
              "request": {
                "method": "POST",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_configuration_ids\": [\n    \"Membership\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"id\": \"did:example:member-0001\",\n    \"type\": \"MembershipCredential\",\n    \"name\": \"Erika Mustermann\",\n    \"membershipNumber\": \"ACME-M-2026-0042\",\n    \"membershipLevel\": \"gold\",\n    \"validFrom\": \"2026-01-01\"\n  },\n  \"correlation_id\": \"e2e-membership-001\"\n}"
                },
                "description": "Creates a pre-authorized offer for the VCDM 2.0 credential with the subject data supplied inline."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Membership offer created', () => pm.expect([200, 201], 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url) => {",
                      "  const publicHost = pm.variables.get('tenantHost');",
                      "  const gatewayBase = trimBase(pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && publicHost && m[2] === publicHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "pm.expect(j.offer_uri, 'offer uri').to.be.a('string').and.not.empty;",
                      "const m = String(j.offer_uri).match(/credential_offer_uri=([^&]+)/);",
                      "pm.expect(m, 'offer uri carries credential_offer_uri').to.not.eql(null);",
                      "pm.collectionVariables.set('membershipOfferUri', rewritePublicUrl(decodeURIComponent(m[1])));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/credential/offers",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_configuration_ids\": [\n    \"Membership\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"id\": \"did:example:member-0001\",\n    \"type\": \"MembershipCredential\",\n    \"name\": \"Erika Mustermann\",\n    \"membershipNumber\": \"ACME-M-2026-0042\",\n    \"membershipLevel\": \"gold\",\n    \"validFrom\": \"2026-01-01\"\n  },\n  \"correlation_id\": \"e2e-membership-001\"\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"e2e-membership-001\",\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"offer_uri\": \"openid-credential-offer://?credential_offer_uri=https%3A%2F%2Facme.example.com%2Foid4vci%2Facme%2Foid4vci%2Fcredentials%2Foffers%2F00000000-0000-4000-8000-000000000000\",\n  \"status_uri\": \"https://acme.example.com/api/oid4vci/v1/backend/credential/offers/e2e-membership-001\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Resolve the Membership offer",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{membershipOfferUri}}",
                "header": [],
                "description": "Resolves the offer as a wallet does and reads the pre-authorized code."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Membership offer resolved', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url) => {",
                      "  const publicHost = pm.variables.get('tenantHost');",
                      "  const gatewayBase = trimBase(pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && publicHost && m[2] === publicHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "pm.expect(j.credential_configuration_ids, 'offered configurations').to.eql(['Membership']);",
                      "const grant = j.grants && (j.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'] || j.grants.pre_authorized_code);",
                      "pm.expect(grant && grant['pre-authorized_code'], 'pre-authorized code').to.be.a('string').and.not.empty;",
                      "pm.collectionVariables.set('membershipPreAuthCode', grant['pre-authorized_code']);",
                      "pm.collectionVariables.set('credentialIssuer', j.credential_issuer);",
                      "const parsed = String(j.credential_issuer).match(/^(https?:\\/\\/[^/]+)(\\/.*)?$/);",
                      "pm.collectionVariables.set('membershipMetadataUrl', rewritePublicUrl(parsed[1] + '/.well-known/openid-credential-issuer' + (parsed[2] || '')));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credentials/offers/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"credential_configuration_ids\": [\n    \"Membership\"\n  ],\n  \"grants\": {\n    \"urn:ietf:params:oauth:grant-type:pre-authorized_code\": {\n      \"pre-authorized_code\": \"<code>\"\n    }\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Fetch the VCDM 2.0 OID4VCI metadata",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{membershipMetadataUrl}}",
                "header": [],
                "description": "Reads the issuer metadata and confirms the VCDM 2.0 credential is advertised with the `jwt_vc_json-ld` format."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('VCDM 2.0 metadata served', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const trimBase = (base) => base && base.endsWith('/') ? base.slice(0, -1) : base;",
                      "const rewritePublicUrl = (url) => {",
                      "  const publicHost = pm.variables.get('tenantHost');",
                      "  const gatewayBase = trimBase(pm.variables.get('tenantGatewayUrl'));",
                      "  const m = String(url || '').match(/^(https?:\\/\\/([^/]+))(.*)$/);",
                      "  if (m && publicHost && m[2] === publicHost && gatewayBase) return gatewayBase + (m[3] || '');",
                      "  return url;",
                      "};",
                      "const configuration = (j.credential_configurations_supported || {})['Membership'];",
                      "pm.test('the issuer advertises Membership as jwt_vc_json-ld', () => {",
                      "  pm.expect(configuration, 'credential configuration').to.be.an('object');",
                      "  pm.expect(configuration.format, 'format').to.eql('jwt_vc_json-ld');",
                      "});",
                      "pm.collectionVariables.set('membershipCredentialEndpoint', rewritePublicUrl(j.credential_endpoint));",
                      "const advertisedAs = Array.isArray(j.authorization_servers) && j.authorization_servers.length ? j.authorization_servers[0] : null;",
                      "pm.collectionVariables.set('membershipTokenEndpoint', rewritePublicUrl(j.token_endpoint || (String(advertisedAs).replace(/\\/$/, '') + '/token')));",
                      "if (j.nonce_endpoint) pm.collectionVariables.set('nonceEndpoint', rewritePublicUrl(j.nonce_endpoint));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/.well-known/openid-credential-issuer/oid4vci/acme",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credential_issuer\": \"https://acme.example.com/oid4vci/acme\",\n  \"authorization_servers\": [\n    \"https://acme.example.com/as/acme\"\n  ],\n  \"credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/credential\",\n  \"deferred_credential_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/deferredCredential\",\n  \"notification_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/notification\",\n  \"nonce_endpoint\": \"https://acme.example.com/oid4vci/acme/oid4vci/nonce\",\n  \"credential_configurations_supported\": {\n    \"EuPid\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu_pid\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\",\n        \"did:jwk\",\n        \"did:key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"https://acme.example.com/public/schema/vct/EuPid\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"EU Personal ID\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"European personal identity credential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"EU Persoonlijke ID\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"EU PID logo\"\n            },\n            \"description\": \"Europese persoonlijke identiteitscredential\",\n            \"background_color\": \"#0B5FFF\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"age_over_18\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Age over 18\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Ouder dan 18\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"nationality\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Nationality\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Nationaliteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"document_number\"\n            ],\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"Mdl\": {\n      \"format\": \"mso_mdoc\",\n      \"scope\": \"mdl\",\n      \"cryptographic_binding_methods_supported\": [\n        \"cose_key\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        -7\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"doctype\": \"org.iso.18013.5.1.mDL\",\n      \"credential_metadata\": {\n        \"display\": [\n          {\n            \"name\": \"Mobile Driving Licence\",\n            \"locale\": \"en\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobile driving licence\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          },\n          {\n            \"name\": \"Mobiel Rijbewijs\",\n            \"locale\": \"nl\",\n            \"logo\": {\n              \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n              \"alt_text\": \"Mobile driving licence logo\"\n            },\n            \"description\": \"ISO 18013-5 mobiel rijbewijs\",\n            \"background_color\": \"#1B5E20\",\n            \"text_color\": \"#FFFFFF\"\n          }\n        ],\n        \"claims\": [\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"family_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Family name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Achternaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"given_name\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Given name\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Voornaam\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"birth_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Date of birth\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Geboortedatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issue_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issue date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Datum van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"expiry_date\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Expiry date\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Vervaldatum\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_country\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing country\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Land van uitgifte\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"issuing_authority\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Issuing authority\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Uitgevende autoriteit\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"document_number\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Document number\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Documentnummer\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"portrait\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Portrait\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Portret\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"driving_privileges\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"Driving privileges\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"Rijbevoegdheden\",\n                \"locale\": \"nl\"\n              }\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"un_distinguishing_sign\"\n            ],\n            \"mandatory\": true,\n            \"display\": [\n              {\n                \"name\": \"UN distinguishing sign\",\n                \"locale\": \"en\"\n              },\n              {\n                \"name\": \"VN-onderscheidingsteken\",\n                \"locale\": \"nl\"\n              }\n            ]\n          }\n        ]\n      }\n    },\n    \"EmployeeBadge\": {\n      \"format\": \"jwt_vc_json\",\n      \"scope\": \"employeebadge\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"EmployeeBadgeCredential\"\n        ]\n      }\n    },\n    \"Membership\": {\n      \"format\": \"jwt_vc_json-ld\",\n      \"scope\": \"membership\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"credential_definition\": {\n        \"type\": [\n          \"VerifiableCredential\",\n          \"MembershipCredential\"\n        ]\n      }\n    },\n    \"EuPidShared\": {\n      \"format\": \"dc+sd-jwt\",\n      \"scope\": \"eu.europa.ec.eudi.pid.shared\",\n      \"cryptographic_binding_methods_supported\": [\n        \"jwk\"\n      ],\n      \"credential_signing_alg_values_supported\": [\n        \"ES256\"\n      ],\n      \"proof_types_supported\": {\n        \"jwt\": {\n          \"proof_signing_alg_values_supported\": [\n            \"ES256\"\n          ]\n        }\n      },\n      \"vct\": \"urn:eudi:pid:shared\"\n    }\n  },\n  \"display\": [\n    {\n      \"name\": \"Acme Corporation Authority\",\n      \"locale\": \"en\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    },\n    {\n      \"name\": \"Acme Corporation Autoriteit\",\n      \"locale\": \"nl\",\n      \"logo\": {\n        \"uri\": \"https://acme.example.com/public/assets/design/2b3582f505a052b8f8c011eae6c10cecc590cf2f3941a8dbecd181e4c9f0e863.png\",\n        \"alt_text\": \"Acme Corporation authority logo\"\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Exchange the Membership pre-authorized code",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "POST",
                "url": "{{membershipTokenEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/x-www-form-urlencoded"
                  }
                ],
                "body": {
                  "mode": "urlencoded",
                  "urlencoded": [
                    {
                      "key": "grant_type",
                      "value": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
                    },
                    {
                      "key": "pre-authorized_code",
                      "value": "{{membershipPreAuthCode}}"
                    }
                  ]
                },
                "description": "Exchanges the pre-authorized code for the wallet access token and the opaque credential identifier."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Membership token issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const j = pm.response.json();",
                      "const authorization = Array.isArray(j.authorization_details) ? j.authorization_details.find((detail) => detail && detail.credential_configuration_id === 'Membership') : undefined;",
                      "const identifiers = authorization && authorization.credential_identifiers;",
                      "pm.test('the token returns an opaque Membership credential identifier', () => {",
                      "  pm.expect(identifiers, 'credential identifiers').to.be.an('array').with.lengthOf(1);",
                      "  pm.expect(identifiers[0], 'credential identifier').to.not.eql('Membership');",
                      "});",
                      "pm.collectionVariables.set('membershipCredentialIdentifier', identifiers ? identifiers[0] : '');",
                      "pm.collectionVariables.set('walletAccessToken', j.access_token);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/as/acme/token",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/x-www-form-urlencoded"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "\"grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Apre-authorized_code&pre-authorized_code=%3Credacted%3E\""
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"access_token\": \"eyJ0eXAiOiJhdCtqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6Im9hdXRoMi1hcy1hY21lIn0.eyJpc3MiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vYXMvYWNtZSIsInN1YiI6IiIsImNsaWVudF9pZCI6IiIsImlhdCI6MTc2NzIyNTYwMCwiZXhwIjoxNzk4NzYxNjAwLCJqdGkiOiI8anRpPiIsImF6cCI6IiIsImF1ZCI6Imh0dHBzOi8vYWNtZS5leGFtcGxlLmNvbS9vaWQ0dmNpL2FjbWUiLCJhdXRob3JpemF0aW9uX2RldGFpbHMiOlt7InR5cGUiOiJvcGVuaWRfY3JlZGVudGlhbCIsImNyZWRlbnRpYWxfY29uZmlndXJhdGlvbl9pZCI6Ik1lbWJlcnNoaXAiLCJjcmVkZW50aWFsX2lkZW50aWZpZXJzIjpbInVybjp2ZHg6b2lkNHZjaTpjcmVkZW50aWFsOjAwMDAwMDAwLTAwMDAtNDAwMC04MDAwLTAwMDAwMDAwMDAwMDowMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDAiXX1dLCJ0ZW5hbnRfaWQiOiIwMDAwMDAwMC0wMDAwLTQwMDAtODAwMC0wMDAwMDAwMDAwMDAifQ.SIGNATURE-REDACTED\",\n  \"access_token_decoded\": {\n    \"header\": {\n      \"typ\": \"at+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"oauth2-as-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"https://acme.example.com/as/acme\",\n      \"sub\": \"\",\n      \"client_id\": \"\",\n      \"iat\": 1767225600,\n      \"exp\": 1798761600,\n      \"jti\": \"<jti>\",\n      \"azp\": \"\",\n      \"aud\": \"https://acme.example.com/oid4vci/acme\",\n      \"authorization_details\": [\n        {\n          \"type\": \"openid_credential\",\n          \"credential_configuration_id\": \"Membership\",\n          \"credential_identifiers\": [\n            \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n          ]\n        }\n      ],\n      \"tenant_id\": \"00000000-0000-4000-8000-000000000000\"\n    }\n  },\n  \"token_type\": \"Bearer\",\n  \"expires_in\": 3600,\n  \"authorization_details\": [\n    {\n      \"type\": \"openid_credential\",\n      \"credential_configuration_id\": \"Membership\",\n      \"credential_identifiers\": [\n        \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\"\n      ]\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 Request the Membership credential",
              "request": {
                "auth": {
                  "type": "bearer",
                  "bearer": [
                    {
                      "key": "token",
                      "value": "{{walletAccessToken}}",
                      "type": "string"
                    }
                  ]
                },
                "method": "POST",
                "url": "{{membershipCredentialEndpoint}}",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_identifier\": \"{{membershipCredentialIdentifier}}\",\n  \"proofs\": {\n    \"jwt\": [\"{{proofJwt}}\"]\n  }\n}"
                },
                "description": "Issues the VCDM 2.0 credential as a VC-JWT with an ES256 proof of possession. The test decodes the returned JWT and checks the VCDM context, the credential type and the status entry. `credentialStatus.type` is `BitstringStatusListEntry` for VCDM 1.1 as well as VCDM 2.0."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "try {",
                      "  pm.test('Membership credential issued', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "  const j = pm.response.json();",
                      "  const credential = (j.credentials && j.credentials[0] && j.credentials[0].credential) || j.credential;",
                      "  pm.expect(credential, 'credential').to.be.a('string').and.not.empty;",
                      "  const decodeJwtPart = (jwt, index) => {",
                      "    const compact = String(jwt || '').split('~')[0];",
                      "    const segment = compact.split('.')[index];",
                      "    pm.expect(segment, 'jwt segment ' + index).to.be.a('string').and.not.empty;",
                      "    const normalized = segment.replace(/-/g, '+').replace(/_/g, '/');",
                      "    const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);",
                      "    return JSON.parse(atob(padded));",
                      "  };",
                      "  const payload = decodeJwtPart(credential, 1);",
                      "  // VCDM 1.1 VC-JWT nests the credential under 'vc'; the VCDM 2.0 JOSE form carries it at the top.",
                      "  const vc = payload.vc || payload;",
                      "  const contexts = [].concat(vc['@context'] || []);",
                      "  const types = [].concat(vc.type || []);",
                      "  const credentialStatus = [].concat(vc.credentialStatus || [])[0] || {};",
                      "  pm.test('the credential is a VCDM 2.0 verifiable credential of type MembershipCredential', () => {",
                      "    pm.expect(contexts, 'JSON-LD context').to.include('https://www.w3.org/ns/credentials/v2');",
                      "    pm.expect(types, 'credential types').to.include('VerifiableCredential');",
                      "    pm.expect(types, 'credential types').to.include('MembershipCredential');",
                      "  });",
                      "  pm.test('the credential status entry is a BitstringStatusListEntry on the bitstring list', () => {",
                      "    pm.expect(credentialStatus.type, 'credentialStatus.type').to.eql('BitstringStatusListEntry');",
                      "    pm.expect(String(credentialStatus.statusListCredential || credentialStatus.id || ''), 'status list reference').to.contain('/public/statuslists/status-bitstring');",
                      "    pm.expect(String(credentialStatus.statusListIndex || ''), 'allocated index').to.not.be.empty;",
                      "  });",
                      "  pm.collectionVariables.set('membershipStatusIndex', String(credentialStatus.statusListIndex || ''));",
                      "} finally {",
                      "  pm.collectionVariables.unset('holderWalletPrivateScalar');",
                      "  pm.collectionVariables.unset('holderWalletPublicJwk');",
                      "  pm.collectionVariables.unset('proofJwt');",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/oid4vci/acme/oid4vci/credential",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_identifier\": \"urn:vdx:oid4vci:credential:00000000-0000-4000-8000-000000000000:00000000-0000-4000-8000-000000000000\",\n  \"proofs\": {\n    \"jwt\": [\n      \"eyJ0eXAiOiJvcGVuaWQ0dmNpLXByb29mK2p3dCIsImFsZyI6IkVTMjU2IiwiandrIjp7Imt0eSI6IkVDIiwiY3J2IjoiUC0yNTYiLCJ4IjoiPHB1YmxpYy1rZXktbWF0ZXJpYWw-IiwieSI6IjxwdWJsaWMta2V5LW1hdGVyaWFsPiJ9fQ.eyJhdWQiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vb2lkNHZjaS9hY21lIiwiaWF0IjoxNzY3MjI1NjAwLCJub25jZSI6Ijxub25jZT4ifQ.SIGNATURE-REDACTED\"\n    ]\n  }\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"credentials\": [\n    {\n      \"credential\": \"eyJ0eXAiOiJ2Yytqd3QiLCJhbGciOiJFUzI1NiIsImtpZCI6ImRpZDp3ZWI6YWNtZS5leGFtcGxlLmNvbSNpc3N1ZXItYXNzZXJ0aW9uLWFjbWUiLCJjdHkiOiJ2YyJ9.eyJAY29udGV4dCI6WyJodHRwczovL3d3dy53My5vcmcvbnMvY3JlZGVudGlhbHMvdjIiXSwidHlwZSI6WyJWZXJpZmlhYmxlQ3JlZGVudGlhbCIsIk1lbWJlcnNoaXBDcmVkZW50aWFsIl0sImlzc3VlciI6Imh0dHBzOi8vYWNtZS5leGFtcGxlLmNvbS9vaWQ0dmNpL2FjbWUiLCJ2YWxpZEZyb20iOiIyMDI2LTAxLTAxVDAwOjAwOjAwWiIsInZhbGlkVW50aWwiOiIyMDI3LTAxLTAxVDAwOjAwOjAwWiIsImNyZWRlbnRpYWxTdWJqZWN0Ijp7ImlkIjoiZGlkOmV4YW1wbGU6bWVtYmVyLTAwMDEiLCJ0eXBlIjoiTWVtYmVyc2hpcENyZWRlbnRpYWwiLCJuYW1lIjoiRXJpa2EgTXVzdGVybWFubiIsIm1lbWJlcnNoaXBOdW1iZXIiOiJBQ01FLU0tMjAyNi0wMDQyIiwibWVtYmVyc2hpcExldmVsIjoiZ29sZCIsInZhbGlkRnJvbSI6IjIwMjYtMDEtMDEifSwiaWQiOiI8anRpPiIsImNyZWRlbnRpYWxTdGF0dXMiOnsiaWQiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vcHVibGljL3N0YXR1c2xpc3RzL3N0YXR1cy1iaXRzdHJpbmcjMTAwNiIsInR5cGUiOiJCaXRzdHJpbmdTdGF0dXNMaXN0RW50cnkiLCJzdGF0dXNQdXJwb3NlIjoicmV2b2NhdGlvbiIsInN0YXR1c0xpc3RJbmRleCI6IjEwMDYiLCJzdGF0dXNMaXN0Q3JlZGVudGlhbCI6Imh0dHBzOi8vYWNtZS5leGFtcGxlLmNvbS9wdWJsaWMvc3RhdHVzbGlzdHMvc3RhdHVzLWJpdHN0cmluZyJ9LCJpc3MiOiJodHRwczovL2FjbWUuZXhhbXBsZS5jb20vb2lkNHZjaS9hY21lIiwianRpIjoiPGp0aT4iLCJpYXQiOjE3NjcyMjU2MDAsImV4cCI6MTc5ODc2MTYwMCwiY25mIjp7Imp3ayI6eyJrdHkiOiJFQyIsImNydiI6IlAtMjU2IiwieCI6IjxwdWJsaWMta2V5LW1hdGVyaWFsPiIsInkiOiI8cHVibGljLWtleS1tYXRlcmlhbD4ifX19.SIGNATURE-REDACTED\",\n      \"credential_decoded\": {\n        \"header\": {\n          \"typ\": \"vc+jwt\",\n          \"alg\": \"ES256\",\n          \"kid\": \"did:web:acme.example.com#issuer-assertion-acme\",\n          \"cty\": \"vc\"\n        },\n        \"payload\": {\n          \"@context\": [\n            \"https://www.w3.org/ns/credentials/v2\"\n          ],\n          \"type\": [\n            \"VerifiableCredential\",\n            \"MembershipCredential\"\n          ],\n          \"issuer\": \"https://acme.example.com/oid4vci/acme\",\n          \"validFrom\": \"2026-01-01T00:00:00Z\",\n          \"validUntil\": \"2027-01-01T00:00:00Z\",\n          \"credentialSubject\": {\n            \"id\": \"did:example:member-0001\",\n            \"type\": \"MembershipCredential\",\n            \"name\": \"Erika Mustermann\",\n            \"membershipNumber\": \"ACME-M-2026-0042\",\n            \"membershipLevel\": \"gold\",\n            \"validFrom\": \"2026-01-01\"\n          },\n          \"id\": \"<jti>\",\n          \"credentialStatus\": {\n            \"id\": \"https://acme.example.com/public/statuslists/status-bitstring#1006\",\n            \"type\": \"BitstringStatusListEntry\",\n            \"statusPurpose\": \"revocation\",\n            \"statusListIndex\": \"1006\",\n            \"statusListCredential\": \"https://acme.example.com/public/statuslists/status-bitstring\"\n          },\n          \"iss\": \"https://acme.example.com/oid4vci/acme\",\n          \"jti\": \"<jti>\",\n          \"iat\": 1767225600,\n          \"exp\": 1798761600,\n          \"cnf\": {\n            \"jwk\": {\n              \"kty\": \"EC\",\n              \"crv\": \"P-256\",\n              \"x\": \"<public-key-material>\",\n              \"y\": \"<public-key-material>\"\n            }\n          }\n        }\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "07 Check the Membership offer status",
              "request": {
                "method": "GET",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers/e2e-membership-001",
                "header": [],
                "description": "Reads the backend session by its business key. The lifecycle ends in credential_issued."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Membership session tracked', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/credential/offers/e2e-membership-001",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"e2e-membership-001\",\n  \"status\": \"credential_issued\",\n  \"last_updated\": 1767225600000,\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"offer_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"issuance_session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"created_at\": 1767225600000,\n  \"expires_at\": 1798761600000,\n  \"error\": null,\n  \"issuance_data\": {\n    \"credential_configuration_ids\": [\n      \"Membership\"\n    ],\n    \"credential_identifiers\": null\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "08 Read the Membership status entry",
              "request": {
                "method": "GET",
                "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{bitstringStatusListId}}/entries/{{membershipStatusIndex}}",
                "header": [],
                "description": "Reads the bitstring entry the issued credential points at. A freshly issued credential is valid, so the entry reads 0."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Membership status entry returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "const entry = pm.response.json();",
                      "pm.test('the freshly issued VCDM 2.0 credential is valid', () => {",
                      "  pm.expect(entry.statusListIndex, 'index').to.eql(Number(pm.collectionVariables.get('membershipStatusIndex')));",
                      "  pm.expect(entry.value, 'value').to.eql(0);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/statuslist/v1/statuslists/00000000-0000-4000-8000-000000000000/entries/1006",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"statusListId\": \"00000000-0000-4000-8000-000000000000\",\n  \"statusListIndex\": 1006,\n  \"entryCorrelationId\": \"\",\n  \"credentialId\": \"<jti>\",\n  \"credentialHash\": null,\n  \"value\": 0,\n  \"purpose\": \"revocation\",\n  \"identifier\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "// Minimal collection-local P-256 holder fixture for Postman/Newman.",
                  "// The private scalar stays in a runtime collection variable and is never sent or logged.",
                  "const CURVE_P = BigInt('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff');",
                  "const CURVE_A = CURVE_P - 3n;",
                  "const CURVE_N = BigInt('0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551');",
                  "const CURVE_G = {",
                  "  x: BigInt('0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296'),",
                  "  y: BigInt('0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5')",
                  "};",
                  "const mod = (value, modulus) => {",
                  "  const result = value % modulus;",
                  "  return result >= 0n ? result : result + modulus;",
                  "};",
                  "const inverse = (value, modulus) => {",
                  "  let low = mod(value, modulus);",
                  "  let high = modulus;",
                  "  let lowCoefficient = 1n;",
                  "  let highCoefficient = 0n;",
                  "  while (low > 1n) {",
                  "    const ratio = high / low;",
                  "    const next = high - low * ratio;",
                  "    const nextCoefficient = highCoefficient - lowCoefficient * ratio;",
                  "    high = low;",
                  "    low = next;",
                  "    highCoefficient = lowCoefficient;",
                  "    lowCoefficient = nextCoefficient;",
                  "  }",
                  "  if (low !== 1n) throw new Error('P-256 modular inverse does not exist');",
                  "  return mod(lowCoefficient, modulus);",
                  "};",
                  "const pointAdd = (left, right) => {",
                  "  if (!left) return right;",
                  "  if (!right) return left;",
                  "  let slope;",
                  "  if (left.x === right.x) {",
                  "    if (mod(left.y + right.y, CURVE_P) === 0n) return null;",
                  "    slope = mod((3n * left.x * left.x + CURVE_A) * inverse(2n * left.y, CURVE_P), CURVE_P);",
                  "  } else {",
                  "    slope = mod((right.y - left.y) * inverse(right.x - left.x, CURVE_P), CURVE_P);",
                  "  }",
                  "  const x = mod(slope * slope - left.x - right.x, CURVE_P);",
                  "  return { x: x, y: mod(slope * (left.x - x) - left.y, CURVE_P) };",
                  "};",
                  "const scalarMultiply = (scalar, point) => {",
                  "  let remaining = scalar;",
                  "  let result = null;",
                  "  let addend = point;",
                  "  while (remaining > 0n) {",
                  "    if ((remaining & 1n) === 1n) result = pointAdd(result, addend);",
                  "    addend = pointAdd(addend, addend);",
                  "    remaining >>= 1n;",
                  "  }",
                  "  return result;",
                  "};",
                  "const randomScalar = () => {",
                  "  while (true) {",
                  "    const candidateHex = CryptoJS.lib.WordArray.random(32).toString(CryptoJS.enc.Hex);",
                  "    const candidate = BigInt('0x' + candidateHex);",
                  "    if (candidate > 0n && candidate < CURVE_N) return candidate;",
                  "  }",
                  "};",
                  "const hex32 = (value) => value.toString(16).padStart(64, '0');",
                  "const base64Url = (wordArray) => CryptoJS.enc.Base64.stringify(wordArray).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '');",
                  "const base64UrlHex = (hex) => base64Url(CryptoJS.enc.Hex.parse(hex));",
                  "const base64UrlJson = (value) => base64Url(CryptoJS.enc.Utf8.parse(JSON.stringify(value)));",
                  "if (pm.info.requestName === '01 Create EuPid offer') {",
                  "  pm.collectionVariables.unset('holderWalletPrivateScalar');",
                  "  pm.collectionVariables.unset('holderWalletPublicJwk');",
                  "  pm.collectionVariables.unset('proofJwt');",
                  "}",
                  "let holderPrivateHex = String(pm.collectionVariables.get('holderWalletPrivateScalar') || '');",
                  "let holderPublicJwkText = String(pm.collectionVariables.get('holderWalletPublicJwk') || '');",
                  "let holderPublicJwk;",
                  "try { holderPublicJwk = JSON.parse(holderPublicJwkText); } catch (_) { holderPublicJwk = null; }",
                  "if (!/^[0-9a-f]{64}$/.test(holderPrivateHex) || !holderPublicJwk || holderPublicJwk.kty !== 'EC' || holderPublicJwk.crv !== 'P-256') {",
                  "  const holderPrivate = randomScalar();",
                  "  const holderPublic = scalarMultiply(holderPrivate, CURVE_G);",
                  "  holderPrivateHex = hex32(holderPrivate);",
                  "  holderPublicJwk = { kty: 'EC', crv: 'P-256', x: base64UrlHex(hex32(holderPublic.x)), y: base64UrlHex(hex32(holderPublic.y)) };",
                  "  holderPublicJwkText = JSON.stringify(holderPublicJwk);",
                  "  pm.collectionVariables.set('holderWalletPrivateScalar', holderPrivateHex);",
                  "  pm.collectionVariables.set('holderWalletPublicJwk', holderPublicJwkText);",
                  "}",
                  "const signEs256 = (signingInput) => {",
                  "  const privateScalar = BigInt('0x' + holderPrivateHex);",
                  "  const digest = BigInt('0x' + CryptoJS.SHA256(signingInput).toString(CryptoJS.enc.Hex));",
                  "  while (true) {",
                  "    const ephemeral = randomScalar();",
                  "    const point = scalarMultiply(ephemeral, CURVE_G);",
                  "    const r = mod(point.x, CURVE_N);",
                  "    if (r === 0n) continue;",
                  "    let s = mod(inverse(ephemeral, CURVE_N) * (digest + r * privateScalar), CURVE_N);",
                  "    if (s === 0n) continue;",
                  "    if (s > CURVE_N / 2n) s = CURVE_N - s;",
                  "    return base64UrlHex(hex32(r) + hex32(s));",
                  "  }",
                  "};",
                  "const buildHolderProof = (nonce) => {",
                  "  const header = { alg: 'ES256', typ: 'openid4vci-proof+jwt', jwk: holderPublicJwk };",
                  "  const payload = {",
                  "    aud: pm.collectionVariables.get('credentialIssuer') || pm.variables.get('tenantGatewayUrl'),",
                  "    iat: Math.floor(Date.now() / 1000)",
                  "  };",
                  "  if (nonce) payload.nonce = nonce;",
                  "  const signingInput = base64UrlJson(header) + '.' + base64UrlJson(payload);",
                  "  pm.collectionVariables.set('proofJwt', signingInput + '.' + signEs256(signingInput));",
                  "};",
                  "if (pm.info.requestName === '06 Request the Membership credential') {",
                  "  const nonceEndpoint = String(pm.collectionVariables.get('nonceEndpoint') || '').trim();",
                  "  if (nonceEndpoint) {",
                  "    pm.sendRequest({ url: nonceEndpoint, method: 'POST', header: { 'Host': pm.variables.get('tenantHost') } }, (error, response) => {",
                  "      if (error) throw new Error('OID4VCI nonce fetch failed: ' + error.message);",
                  "      const nonce = response.json().c_nonce;",
                  "      if (!nonce) throw new Error('OID4VCI nonce response did not contain c_nonce');",
                  "      pm.collectionVariables.set('membershipNonce', nonce);",
                  "      buildHolderProof(nonce);",
                  "    });",
                  "  } else {",
                  "    buildHolderProof(undefined);",
                  "  }",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "19 Issue Through a Pipeline",
          "description": "Exercises the pipeline issuance API where attributes are contributed into a session before approval releases issuance.",
          "item": [
            {
              "name": "01 Initialize pipeline session",
              "request": {
                "method": "POST",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/sessions",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"pipeline_configuration\": {\n    \"pipelineId\": \"eupid-registration\",\n    \"claimsBindings\": [\n      {\n        \"id\": \"EuPid\",\n        \"semanticAttributeSetRef\": {\n          \"bundleId\": \"credential-config:EuPid\"\n        },\n        \"deferralPolicy\": {\n          \"approvalRequired\": true\n        }\n      }\n    ]\n  },\n  \"correlation_id\": \"e2e-pipeline-001\",\n  \"ttl_seconds\": 600\n}"
                },
                "description": "Opens an attribute pipeline session keyed by correlation id, seeded with the lookup keys that attribute sources use to find the subject."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('pipeline session opened', () => pm.expect([200, 201]).to.include(pm.response.code));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/sessions",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"pipeline_configuration\": {\n    \"pipelineId\": \"eupid-registration\",\n    \"claimsBindings\": [\n      {\n        \"id\": \"EuPid\",\n        \"semanticAttributeSetRef\": {\n          \"bundleId\": \"credential-config:EuPid\"\n        },\n        \"deferralPolicy\": {\n          \"approvalRequired\": true\n        }\n      }\n    ]\n  },\n  \"correlation_id\": \"e2e-pipeline-001\",\n  \"ttl_seconds\": 600\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"sessionId\": \"00000000-0000-4000-8000-000000000000\",\n  \"correlationId\": \"e2e-pipeline-001\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Contribute attributes",
              "request": {
                "method": "POST",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/sessions/e2e-pipeline-001/attributes",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"groups\": [\n    {\n      \"contributorId\": \"registration-office\",\n      \"phase\": \"oid4vci_credential_request\",\n      \"timestamp\": \"2026-06-01T00:00:00Z\",\n      \"attributes\": [\n        {\n          \"path\": \"family_name\",\n          \"value\": \"Mustermann\",\n          \"verified\": true\n        },\n        {\n          \"path\": \"given_name\",\n          \"value\": \"Erika\",\n          \"verified\": true\n        },\n        {\n          \"path\": \"birth_date\",\n          \"value\": \"1964-08-12\",\n          \"verified\": true\n        }\n      ]\n    }\n  ]\n}"
                },
                "description": "An attribute source contributes verified claims into the session. Multiple sources can contribute; priorities resolve conflicts."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('attributes contributed', () => pm.expect([200, 201]).to.include(pm.response.code));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/sessions/e2e-pipeline-001/attributes",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"groups\": [\n    {\n      \"contributorId\": \"registration-office\",\n      \"phase\": \"oid4vci_credential_request\",\n      \"timestamp\": \"2026-01-01T00:00:00Z\",\n      \"attributes\": [\n        {\n          \"path\": \"family_name\",\n          \"value\": \"Mustermann\",\n          \"verified\": true\n        },\n        {\n          \"path\": \"given_name\",\n          \"value\": \"Erika\",\n          \"verified\": true\n        },\n        {\n          \"path\": \"birth_date\",\n          \"value\": \"1964-08-12\",\n          \"verified\": true\n        }\n      ]\n    }\n  ]\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"sessionId\": \"00000000-0000-4000-8000-000000000000\",\n  \"status\": \"AWAITING_APPROVAL\",\n  \"completedPhases\": [\n    {\n      \"value\": \"oid4vci_credential_request\"\n    }\n  ],\n  \"instanceId\": null,\n  \"versionId\": \"00000000-0000-4000-8000-000000000000\",\n  \"developerPipeline\": false,\n  \"connectorInvocations\": []\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Read accumulated attributes",
              "request": {
                "method": "GET",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/sessions/e2e-pipeline-001/attributes",
                "description": "Reads the attributes accumulated so far across all sources.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('attributes returned', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/sessions/e2e-pipeline-001/attributes",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"attributes\": {\n    \"family_name\": \"Mustermann\",\n    \"given_name\": \"Erika\",\n    \"birth_date\": \"1964-08-12\"\n  },\n  \"connectorFieldNames\": []\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Evaluate completeness",
              "request": {
                "method": "GET",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/sessions/e2e-pipeline-001/completeness",
                "description": "Evaluates whether the accumulated attributes satisfy each credential binding's mandatory claims, and whether deferral or approval is recommended.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('completeness evaluated', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/sessions/e2e-pipeline-001/completeness",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"verdicts\": [\n    {\n      \"bindingId\": \"EuPid\",\n      \"complete\": true,\n      \"awaitingApproval\": true\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Approve issuance",
              "request": {
                "method": "POST",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/sessions/e2e-pipeline-001/approve",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"decision\": \"APPROVE\",\n  \"reason\": \"Registration office data verified\"\n}"
                },
                "description": "Releases the approval gate. After approval, issuance proceeds with the pipeline-collected attributes instead of inline subject data."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('issuance approved', () => pm.expect([200, 201]).to.include(pm.response.code));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/oid4vci/v1/backend/sessions/e2e-pipeline-001/approve",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"decision\": \"APPROVE\",\n  \"reason\": \"Registration office data verified\"\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlationId\": \"e2e-pipeline-001\",\n  \"status\": \"READY\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "21 DCQL Queries",
          "description": "Creates and lists the DCQL query definitions used by the verifier, including a combined query that requests EuPid and Mdl together.\n\nDocumentation: https://docs.sphereon.com/edk/admin-console/guides/verify-credentials#define-the-dcql-query",
          "item": [
            {
              "name": "01 Create EuPid query",
              "request": {
                "method": "POST",
                "url": "{{tenantDcqlApiBaseUrl}}/queries",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"queryId\": \"walkthrough-eupid-sdjwt\",\n  \"name\": \"EuPid identity check\",\n  \"description\": \"Requests name and age attestation from the EU Personal ID\",\n  \"enabled\": true,\n  \"dcqlQuery\": {\n    \"credentials\": [\n      {\n        \"id\": \"eupid\",\n        \"format\": \"dc+sd-jwt\",\n        \"meta\": {\n          \"vct_values\": [\"{{tenantGatewayUrl}}/public/schema/vct/EuPid\"]\n        },\n        \"claims\": [\n          { \"path\": [\"family_name\"] },\n          { \"path\": [\"given_name\"] },\n          { \"path\": [\"age_over_18\"] }\n        ]\n      }\n    ]\n  }\n}"
                },
                "description": "Selects only family_name, given_name, and age_over_18 from the EuPid. The other claims stay undisclosed."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('eupid query stored', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const q = pm.response.json();",
                      "pm.test('EuPid DCQL query content is versioned and enabled', () => {",
                      "  pm.expect(q.queryId).to.eql('walkthrough-eupid-sdjwt');",
                      "  pm.expect(q.enabled).to.eql(true);",
                      "  pm.expect(q.currentVersion).to.eql(1);",
                      "  const credential = q.dcqlQuery.credentials[0];",
                      "  pm.expect(credential.format).to.eql('dc+sd-jwt');",
                      "  pm.expect(credential.meta.vct_values).to.eql([pm.variables.get('tenantGatewayUrl') + '/public/schema/vct/EuPid']);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/dcql/v1/queries",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"queryId\": \"walkthrough-eupid-sdjwt\",\n  \"name\": \"EuPid identity check\",\n  \"description\": \"Requests name and age attestation from the EU Personal ID\",\n  \"enabled\": true,\n  \"dcqlQuery\": {\n    \"credentials\": [\n      {\n        \"id\": \"eupid\",\n        \"format\": \"dc+sd-jwt\",\n        \"meta\": {\n          \"vct_values\": [\n            \"https://acme.example.com/public/schema/vct/EuPid\"\n          ]\n        },\n        \"claims\": [\n          {\n            \"path\": [\n              \"family_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"given_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"age_over_18\"\n            ]\n          }\n        ]\n      }\n    ]\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"queryId\": \"walkthrough-eupid-sdjwt\",\n  \"name\": \"EuPid identity check\",\n  \"description\": \"Requests name and age attestation from the EU Personal ID\",\n  \"dcqlQuery\": {\n    \"credentials\": [\n      {\n        \"id\": \"eupid\",\n        \"format\": \"dc+sd-jwt\",\n        \"meta\": {\n          \"vct_values\": [\n            \"https://acme.example.com/public/schema/vct/EuPid\"\n          ]\n        },\n        \"claims\": [\n          {\n            \"path\": [\n              \"family_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"given_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"age_over_18\"\n            ]\n          }\n        ],\n        \"require_cryptographic_holder_binding\": true,\n        \"multiple\": false\n      }\n    ]\n  },\n  \"enabled\": true,\n  \"createdAt\": 1767225600000,\n  \"updatedAt\": 1767225600000,\n  \"currentVersion\": 1\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Create Mdl query",
              "request": {
                "method": "POST",
                "url": "{{tenantDcqlApiBaseUrl}}/queries",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"queryId\": \"walkthrough-mdl-mdoc\",\n  \"name\": \"Driving licence check\",\n  \"description\": \"Requests the holder name from the mobile driving licence\",\n  \"enabled\": true,\n  \"dcqlQuery\": {\n    \"credentials\": [\n      {\n        \"id\": \"mdl\",\n        \"format\": \"mso_mdoc\",\n        \"meta\": {\n          \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n        },\n        \"claims\": [\n          { \"path\": [\"org.iso.18013.5.1\", \"family_name\"] },\n          { \"path\": [\"org.iso.18013.5.1\", \"given_name\"] }\n        ]\n      }\n    ]\n  }\n}"
                },
                "description": "Selects family_name and given_name from the ISO 18013-5 namespace."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('mdl query stored', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const q = pm.response.json();",
                      "pm.test('mDL DCQL query content is versioned and enabled', () => {",
                      "  pm.expect(q.queryId).to.eql('walkthrough-mdl-mdoc');",
                      "  pm.expect(q.enabled).to.eql(true);",
                      "  pm.expect(q.currentVersion).to.eql(1);",
                      "  const credential = q.dcqlQuery.credentials[0];",
                      "  pm.expect(credential.format).to.eql('mso_mdoc');",
                      "  pm.expect(credential.meta.doctype_value).to.eql('org.iso.18013.5.1.mDL');",
                      "  pm.expect(credential.claims.map((claim) => claim.path)).to.eql([['org.iso.18013.5.1', 'family_name'], ['org.iso.18013.5.1', 'given_name']]);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/dcql/v1/queries",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"queryId\": \"walkthrough-mdl-mdoc\",\n  \"name\": \"Driving licence check\",\n  \"description\": \"Requests the holder name from the mobile driving licence\",\n  \"enabled\": true,\n  \"dcqlQuery\": {\n    \"credentials\": [\n      {\n        \"id\": \"mdl\",\n        \"format\": \"mso_mdoc\",\n        \"meta\": {\n          \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n        },\n        \"claims\": [\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"family_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"given_name\"\n            ]\n          }\n        ]\n      }\n    ]\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"queryId\": \"walkthrough-mdl-mdoc\",\n  \"name\": \"Driving licence check\",\n  \"description\": \"Requests the holder name from the mobile driving licence\",\n  \"dcqlQuery\": {\n    \"credentials\": [\n      {\n        \"id\": \"mdl\",\n        \"format\": \"mso_mdoc\",\n        \"meta\": {\n          \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n        },\n        \"claims\": [\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"family_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"given_name\"\n            ]\n          }\n        ],\n        \"require_cryptographic_holder_binding\": true,\n        \"multiple\": false\n      }\n    ]\n  },\n  \"enabled\": true,\n  \"createdAt\": 1767225600000,\n  \"updatedAt\": 1767225600000,\n  \"currentVersion\": 1\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Create combined query",
              "request": {
                "method": "POST",
                "url": "{{tenantDcqlApiBaseUrl}}/queries",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"queryId\": \"walkthrough-eupid-and-mdl\",\n  \"name\": \"Identity and driving licence\",\n  \"description\": \"Requests the EuPid and the mobile driving licence in one presentation\",\n  \"enabled\": true,\n  \"dcqlQuery\": {\n    \"credentials\": [\n      {\n        \"id\": \"eupid\",\n        \"format\": \"dc+sd-jwt\",\n        \"meta\": {\n          \"vct_values\": [\"{{tenantGatewayUrl}}/public/schema/vct/EuPid\"]\n        },\n        \"claims\": [\n          { \"path\": [\"family_name\"] },\n          { \"path\": [\"given_name\"] }\n        ]\n      },\n      {\n        \"id\": \"mdl\",\n        \"format\": \"mso_mdoc\",\n        \"meta\": {\n          \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n        },\n        \"claims\": [\n          { \"path\": [\"org.iso.18013.5.1\", \"family_name\"] },\n          { \"path\": [\"org.iso.18013.5.1\", \"given_name\"] }\n        ]\n      }\n    ]\n  }\n}"
                },
                "description": "Requests both credentials in a single presentation, each with its own claim selection."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('combined query stored', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const q = pm.response.json();",
                      "pm.test('combined DCQL query contains EuPid and mDL credentials', () => {",
                      "  pm.expect(q.queryId).to.eql('walkthrough-eupid-and-mdl');",
                      "  pm.expect(q.enabled).to.eql(true);",
                      "  pm.expect(q.currentVersion).to.eql(1);",
                      "  const byId = Object.fromEntries(q.dcqlQuery.credentials.map((credential) => [credential.id, credential]));",
                      "  pm.expect(byId.eupid.format).to.eql('dc+sd-jwt');",
                      "  pm.expect(byId.eupid.meta.vct_values).to.eql([pm.variables.get('tenantGatewayUrl') + '/public/schema/vct/EuPid']);",
                      "  pm.expect(byId.mdl.format).to.eql('mso_mdoc');",
                      "  pm.expect(byId.mdl.meta.doctype_value).to.eql('org.iso.18013.5.1.mDL');",
                      "  pm.expect(byId.mdl.claims.map((claim) => claim.path)).to.eql([['org.iso.18013.5.1', 'family_name'], ['org.iso.18013.5.1', 'given_name']]);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/dcql/v1/queries",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"queryId\": \"walkthrough-eupid-and-mdl\",\n  \"name\": \"Identity and driving licence\",\n  \"description\": \"Requests the EuPid and the mobile driving licence in one presentation\",\n  \"enabled\": true,\n  \"dcqlQuery\": {\n    \"credentials\": [\n      {\n        \"id\": \"eupid\",\n        \"format\": \"dc+sd-jwt\",\n        \"meta\": {\n          \"vct_values\": [\n            \"https://acme.example.com/public/schema/vct/EuPid\"\n          ]\n        },\n        \"claims\": [\n          {\n            \"path\": [\n              \"family_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"given_name\"\n            ]\n          }\n        ]\n      },\n      {\n        \"id\": \"mdl\",\n        \"format\": \"mso_mdoc\",\n        \"meta\": {\n          \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n        },\n        \"claims\": [\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"family_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"given_name\"\n            ]\n          }\n        ]\n      }\n    ]\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"queryId\": \"walkthrough-eupid-and-mdl\",\n  \"name\": \"Identity and driving licence\",\n  \"description\": \"Requests the EuPid and the mobile driving licence in one presentation\",\n  \"dcqlQuery\": {\n    \"credentials\": [\n      {\n        \"id\": \"eupid\",\n        \"format\": \"dc+sd-jwt\",\n        \"meta\": {\n          \"vct_values\": [\n            \"https://acme.example.com/public/schema/vct/EuPid\"\n          ]\n        },\n        \"claims\": [\n          {\n            \"path\": [\n              \"family_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"given_name\"\n            ]\n          }\n        ],\n        \"require_cryptographic_holder_binding\": true,\n        \"multiple\": false\n      },\n      {\n        \"id\": \"mdl\",\n        \"format\": \"mso_mdoc\",\n        \"meta\": {\n          \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n        },\n        \"claims\": [\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"family_name\"\n            ]\n          },\n          {\n            \"path\": [\n              \"org.iso.18013.5.1\",\n              \"given_name\"\n            ]\n          }\n        ],\n        \"require_cryptographic_holder_binding\": true,\n        \"multiple\": false\n      }\n    ]\n  },\n  \"enabled\": true,\n  \"createdAt\": 1767225600000,\n  \"updatedAt\": 1767225600000,\n  \"currentVersion\": 1\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 List queries",
              "request": {
                "method": "GET",
                "url": "{{tenantDcqlApiBaseUrl}}/queries",
                "description": "Lists the tenant's stored DCQL query configurations.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('queries listed', () => pm.response.to.have.status(200));",
                      "const queries = pm.response.json();",
                      "const byId = Object.fromEntries(queries.map((query) => [query.queryId, query]));",
                      "pm.test('query list includes exact enabled EuPid, mDL, and combined definitions', () => {",
                      "  ['eupid-sdjwt', 'mdl-mdoc', 'eupid-and-mdl'].forEach((id) => pm.expect(byId[id], id).to.be.an('object'));",
                      "  pm.expect(byId['eupid-sdjwt'].enabled).to.eql(true);",
                      "  pm.expect(byId['eupid-sdjwt'].dcqlQuery.credentials[0].format).to.eql('dc+sd-jwt');",
                      "  pm.expect(byId['eupid-sdjwt'].dcqlQuery.credentials[0].meta.vct_values[0]).to.match(/EuPid/);",
                      "  pm.expect(byId['mdl-mdoc'].enabled).to.eql(true);",
                      "  pm.expect(byId['mdl-mdoc'].dcqlQuery.credentials[0].format).to.eql('mso_mdoc');",
                      "  pm.expect(byId['mdl-mdoc'].dcqlQuery.credentials[0].meta.doctype_value).to.eql('org.iso.18013.5.1.mDL');",
                      "  pm.expect(byId['eupid-and-mdl'].enabled).to.eql(true);",
                      "  pm.expect(byId['eupid-and-mdl'].dcqlQuery.credentials.map((credential) => credential.id).sort()).to.eql(['eupid', 'mdl']);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/dcql/v1/queries",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "[\n  {\n    \"queryId\": \"eupid-and-mdl\",\n    \"name\": \"Identity and driving licence\",\n    \"description\": \"Requests the EuPid and the mobile driving licence in one presentation\",\n    \"dcqlQuery\": {\n      \"credentials\": [\n        {\n          \"id\": \"eupid\",\n          \"format\": \"dc+sd-jwt\",\n          \"meta\": {\n            \"vct_values\": [\n              \"https://acme.example.com/public/schema/vct/EuPid\"\n            ]\n          },\n          \"claims\": [\n            {\n              \"path\": [\n                \"family_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"given_name\"\n              ]\n            }\n          ],\n          \"require_cryptographic_holder_binding\": true,\n          \"multiple\": false\n        },\n        {\n          \"id\": \"mdl\",\n          \"format\": \"mso_mdoc\",\n          \"meta\": {\n            \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n          },\n          \"claims\": [\n            {\n              \"path\": [\n                \"org.iso.18013.5.1\",\n                \"family_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"org.iso.18013.5.1\",\n                \"given_name\"\n              ]\n            }\n          ],\n          \"require_cryptographic_holder_binding\": true,\n          \"multiple\": false\n        }\n      ]\n    },\n    \"enabled\": true,\n    \"createdAt\": 1767225600000,\n    \"updatedAt\": 1767225600000,\n    \"currentVersion\": 1\n  },\n  {\n    \"queryId\": \"eupid-sdjwt\",\n    \"name\": \"EuPid identity check\",\n    \"description\": \"Requests name and age attestation from the EU Personal ID\",\n    \"dcqlQuery\": {\n      \"credentials\": [\n        {\n          \"id\": \"eupid\",\n          \"format\": \"dc+sd-jwt\",\n          \"meta\": {\n            \"vct_values\": [\n              \"https://acme.example.com/public/schema/vct/EuPid\"\n            ]\n          },\n          \"claims\": [\n            {\n              \"path\": [\n                \"family_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"given_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"age_over_18\"\n              ]\n            }\n          ],\n          \"require_cryptographic_holder_binding\": true,\n          \"multiple\": false\n        }\n      ]\n    },\n    \"enabled\": true,\n    \"createdAt\": 1767225600000,\n    \"updatedAt\": 1767225600000,\n    \"currentVersion\": 1\n  },\n  {\n    \"queryId\": \"mdl-mdoc\",\n    \"name\": \"Driving licence check\",\n    \"description\": \"Requests the holder name from the mobile driving licence\",\n    \"dcqlQuery\": {\n      \"credentials\": [\n        {\n          \"id\": \"mdl\",\n          \"format\": \"mso_mdoc\",\n          \"meta\": {\n            \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n          },\n          \"claims\": [\n            {\n              \"path\": [\n                \"org.iso.18013.5.1\",\n                \"family_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"org.iso.18013.5.1\",\n                \"given_name\"\n              ]\n            }\n          ],\n          \"require_cryptographic_holder_binding\": true,\n          \"multiple\": false\n        }\n      ]\n    },\n    \"enabled\": true,\n    \"createdAt\": 1767225600000,\n    \"updatedAt\": 1767225600000,\n    \"currentVersion\": 1\n  },\n  {\n    \"queryId\": \"walkthrough-eupid-and-mdl\",\n    \"name\": \"Identity and driving licence\",\n    \"description\": \"Requests the EuPid and the mobile driving licence in one presentation\",\n    \"dcqlQuery\": {\n      \"credentials\": [\n        {\n          \"id\": \"eupid\",\n          \"format\": \"dc+sd-jwt\",\n          \"meta\": {\n            \"vct_values\": [\n              \"https://acme.example.com/public/schema/vct/EuPid\"\n            ]\n          },\n          \"claims\": [\n            {\n              \"path\": [\n                \"family_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"given_name\"\n              ]\n            }\n          ],\n          \"require_cryptographic_holder_binding\": true,\n          \"multiple\": false\n        },\n        {\n          \"id\": \"mdl\",\n          \"format\": \"mso_mdoc\",\n          \"meta\": {\n            \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n          },\n          \"claims\": [\n            {\n              \"path\": [\n                \"org.iso.18013.5.1\",\n                \"family_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"org.iso.18013.5.1\",\n                \"given_name\"\n              ]\n            }\n          ],\n          \"require_cryptographic_holder_binding\": true,\n          \"multiple\": false\n        }\n      ]\n    },\n    \"enabled\": true,\n    \"createdAt\": 1767225600000,\n    \"updatedAt\": 1767225600000,\n    \"currentVersion\": 1\n  },\n  {\n    \"queryId\": \"walkthrough-eupid-sdjwt\",\n    \"name\": \"EuPid identity check\",\n    \"description\": \"Requests name and age attestation from the EU Personal ID\",\n    \"dcqlQuery\": {\n      \"credentials\": [\n        {\n          \"id\": \"eupid\",\n          \"format\": \"dc+sd-jwt\",\n          \"meta\": {\n            \"vct_values\": [\n              \"https://acme.example.com/public/schema/vct/EuPid\"\n            ]\n          },\n          \"claims\": [\n            {\n              \"path\": [\n                \"family_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"given_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"age_over_18\"\n              ]\n            }\n          ],\n          \"require_cryptographic_holder_binding\": true,\n          \"multiple\": false\n        }\n      ]\n    },\n    \"enabled\": true,\n    \"createdAt\": 1767225600000,\n    \"updatedAt\": 1767225600000,\n    \"currentVersion\": 1\n  },\n  {\n    \"queryId\": \"walkthrough-mdl-mdoc\",\n    \"name\": \"Driving licence check\",\n    \"description\": \"Requests the holder name from the mobile driving licence\",\n    \"dcqlQuery\": {\n      \"credentials\": [\n        {\n          \"id\": \"mdl\",\n          \"format\": \"mso_mdoc\",\n          \"meta\": {\n            \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n          },\n          \"claims\": [\n            {\n              \"path\": [\n                \"org.iso.18013.5.1\",\n                \"family_name\"\n              ]\n            },\n            {\n              \"path\": [\n                \"org.iso.18013.5.1\",\n                \"given_name\"\n              ]\n            }\n          ],\n          \"require_cryptographic_holder_binding\": true,\n          \"multiple\": false\n        }\n      ]\n    },\n    \"enabled\": true,\n    \"createdAt\": 1767225600000,\n    \"updatedAt\": 1767225600000,\n    \"currentVersion\": 1\n  }\n]",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 List combined query versions",
              "request": {
                "method": "GET",
                "url": "{{tenantDcqlApiBaseUrl}}/queries/eupid-and-mdl/versions",
                "description": "Lists version history for the combined DCQL query. This exercises the versioned DCQL store packaged in the verifier image.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('query versions listed', () => pm.response.to.have.status(200));",
                      "const versions = pm.response.json();",
                      "pm.test('combined query version history starts at version 1', () => {",
                      "  pm.expect(Array.isArray(versions) ? versions.length : 0).to.be.greaterThan(0);",
                      "  pm.expect(versions[0].version).to.eql(1);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/dcql/v1/queries/eupid-and-mdl/versions",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "[\n  {\n    \"version\": 1,\n    \"createdAt\": 1767225600000,\n    \"createdBy\": \"00000000-0000-4000-8000-000000000000\"\n  }\n]",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 Bind combined query to verifier",
              "request": {
                "method": "POST",
                "url": "{{tenantDcqlApiBaseUrl}}/verifiers/{{verifierId}}/bindings",
                "description": "Binds the stored combined DCQL query to the tenant verifier instance. Verification requests below pass verifier_id so the verifier resolves the query through this instance binding.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"queryId\": \"eupid-and-mdl\",\n  \"version\": 1\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('combined query bound or already provisioned', () => pm.expect([200, 201, 409]).to.include(pm.response.code));",
                      "const binding = pm.response.json();",
                      "const alreadyExists = pm.response.code === 409;",
                      "if (alreadyExists) {",
                      "  pm.test('combined query binding is already provisioned', () => {",
                      "    pm.expect(binding.error.code).to.eql('ALREADY_EXISTS_ERROR');",
                      "    pm.expect(binding.error.message).to.include('eupid-and-mdl');",
                      "  });",
                      "} else {",
                      "if (binding.id) pm.collectionVariables.set('combinedDcqlBindingId', binding.id);",
                      "pm.test('combined query binding pins version 1 on the tenant verifier', () => {",
                      "  pm.expect(binding.verifierId).to.eql(pm.variables.get('verifierId'));",
                      "  pm.expect(binding.queryId).to.eql('eupid-and-mdl');",
                      "  pm.expect(binding.pinnedVersion).to.eql(1);",
                      "  pm.expect(binding.enabled).to.eql(true);",
                      "});",
                      "}"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/dcql/v1/verifiers/00000000-0000-4000-8000-000000000000/bindings",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"queryId\": \"eupid-and-mdl\",\n  \"version\": 1\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"verifierId\": \"00000000-0000-4000-8000-000000000000\",\n  \"queryId\": \"eupid-and-mdl\",\n  \"pinnedVersion\": 1,\n  \"enabled\": true,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "07 List verifier DCQL bindings",
              "request": {
                "method": "GET",
                "url": "{{tenantDcqlApiBaseUrl}}/verifiers/{{verifierId}}/bindings",
                "description": "Lists the verifier instance bindings and proves the combined query is available to the verifier before verification starts.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('verifier bindings listed', () => pm.response.to.have.status(200));",
                      "const bindings = pm.response.json();",
                      "const binding = bindings.find((b) => b.queryId === 'eupid-and-mdl');",
                      "pm.test('verifier binding list includes the combined query', () => {",
                      "  pm.expect(binding, 'combined binding').to.be.an('object');",
                      "  pm.expect(binding.verifierId).to.eql(pm.variables.get('verifierId'));",
                      "  pm.expect(binding.pinnedVersion).to.eql(1);",
                      "  pm.expect(binding.enabled).to.eql(true);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/dcql/v1/verifiers/00000000-0000-4000-8000-000000000000/bindings",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "[\n  {\n    \"id\": \"00000000-0000-4000-8000-000000000000\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"verifierId\": \"00000000-0000-4000-8000-000000000000\",\n    \"queryId\": \"eupid-and-mdl\",\n    \"pinnedVersion\": 1,\n    \"enabled\": true,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\"\n  }\n]",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "08 List combined query verifier bindings",
              "request": {
                "method": "GET",
                "url": "{{tenantDcqlApiBaseUrl}}/queries/eupid-and-mdl/verifiers",
                "description": "Reverse-lists verifier bindings for the combined query, proving the query-to-verifier link is visible from the query resource as well.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('combined query verifier bindings listed', () => pm.response.to.have.status(200));",
                      "const bindings = pm.response.json();",
                      "const binding = bindings.find((b) => b.verifierId === pm.variables.get('verifierId') && b.queryId === 'eupid-and-mdl');",
                      "pm.test('combined query is bound to the tenant verifier', () => {",
                      "  pm.expect(binding, 'combined query verifier binding').to.be.an('object');",
                      "  pm.expect(binding.pinnedVersion).to.eql(1);",
                      "  pm.expect(binding.enabled).to.eql(true);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/dcql/v1/queries/eupid-and-mdl/verifiers",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "[\n  {\n    \"id\": \"00000000-0000-4000-8000-000000000000\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"verifierId\": \"00000000-0000-4000-8000-000000000000\",\n    \"queryId\": \"eupid-and-mdl\",\n    \"pinnedVersion\": 1,\n    \"enabled\": true,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\"\n  },\n  {\n    \"id\": \"00000000-0000-4000-8000-000000000000\",\n    \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"verifierId\": \"acme\",\n    \"queryId\": \"eupid-and-mdl\",\n    \"pinnedVersion\": 1,\n    \"enabled\": true,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\"\n  }\n]",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "22 Verification",
          "description": "Creates, polls, and cancels a verification session for the stored combined DCQL query. The collection covers verifier session lifecycle without simulating a full wallet presentation.\n\nDocumentation: https://docs.sphereon.com/edk/admin-console/guides/verify-credentials",
          "item": [
            {
              "name": "01 Create verification request",
              "request": {
                "method": "POST",
                "url": "{{tenantVerifierBackendBaseUrl}}/auth/requests",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"query_id\": \"eupid-and-mdl\",\n  \"verifier_id\": \"{{verifierId}}\",\n  \"client_id\": \"decentralized_identifier:{{did}}\",\n  \"correlation_id\": \"e2e-verify-001\"\n}"
                },
                "description": "Creates a verifier session for the combined DCQL query. The response includes the authorization request URI a wallet would open."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('verification session created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const j = pm.response.json();",
                      "pm.expect(j.request_uri, 'wallet authorization request URI').to.be.a('string').and.not.empty;",
                      "const requestObjectMatch = j.request_uri.match(/[?&]request_uri=([^&]+)/);",
                      "pm.expect(requestObjectMatch, 'authorization request contains request_uri').to.not.eql(null);",
                      "pm.collectionVariables.set('requestObjectUri', decodeURIComponent(requestObjectMatch[1]));",
                      "pm.collectionVariables.set('verifyCorrelationId', j.correlation_id || 'e2e-verify-001');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/oid4vp/backend/auth/requests",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"query_id\": \"eupid-and-mdl\",\n  \"verifier_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"client_id\": \"decentralized_identifier:did:web:acme.example.com\",\n  \"correlation_id\": \"e2e-verify-001\"\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"correlation_id\": \"e2e-verify-001\",\n  \"query_id\": \"eupid-and-mdl\",\n  \"request_uri\": \"openid4vp://?client_id=decentralized_identifier%3Adid%3Aweb%3Aacme.example.com&request_uri=https%3A%2F%2Facme.example.com%2Foid4vp%2Facme%2Foid4vp%2Frequest-uri%2Fe2e-verify-001\",\n  \"status_uri\": \"https://acme.example.com/oid4vp/acme/backend/auth/requests/e2e-verify-001\",\n  \"verification_binding\": {\n    \"instanceId\": \"acme\",\n    \"templateId\": null,\n    \"templateRevision\": null,\n    \"queryId\": \"eupid-and-mdl\",\n    \"queryVersion\": 1,\n    \"createdAtEpochMillis\": 1767225600000,\n    \"expiresAtEpochMillis\": 1798761600000\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "01a Fetch signed verification request object",
              "request": {
                "auth": {
                  "type": "noauth"
                },
                "method": "GET",
                "url": "{{requestObjectUri}}",
                "header": [
                  {
                    "key": "Accept",
                    "value": "application/oauth-authz-req+jwt, application/jwt"
                  }
                ],
                "description": "Fetches the signed verifier request object and proves its issuer and signing key both identify the activation-created tenant DID."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('signed verification request object returned', () => pm.response.to.have.status(200));",
                      "const compact = pm.response.text().trim();",
                      "const parts = compact.split('.');",
                      "pm.expect(parts, 'compact request-object JWT').to.have.length(3);",
                      "const decodeJwtPart = (index) => {",
                      "  const normalized = parts[index].replace(/-/g, '+').replace(/_/g, '/');",
                      "  const padded = normalized + '='.repeat((4 - (normalized.length % 4)) % 4);",
                      "  return JSON.parse(atob(padded));",
                      "};",
                      "const header = decodeJwtPart(0);",
                      "const payload = decodeJwtPart(1);",
                      "pm.test('verifier request object issuer and kid use the same DID', () => {",
                      "  pm.expect(payload.iss).to.eql(pm.collectionVariables.get('did'));",
                      "  pm.expect(header.kid).to.eql(pm.collectionVariables.get('verifierDidVerificationMethodId'));",
                      "  pm.expect(header.kid.startsWith(payload.iss + '#')).to.eql(true);",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/oid4vp/acme/oid4vp/request-uri/e2e-verify-001",
                    "header": [
                      {
                        "key": "Accept",
                        "value": "application/oauth-authz-req+jwt, application/jwt"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/oauth-authz-req+jwt"
                    }
                  ],
                  "body": "{\n  \"_raw\": \"eyJ0eXAiOiJvYXV0aC1hdXRoei1yZXErand0IiwiYWxnIjoiRVMyNTYiLCJraWQiOiJkaWQ6d2ViOmFjbWUuZXhhbXBsZS5jb20jdmVyaWZpZXItcmVxdWVzdC1vYmplY3QtYWNtZSJ9.eyJpc3MiOiJkaWQ6d2ViOmFjbWUuZXhhbXBsZS5jb20iLCJhdWQiOiJodHRwczovL3NlbGYtaXNzdWVkLm1lL3YyIiwiaWF0IjoxNzY3MjI1NjAwLCJleHAiOjE3OTg3NjE2MDAsImp0aSI6IjxqdGk-IiwiY2xpZW50X2lkIjoiZGVjZW50cmFsaXplZF9pZGVudGlmaWVyOmRpZDp3ZWI6YWNtZS5leGFtcGxlLmNvbSIsInJlc3BvbnNlX3R5cGUiOiJ2cF90b2tlbiIsInN0YXRlIjoiZTJlLXZlcmlmeS0wMDEiLCJub25jZSI6Ijxub25jZT4iLCJyZXNwb25zZV9tb2RlIjoiZGlyZWN0X3Bvc3QiLCJkY3FsX3F1ZXJ5Ijp7ImNyZWRlbnRpYWxzIjpbeyJpZCI6ImV1cGlkIiwiZm9ybWF0IjoiZGMrc2Qtand0IiwibWV0YSI6eyJ2Y3RfdmFsdWVzIjpbImh0dHBzOi8vYWNtZS5leGFtcGxlLmNvbS9wdWJsaWMvc2NoZW1hL3ZjdC9FdVBpZCJdfSwiY2xhaW1zIjpbeyJwYXRoIjpbImZhbWlseV9uYW1lIl19LHsicGF0aCI6WyJnaXZlbl9uYW1lIl19XX0seyJpZCI6Im1kbCIsImZvcm1hdCI6Im1zb19tZG9jIiwibWV0YSI6eyJkb2N0eXBlX3ZhbHVlIjoib3JnLmlzby4xODAxMy41LjEubURMIn0sImNsYWltcyI6W3sicGF0aCI6WyJvcmcuaXNvLjE4MDEzLjUuMSIsImZhbWlseV9uYW1lIl19LHsicGF0aCI6WyJvcmcuaXNvLjE4MDEzLjUuMSIsImdpdmVuX25hbWUiXX1dfV19LCJjbGllbnRfbWV0YWRhdGEiOnsidnBfZm9ybWF0c19zdXBwb3J0ZWQiOnsiZGMrc2Qtand0Ijp7InNkLWp3dF9hbGdfdmFsdWVzIjpbIkVTMjU2Il0sImtiLWp3dF9hbGdfdmFsdWVzIjpbIkVTMjU2Il19LCJtc29fbWRvYyI6eyJpc3N1ZXJhdXRoX2FsZ192YWx1ZXMiOlstN10sImRldmljZWF1dGhfYWxnX3ZhbHVlcyI6Wy03XX0sImp3dF92Y19qc29uIjp7ImFsZ192YWx1ZXMiOlsiRVMyNTYiXX0sImp3dF92Y19qc29uLWxkIjp7ImFsZ192YWx1ZXMiOlsiRVMyNTYiXX19fSwicmVzcG9uc2VfdXJpIjoiaHR0cHM6Ly9hY21lLmV4YW1wbGUuY29tL29pZDR2cC9hY21lL2F1dGgvcmVzcG9uc2UifQ.SIGNATURE-REDACTED\",\n  \"_decoded\": {\n    \"header\": {\n      \"typ\": \"oauth-authz-req+jwt\",\n      \"alg\": \"ES256\",\n      \"kid\": \"did:web:acme.example.com#verifier-request-object-acme\"\n    },\n    \"payload\": {\n      \"iss\": \"did:web:acme.example.com\",\n      \"aud\": \"https://self-issued.me/v2\",\n      \"iat\": 1767225600,\n      \"exp\": 1798761600,\n      \"jti\": \"<jti>\",\n      \"client_id\": \"decentralized_identifier:did:web:acme.example.com\",\n      \"response_type\": \"vp_token\",\n      \"state\": \"e2e-verify-001\",\n      \"nonce\": \"<nonce>\",\n      \"response_mode\": \"direct_post\",\n      \"dcql_query\": {\n        \"credentials\": [\n          {\n            \"id\": \"eupid\",\n            \"format\": \"dc+sd-jwt\",\n            \"meta\": {\n              \"vct_values\": [\n                \"https://acme.example.com/public/schema/vct/EuPid\"\n              ]\n            },\n            \"claims\": [\n              {\n                \"path\": [\n                  \"family_name\"\n                ]\n              },\n              {\n                \"path\": [\n                  \"given_name\"\n                ]\n              }\n            ]\n          },\n          {\n            \"id\": \"mdl\",\n            \"format\": \"mso_mdoc\",\n            \"meta\": {\n              \"doctype_value\": \"org.iso.18013.5.1.mDL\"\n            },\n            \"claims\": [\n              {\n                \"path\": [\n                  \"org.iso.18013.5.1\",\n                  \"family_name\"\n                ]\n              },\n              {\n                \"path\": [\n                  \"org.iso.18013.5.1\",\n                  \"given_name\"\n                ]\n              }\n            ]\n          }\n        ]\n      },\n      \"client_metadata\": {\n        \"vp_formats_supported\": {\n          \"dc+sd-jwt\": {\n            \"sd-jwt_alg_values\": [\n              \"ES256\"\n            ],\n            \"kb-jwt_alg_values\": [\n              \"ES256\"\n            ]\n          },\n          \"mso_mdoc\": {\n            \"issuerauth_alg_values\": [\n              -7\n            ],\n            \"deviceauth_alg_values\": [\n              -7\n            ]\n          },\n          \"jwt_vc_json\": {\n            \"alg_values\": [\n              \"ES256\"\n            ]\n          },\n          \"jwt_vc_json-ld\": {\n            \"alg_values\": [\n              \"ES256\"\n            ]\n          }\n        }\n      },\n      \"response_uri\": \"https://acme.example.com/oid4vp/acme/auth/response\"\n    }\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Poll verification status",
              "request": {
                "method": "GET",
                "url": "{{tenantVerifierBackendBaseUrl}}/auth/requests/{{verifyCorrelationId}}",
                "description": "Polls the session. With no wallet attached, the session stays in authorization_request_created; after a wallet presents, it ends in authorization_response_verified with the disclosed claims.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('status returned', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/oid4vp/backend/auth/requests/e2e-verify-001",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"correlation_id\": \"e2e-verify-001\",\n  \"query_id\": \"eupid-and-mdl\",\n  \"status\": \"authorization_request_retrieved\",\n  \"last_updated\": 1767225600000,\n  \"session_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"verifier_id\": \"00000000-0000-4000-8000-000000000000\",\n  \"created_at\": 1767225600000,\n  \"expires_at\": 1798761600000,\n  \"verification_binding\": {\n    \"instanceId\": \"acme\",\n    \"templateId\": null,\n    \"templateRevision\": null,\n    \"queryId\": \"eupid-and-mdl\",\n    \"queryVersion\": 1,\n    \"createdAtEpochMillis\": 1767225600000,\n    \"expiresAtEpochMillis\": 1798761600000\n  },\n  \"error\": null,\n  \"verified_data\": null\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "23 Trust Domains and Trust Lists",
          "description": "Trust Domains V2: domains and anchors as evidence, admission classes as what that evidence may answer, attachments as who uses it, eligibility grants as the governance cap, and the ISO 18013-5 Annex C VICAL path. Runs after tenant onboarding because it starts from the seeded issuer trust domain. The trust list and LoTE source requests show how a list you publish yourself, in ETSI TS 119 612 or TS 119 602 form, is registered as a source the domain consumes.\n\nDocumentation: https://docs.sphereon.com/edk/admin-console/guides/trust-domains",
          "item": [
            {
              "name": "01 List trust domains",
              "request": {
                "method": "GET",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains",
                "description": "Reads the tenant trust-domain inventory. Onboarding seeds one issuer trust domain, so an empty list here means the sample-data seeder did not run or failed.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('trust domains listed', () => pm.response.to.have.status(200));",
                      "const items = pm.response.json().items || [];",
                      "pm.test('the onboarding-seeded issuer trust domain exists', () => pm.expect(items.length).to.be.above(0));",
                      "const seeded = items.find((d) => /issuer trust/i.test(d.displayName)) || items[0];",
                      "pm.collectionVariables.set('trustDomainId', seeded.domainId);",
                      "pm.collectionVariables.set('trustDomainVersion', String(seeded.version));",
                      "pm.test('seeded domain is active', () => pm.expect(seeded.status).to.eql('ACTIVE'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"items\": [\n    {\n      \"domainId\": \"trust-domain-issuer-00000000-0000-4000-8000-000000000000\",\n      \"displayName\": \"Acme Corporation issuer trust\",\n      \"description\": \"Issuer material provisioned for Acme Corporation\",\n      \"status\": \"ACTIVE\",\n      \"version\": 1,\n      \"createdAt\": \"2026-01-01T00:00:00Z\",\n      \"updatedAt\": \"2026-01-01T00:00:00Z\"\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 List anchors of the seeded domain",
              "request": {
                "method": "GET",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{trustDomainId}}/anchors",
                "description": "Each entry pairs the stored anchor with an enforcement-safe identifier summary. The seeder creates one anchor per evidence mechanism from the issuer key material.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('anchors listed', () => pm.response.to.have.status(200));",
                      "const items = pm.response.json().items || [];",
                      "pm.test('seeded anchors present', () => pm.expect(items.length).to.be.above(0));",
                      "const mechanisms = items.map((i) => i.anchor.evidenceMechanism);",
                      "pm.test('issuer DID anchor seeded', () => pm.expect(mechanisms).to.include('DID'));",
                      "const did = items.find((i) => i.anchor.evidenceMechanism === 'DID');",
                      "pm.collectionVariables.set('trustAnchorId', did.anchor.anchorId);",
                      "pm.collectionVariables.set('trustAnchorVersion', String(did.anchor.version));",
                      "pm.collectionVariables.set('trustIdentityIdentifierId', did.anchor.identityIdentifierId);",
                      "pm.test('seeded anchors are tenant-produced material', () => pm.expect(did.anchor.origin).to.eql('TENANT_PUBLIC'));",
                      "pm.test('issuer X.509 anchor seeded', () => pm.expect(mechanisms).to.include('X509'));",
                      "const x509 = items.find((i) => i.anchor.evidenceMechanism === 'X509');",
                      "pm.collectionVariables.set('trustX509IdentityIdentifierId', x509.anchor.identityIdentifierId);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/trust-domain-issuer-00000000-0000-4000-8000-000000000000/anchors",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"items\": [\n    {\n      \"anchor\": {\n        \"anchorId\": \"trust-anchor-issuer-00000000-0000-4000-8000-000000000000-issuer-did\",\n        \"domainId\": \"trust-domain-issuer-00000000-0000-4000-8000-000000000000\",\n        \"identityIdentifierId\": \"00000000-0000-4000-8000-000000000000\",\n        \"evidenceMechanism\": \"DID\",\n        \"origin\": \"TENANT_PUBLIC\",\n        \"status\": \"ACTIVE\",\n        \"metadata\": {\n          \"source\": \"tenant-onboarding\",\n          \"productRole\": \"issuer-did\"\n        },\n        \"version\": 2,\n        \"createdAt\": \"2026-01-01T00:00:00Z\",\n        \"updatedAt\": \"2026-01-01T00:00:00Z\"\n      },\n      \"identifier\": {\n        \"anchorId\": \"trust-anchor-issuer-00000000-0000-4000-8000-000000000000-issuer-did\",\n        \"identityIdentifierId\": \"00000000-0000-4000-8000-000000000000\",\n        \"resolved\": false\n      }\n    },\n    {\n      \"anchor\": {\n        \"anchorId\": \"trust-anchor-issuer-00000000-0000-4000-8000-000000000000-issuer-jwk\",\n        \"domainId\": \"trust-domain-issuer-00000000-0000-4000-8000-000000000000\",\n        \"identityIdentifierId\": \"00000000-0000-4000-8000-000000000000\",\n        \"evidenceMechanism\": \"JWK\",\n        \"origin\": \"TENANT_PUBLIC\",\n        \"status\": \"ACTIVE\",\n        \"metadata\": {\n          \"source\": \"tenant-onboarding\",\n          \"productRole\": \"issuer-metadata-signing\"\n        },\n        \"version\": 2,\n        \"createdAt\": \"2026-01-01T00:00:00Z\",\n        \"updatedAt\": \"2026-01-01T00:00:00Z\"\n      },\n      \"identifier\": {\n        \"anchorId\": \"trust-anchor-issuer-00000000-0000-4000-8000-000000000000-issuer-jwk\",\n        \"identityIdentifierId\": \"00000000-0000-4000-8000-000000000000\",\n        \"resolved\": false\n      }\n    },\n    {\n      \"anchor\": {\n        \"anchorId\": \"trust-anchor-issuer-00000000-0000-4000-8000-000000000000-issuer-x509\",\n        \"domainId\": \"trust-domain-issuer-00000000-0000-4000-8000-000000000000\",\n        \"identityIdentifierId\": \"00000000-0000-4000-8000-000000000000\",\n        \"evidenceMechanism\": \"X509\",\n        \"origin\": \"TENANT_PUBLIC\",\n        \"status\": \"ACTIVE\",\n        \"metadata\": {\n          \"source\": \"tenant-onboarding\",\n          \"productRole\": \"issuer-certificate\"\n        },\n        \"version\": 2,\n        \"createdAt\": \"2026-01-01T00:00:00Z\",\n        \"updatedAt\": \"2026-01-01T00:00:00Z\"\n      },\n      \"identifier\": {\n        \"anchorId\": \"trust-anchor-issuer-00000000-0000-4000-8000-000000000000-issuer-x509\",\n        \"identityIdentifierId\": \"00000000-0000-4000-8000-000000000000\",\n        \"resolved\": false\n      }\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 List admissions of the issuer anchor",
              "request": {
                "method": "GET",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{trustDomainId}}/anchors/{{trustAnchorId}}/admissions",
                "description": "Membership in a domain is not admission. An anchor answers a usage only when it holds that usage admission class, so an empty list here would mean the anchor is inert.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('admissions listed', () => pm.response.to.have.status(200));",
                      "const items = pm.response.json().items || [];",
                      "pm.test('issuer anchor is admitted as CREDENTIAL_ISSUER', () =>",
                      "  pm.expect(items.map((a) => a.admissionClass)).to.include('CREDENTIAL_ISSUER'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/trust-domain-issuer-00000000-0000-4000-8000-000000000000/anchors/trust-anchor-issuer-00000000-0000-4000-8000-000000000000-issuer-did/admissions",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"items\": [\n    {\n      \"anchorId\": \"trust-anchor-issuer-00000000-0000-4000-8000-000000000000-issuer-did\",\n      \"admissionClass\": \"CREDENTIAL_ISSUER\"\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Read the tenant issuer-trust attachment",
              "request": {
                "method": "GET",
                "url": "{{tenantTrustDomainApiBaseUrl}}/attachments/TENANT/{{tenantId}}/CREDENTIAL_ISSUER_TRUST",
                "description": "The tenant fallback is an ordinary attachment. A tenant with none fails closed on every credential-issuer decision, which is the state a brand-new tenant starts in.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('tenant attachment returned', () => pm.response.to.have.status(200));",
                      "const body = pm.response.json();",
                      "pm.test('tenant issuer trust is fail closed', () => pm.expect(body.attachment.policy.mode).to.eql('FAIL_CLOSED'));",
                      "pm.test('tenant attachment selects the seeded domain', () =>",
                      "  pm.expect(body.domains.map((d) => d.domainId)).to.include(pm.collectionVariables.get('trustDomainId')));",
                      "pm.test('domain ordinals are contiguous from zero', () =>",
                      "  pm.expect(body.domains.map((d) => d.order !== undefined ? d.order : d.ordinal)).to.eql(body.domains.map((_, i) => i)));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/trust-domain/v1/attachments/TENANT/00000000-0000-4000-8000-000000000000/CREDENTIAL_ISSUER_TRUST",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"attachment\": {\n    \"attachmentId\": \"trust-attachment-issuer-00000000-0000-4000-8000-000000000000-tenant\",\n    \"consumerKind\": \"TENANT\",\n    \"consumerId\": \"00000000-0000-4000-8000-000000000000\",\n    \"usage\": \"CREDENTIAL_ISSUER_TRUST\",\n    \"policy\": {\n      \"type\": \"IDENTITY_ADMISSION\",\n      \"mode\": \"FAIL_CLOSED\",\n      \"walletEvidencePolicy\": \"NONE\"\n    },\n    \"version\": 1,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\"\n  },\n  \"domains\": [\n    {\n      \"attachmentId\": \"trust-attachment-issuer-00000000-0000-4000-8000-000000000000-tenant\",\n      \"domainId\": \"trust-domain-issuer-00000000-0000-4000-8000-000000000000\",\n      \"ordinal\": 0\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Read the verifier eligibility grant",
              "request": {
                "method": "GET",
                "url": "{{tenantTrustDomainApiBaseUrl}}/eligibility/OID4VP_VERIFIER/CREDENTIAL_ISSUER_TRUST",
                "description": "The grant caps which domains a verifier may select. It is governance, not selection, and is checked only against non-tenant attachments.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('eligibility grant returned', () => pm.response.to.have.status(200));",
                      "const items = pm.response.json().items || [];",
                      "const eligible = items.flatMap((g) => g.eligibleDomainIds || []);",
                      "pm.test('seeded domain is eligible for verifiers', () =>",
                      "  pm.expect(eligible).to.include(pm.collectionVariables.get('trustDomainId')));",
                      "pm.collectionVariables.set('trustEligibilityVersion', String(items[0] ? items[0].version : 1));",
                      "pm.collectionVariables.set('trustEligibilityGrantId', items[0] ? items[0].grantId : 'grant-verifier-issuer-trust');",
                      "pm.collectionVariables.set('trustEligibleDomainIds', JSON.stringify(eligible));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/trust-domain/v1/eligibility/OID4VP_VERIFIER/CREDENTIAL_ISSUER_TRUST",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"items\": [\n    {\n      \"grantId\": \"trust-eligibility-issuer-00000000-0000-4000-8000-000000000000-verifier\",\n      \"subjectConsumerKind\": \"OID4VP_VERIFIER\",\n      \"usage\": \"CREDENTIAL_ISSUER_TRUST\",\n      \"eligibleDomainIds\": [\n        \"trust-domain-issuer-00000000-0000-4000-8000-000000000000\"\n      ],\n      \"version\": 1\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 List consumers of the seeded domain",
              "request": {
                "method": "GET",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{trustDomainId}}/consumers",
                "description": "Reverse lookup used before disabling or deleting a domain. There is no pointer stored on the domain; this is a query over attachments.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const detail = () => pm.response.code + ' ' + pm.response.text();",
                      "pm.test('consumers listed', () => pm.expect(pm.response.code, detail()).to.eql(200));",
                      "const items = pm.response.json().items || [];",
                      "pm.test('the tenant consumes the seeded domain', () =>",
                      "  pm.expect(items.map((c) => c.consumerKind)).to.include('TENANT'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/trust-domain-issuer-00000000-0000-4000-8000-000000000000/consumers",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"items\": [\n    {\n      \"consumerKind\": \"OID4VP_VERIFIER\",\n      \"consumerId\": \"acme\",\n      \"usage\": \"CREDENTIAL_ISSUER_TRUST\",\n      \"attachmentId\": \"trust-attachment-issuer-00000000-0000-4000-8000-000000000000-verifier\"\n    },\n    {\n      \"consumerKind\": \"TENANT\",\n      \"consumerId\": \"00000000-0000-4000-8000-000000000000\",\n      \"usage\": \"CREDENTIAL_ISSUER_TRUST\",\n      \"attachmentId\": \"trust-attachment-issuer-00000000-0000-4000-8000-000000000000-tenant\"\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "07 Create a second trust domain",
              "request": {
                "method": "POST",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains",
                "description": "New domains start as DRAFT. A draft domain can be attached but never resolves, because resolution requires ACTIVE.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"displayName\": \"Postman mdoc VICAL domain\",\n  \"description\": \"Created by the customer release gate to exercise attachments, eligibility and mdoc VICAL.\"\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('domain created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                      "const d = pm.response.json();",
                      "pm.collectionVariables.set('vicalDomainId', d.domainId);",
                      "pm.collectionVariables.set('vicalDomainVersion', String(d.version));",
                      "pm.test('new domains start as DRAFT', () => pm.expect(d.status).to.eql('DRAFT'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"displayName\": \"Postman mdoc VICAL domain\",\n  \"description\": \"Created by the customer release gate to exercise attachments, eligibility and mdoc VICAL.\"\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"displayName\": \"Postman mdoc VICAL domain\",\n  \"description\": \"Created by the customer release gate to exercise attachments, eligibility and mdoc VICAL.\",\n  \"status\": \"DRAFT\",\n  \"version\": 1,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "08 Activate the second trust domain",
              "request": {
                "method": "PUT",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{vicalDomainId}}",
                "description": "Mutations are optimistically concurrent: the current version goes in If-Match and a stale value returns 412.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "If-Match",
                    "value": "\"{{vicalDomainVersion}}\""
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"domainId\": \"{{vicalDomainId}}\",\n  \"displayName\": \"Postman mdoc VICAL domain\",\n  \"status\": \"ACTIVE\",\n  \"version\": {{vicalDomainVersion}}\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('domain activated', () => pm.response.to.have.status(200));",
                      "const d = pm.response.json();",
                      "pm.test('status is ACTIVE', () => pm.expect(d.status).to.eql('ACTIVE'));",
                      "pm.collectionVariables.set('vicalDomainVersion', String(d.version));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"displayName\": \"Postman mdoc VICAL domain\",\n  \"status\": \"ACTIVE\",\n  \"version\": 1\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"displayName\": \"Postman mdoc VICAL domain\",\n  \"status\": \"ACTIVE\",\n  \"version\": 2,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "11 Create a VICAL signer anchor",
              "request": {
                "method": "POST",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{vicalDomainId}}/anchors",
                "description": "An anchor references public evidence by identity-identifier id rather than carrying raw material. This reuses the identifier the onboarding seeder already materialized. A VICAL is a COSE_Sign1 over an X.509 chain, so its signer anchor carries X.509 evidence; the seeded issuer certificate identifier stands in for the VICAL provider here.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"domainId\": \"{{vicalDomainId}}\",\n  \"identityIdentifierId\": \"{{trustX509IdentityIdentifierId}}\",\n  \"evidenceMechanism\": \"X509\",\n  \"origin\": \"IMPORTED\",\n  \"status\": \"ACTIVE\",\n  \"metadata\": {\n    \"source\": \"customer-release-gate\",\n    \"productRole\": \"mdoc-vical-signer\"\n  }\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('anchor created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                      "const a = pm.response.json();",
                      "pm.collectionVariables.set('vicalAnchorId', a.anchorId);",
                      "pm.collectionVariables.set('vicalAnchorVersion', String(a.version));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/00000000-0000-4000-8000-000000000000/anchors",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"identityIdentifierId\": \"00000000-0000-4000-8000-000000000000\",\n  \"evidenceMechanism\": \"X509\",\n  \"origin\": \"IMPORTED\",\n  \"status\": \"ACTIVE\",\n  \"metadata\": {\n    \"source\": \"customer-release-gate\",\n    \"productRole\": \"mdoc-vical-signer\"\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"anchorId\": \"00000000-0000-4000-8000-000000000000\",\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"identityIdentifierId\": \"00000000-0000-4000-8000-000000000000\",\n  \"evidenceMechanism\": \"X509\",\n  \"origin\": \"IMPORTED\",\n  \"status\": \"ACTIVE\",\n  \"metadata\": {\n    \"source\": \"customer-release-gate\",\n    \"productRole\": \"mdoc-vical-signer\"\n  },\n  \"version\": 1,\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "13 Admit the anchor as MDOC_VICAL_SIGNER",
              "request": {
                "method": "PUT",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{vicalDomainId}}/anchors/{{vicalAnchorId}}/admissions/MDOC_VICAL_SIGNER",
                "description": "Admission is a separate decision from membership. MDOC_VICAL_SIGNER only lets the anchor verify a VICAL signature; it does not make it a credential issuer.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "If-Match",
                    "value": "\"{{vicalAnchorVersion}}\""
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"anchorId\": \"{{vicalAnchorId}}\",\n  \"admissionClass\": \"MDOC_VICAL_SIGNER\"\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const detail = () => pm.response.code + ' ' + pm.response.text();",
                      "pm.test('admission granted', () => pm.expect(pm.response.code, detail()).to.eql(200));",
                      "pm.test('admission class echoed', () => pm.expect(pm.response.json().admissionClass).to.eql('MDOC_VICAL_SIGNER'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/00000000-0000-4000-8000-000000000000/anchors/00000000-0000-4000-8000-000000000000/admissions/MDOC_VICAL_SIGNER",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"anchorId\": \"00000000-0000-4000-8000-000000000000\",\n  \"admissionClass\": \"MDOC_VICAL_SIGNER\"\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"anchorId\": \"00000000-0000-4000-8000-000000000000\",\n  \"admissionClass\": \"MDOC_VICAL_SIGNER\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "15 Configure the VICAL source",
              "request": {
                "method": "PUT",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{vicalDomainId}}/anchors/{{vicalAnchorId}}/mdoc-vical",
                "description": "The signer anchor now holds MDOC_VICAL_SIGNER, so the same body that was refused in step 12 is accepted.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"url\": \"https://vical.example.com/vical.cbor\",\n  \"signerAnchorIds\": [\n    \"{{vicalAnchorId}}\"\n  ],\n  \"issuerAnchorIds\": [],\n  \"requiredCertificateProfiles\": [\n    \"iso18013-5-iaca\"\n  ],\n  \"enabled\": true\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const detail = () => pm.response.code + ' ' + pm.response.text();",
                      "pm.test('VICAL configured', () => pm.expect(pm.response.code, detail()).to.eql(200));",
                      "const v = pm.response.json();",
                      "pm.test('the source round-trips', () => {",
                      "  pm.expect(v.source.url).to.eql('https://vical.example.com/vical.cbor');",
                      "  pm.expect(v.source.signerAnchorIds).to.include(pm.collectionVariables.get('vicalAnchorId'));",
                      "  pm.expect(v.source.enabled).to.be.true;",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/00000000-0000-4000-8000-000000000000/anchors/00000000-0000-4000-8000-000000000000/mdoc-vical",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"url\": \"https://vical.example.com/vical.cbor\",\n  \"signerAnchorIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"issuerAnchorIds\": [],\n  \"requiredCertificateProfiles\": [\n    \"iso18013-5-iaca\"\n  ],\n  \"enabled\": true\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"anchorId\": \"00000000-0000-4000-8000-000000000000\",\n  \"source\": {\n    \"url\": \"https://vical.example.com/vical.cbor\",\n    \"signerAnchorIds\": [\n      \"00000000-0000-4000-8000-000000000000\"\n    ],\n    \"issuerAnchorIds\": [],\n    \"requiredCertificateProfiles\": [\n      \"iso18013-5-iaca\"\n    ],\n    \"enabled\": true\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "17a Register a published trust list as a trust source",
              "request": {
                "method": "PUT",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{vicalDomainId}}/trust-sources/{{customerTrustListSourceId}}",
                "description": "Registers a trust list you publish yourself (ETSI TS 119 612 structure, signed by your trust-list signing certificate) as a source of the second trust domain. signerAnchorIds names the anchor holding the certificate that signs the list; egressPolicy restricts where the platform may fetch from and how large the artifact may be. If-Match \"*\" registers a source that does not exist yet.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "If-Match",
                    "value": "*",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"url\": \"{{customerTrustListUrl}}\",\n  \"format\": \"application/xml\",\n  \"schemeIdentity\": \"{{customerTrustListSchemeIdentity}}\",\n  \"signerAnchorIds\": [\n    \"{{vicalAnchorId}}\"\n  ],\n  \"egressPolicy\": {\n    \"allowedHosts\": [\n      \"{{customerTrustListHost}}\"\n    ],\n    \"maxArtifactBytes\": 5242880\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const url = String(pm.variables.get('customerTrustListUrl') || '');",
                      "pm.collectionVariables.set('customerTrustListHost', url.replace(/^https:\\/\\//, '').split('/')[0]);"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('trust list source registered', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200,201]));",
                      "const source = pm.response.json();",
                      "pm.test('the source belongs to the domain and is a custom TS 119 612 list', () => {",
                      "  pm.expect(source.sourceId, 'source id').to.eql(pm.variables.get('customerTrustListSourceId'));",
                      "  pm.expect(source.domainId, 'domain id').to.eql(pm.collectionVariables.get('vicalDomainId'));",
                      "  pm.expect(source.kind, 'kind').to.eql('ETSI_119612_CUSTOM_LOTL');",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/00000000-0000-4000-8000-000000000000/trust-sources/customer-trust-list",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"url\": \"https://trust.example.com/trust-list.xml\",\n  \"format\": \"application/xml\",\n  \"schemeIdentity\": \"https://trust.example.com/trust-list-scheme\",\n  \"signerAnchorIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"egressPolicy\": {\n    \"allowedHosts\": [\n      \"trust.example.com\"\n    ],\n    \"maxArtifactBytes\": 5242880\n  }\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"sourceId\": \"customer-trust-list\",\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"kind\": \"ETSI_119612_CUSTOM_LOTL\",\n  \"revision\": 1,\n  \"state\": \"DRAFT\",\n  \"url\": \"https://trust.example.com/trust-list.xml\",\n  \"format\": \"application/xml\",\n  \"schemeIdentity\": \"https://trust.example.com/trust-list-scheme\",\n  \"bootstrap\": {\n    \"kind\": \"EXPLICIT_SIGNER_ANCHORS\",\n    \"identity\": \"CUSTOM_DOMAIN_SIGNER_ANCHORS\"\n  },\n  \"signerAnchorIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"egressPolicy\": {\n    \"allowedHosts\": [\n      \"trust.example.com\"\n    ],\n    \"maxArtifactBytes\": 5242880\n  },\n  \"managedBy\": \"edk-walkthrough-tenant-service\",\n  \"managedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "17b Read the trust list source",
              "request": {
                "method": "GET",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{vicalDomainId}}/trust-sources/{{customerTrustListSourceId}}",
                "description": "Reads the registered source. activeRevision stays empty until a fetched revision has been validated and activated.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('trust list source read', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200]));",
                      "const source = pm.response.json();",
                      "pm.test('the source reads back as registered', () => {",
                      "  pm.expect(source.sourceId, 'source id').to.eql(pm.variables.get('customerTrustListSourceId'));",
                      "  pm.expect(source.enabled, 'enabled').to.be.a('boolean');",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/00000000-0000-4000-8000-000000000000/trust-sources/customer-trust-list",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"sourceId\": \"customer-trust-list\",\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"kind\": \"ETSI_119612_CUSTOM_LOTL\",\n  \"enabled\": true,\n  \"managedBy\": \"edk-walkthrough-tenant-service\",\n  \"managedAt\": \"2026-01-01T00:00:00Z\",\n  \"createdAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "17c Register a list of trusted entities (LoTE) source",
              "request": {
                "method": "PUT",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{vicalDomainId}}/lote-sources/{{customerLoteSourceId}}",
                "description": "Registers a published list of trusted entities (TS 119 602 LoTE) as a remote source of the domain. The call creates the first candidate revision of the source and returns that revision; the source itself, with the etag later mutations must present, is read in the next request.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  },
                  {
                    "key": "If-Match",
                    "value": "*",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"sourceKind\": \"REMOTE\",\n  \"profile\": \"PUB_EAA_PROVIDER\",\n  \"url\": \"{{customerLoteUrl}}\",\n  \"verificationTrustAnchorIds\": [\n    \"{{vicalAnchorId}}\"\n  ],\n  \"allowedHosts\": [\n    \"{{customerLoteHost}}\"\n  ],\n  \"maxArtifactBytes\": 5242880,\n  \"enabled\": true\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "prerequest",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "const url = String(pm.variables.get('customerLoteUrl') || '');",
                      "pm.collectionVariables.set('customerLoteHost', url.replace(/^https:\\/\\//, '').split('/')[0]);"
                    ]
                  }
                },
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('LoTE source registered', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200,201]));",
                      "const revision = pm.response.json();",
                      "pm.test('the registration returns the first candidate revision of the source', () => {",
                      "  pm.expect(revision.sourceId, 'source id').to.eql(pm.variables.get('customerLoteSourceId'));",
                      "  pm.expect(revision.domainId, 'domain id').to.eql(pm.collectionVariables.get('vicalDomainId'));",
                      "  pm.expect(revision.profile, 'profile').to.eql('PUB_EAA_PROVIDER');",
                      "  pm.expect(revision.revision, 'revision number').to.eql(1);",
                      "  pm.expect(revision.etag, 'revision etag').to.be.a('string').and.not.empty;",
                      "});"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/00000000-0000-4000-8000-000000000000/lote-sources/customer-lote",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"sourceKind\": \"REMOTE\",\n  \"profile\": \"PUB_EAA_PROVIDER\",\n  \"url\": \"https://trust.example.com/lote.jws\",\n  \"verificationTrustAnchorIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"allowedHosts\": [\n    \"trust.example.com\"\n  ],\n  \"maxArtifactBytes\": 5242880,\n  \"enabled\": true\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"sourceId\": \"customer-lote\",\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"revision\": 1,\n  \"profile\": \"PUB_EAA_PROVIDER\",\n  \"url\": \"https://trust.example.com/lote.jws\",\n  \"verificationTrustAnchorIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"allowedHosts\": [\n    \"trust.example.com\"\n  ],\n  \"maxArtifactBytes\": 5242880,\n  \"state\": \"CANDIDATE\",\n  \"etag\": \"\\\"remote-lote-revision-1-candidate-188040643\\\"\",\n  \"managedBy\": \"edk-walkthrough-tenant-service\",\n  \"managedAt\": \"2026-01-01T00:00:00Z\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "17d Read the LoTE source",
              "request": {
                "method": "GET",
                "url": "{{tenantTrustDomainApiBaseUrl}}/domains/{{vicalDomainId}}/lote-sources/{{customerLoteSourceId}}",
                "description": "Reads the LoTE source. Its etag is the If-Match value for the next change to the source (enable, disable, replace); revisions carry their own etags.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('LoTE source read', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200]));",
                      "const source = pm.response.json();",
                      "pm.test('the source carries the registered profile and an etag for the next mutation', () => {",
                      "  pm.expect(source.sourceId, 'source id').to.eql(pm.variables.get('customerLoteSourceId'));",
                      "  pm.expect(source.profile, 'profile').to.eql('PUB_EAA_PROVIDER');",
                      "  pm.expect(source.etag, 'source etag').to.be.a('string').and.not.empty;",
                      "});",
                      "pm.collectionVariables.set('customerLoteEtag', source.etag);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/trust-domain/v1/domains/00000000-0000-4000-8000-000000000000/lote-sources/customer-lote",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"sourceId\": \"customer-lote\",\n  \"domainId\": \"00000000-0000-4000-8000-000000000000\",\n  \"profile\": \"PUB_EAA_PROVIDER\",\n  \"enabled\": true,\n  \"managedBy\": \"edk-walkthrough-tenant-service\",\n  \"managedAt\": \"2026-01-01T00:00:00Z\",\n  \"etag\": \"\\\"remote-lote-source-1-true-0\\\"\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "24 KMS Runtime API",
          "description": "The runtime KMS surface a tenant integrates against: discover providers, then generate, read, use and remove a key by provider id and alias. Keys are addressed by the alias the tenant chose, never by a server-issued key id, so the same request works across deployments. Requests run under the tenant service token (folder 04); the tenant KMS API rejects the platform operator token because its audience is the platform, not the tenant KMS.\n\nDocumentation: https://docs.sphereon.com/edk/admin-console/guides/keys-and-did",
          "item": [
            {
              "name": "01 List runtime providers",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/providers",
                "description": "Lists the KMS providers this tenant may address at runtime. The provider id returned here is the one used in every later path segment.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('runtime providers listed', () => pm.response.to.have.status(200));",
                      "const providers = pm.response.json().providers || pm.response.json().data || [];",
                      "pm.expect(providers, 'at least one runtime provider is addressable').to.not.be.empty;",
                      "const preferred = providers.find((p) => (p.id || p.providerId) === \"default\") || providers[0];",
                      "pm.collectionVariables.set(\"kmsRuntimeProviderId\", preferred.id || preferred.providerId);",
                      "// Fixed aliases: the snapshot must be byte-stable across runs, and each run onboards a fresh",
                      "// tenant, so there is nothing to collide with. Requests 07 and 16 remove them again.",
                      "pm.collectionVariables.set(\"kmsRuntimeKeyAlias\", \"customer-runtime-signing-key\");",
                      "pm.collectionVariables.set(\"kmsTenantKeyAlias\", \"customer-tenant-signing-key\");",
                      "pm.collectionVariables.set(\"kmsTenantCertificateAlias\", \"customer-tenant-signing-chain\");"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/kms/v1/providers",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"providers\": [\n    {\n      \"providerId\": \"default\",\n      \"type\": \"SOFTWARE\",\n      \"displayName\": \"Software KMS\",\n      \"ownership\": \"TENANT\",\n      \"sharedFromPlatform\": false,\n      \"isDefault\": true\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "01a Import externally supplied public key",
              "request": {
                "method": "POST",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"keyInfo\": {\n    \"key\": {\n      \"kty\": \"EC\",\n      \"crv\": \"P-256\",\n      \"x\": \"HFL67WWh6PYWKOy1mzt9Y2ANs-CWFIyVtouR-Jx_mAM\",\n      \"y\": \"9f_1x7fwUuEbEwxSNTYE3jQF-zForWpKkEMpiUp1MNI\"\n    },\n    \"alias\": \"customer-evaluation-imported-key\",\n    \"providerId\": \"{{kmsRuntimeProviderId}}\",\n    \"signatureAlgorithm\": \"ECDSA_SHA256\",\n    \"keyVisibility\": \"PUBLIC\",\n    \"keyEncoding\": \"JOSE\",\n    \"keyType\": \"EC\"\n  }\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                },
                "url": "{{tenantKmsApiBaseUrl}}/keys/import"
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('public key imported', () => pm.response.to.have.status(201));",
                      "const body = pm.response.json();",
                      "pm.test('import response identifies the imported key', () => { pm.expect(body.keyInfo, 'keyInfo').to.be.an('object'); pm.expect(body.keyInfo.alias, 'alias').to.eql('customer-evaluation-imported-key'); });"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/kms/v1/keys/import",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"keyInfo\": {\n    \"key\": {\n      \"kty\": \"EC\",\n      \"crv\": \"P-256\",\n      \"x\": \"<public-key-material>\",\n      \"y\": \"<public-key-material>\"\n    },\n    \"alias\": \"customer-evaluation-imported-key\",\n    \"providerId\": \"default\",\n    \"signatureAlgorithm\": \"ECDSA_SHA256\",\n    \"keyVisibility\": \"PUBLIC\",\n    \"keyEncoding\": \"JOSE\",\n    \"keyType\": \"EC\"\n  }\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"keyInfo\": {\n    \"key\": {\n      \"kty\": \"EC\",\n      \"kid\": \"customer-evaluation-imported-key\",\n      \"crv\": \"P-256\",\n      \"x\": \"<public-key-material>\",\n      \"y\": \"<public-key-material>\"\n    },\n    \"alias\": \"customer-evaluation-imported-key\",\n    \"providerId\": \"default\",\n    \"kid\": \"customer-evaluation-imported-key\",\n    \"signatureAlgorithm\": \"ECDSA_SHA256\",\n    \"keyType\": \"EC\",\n    \"keyEncoding\": \"JOSE\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 List keys by providerId",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/providers/{{kmsRuntimeProviderId}}/keys",
                "description": "Lists the keys the tenant holds in one provider.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('keys listed for the provider', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/kms/v1/providers/default/keys",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"keyInfos\": [\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"catalog-public-signing-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    },\n    {\n      \"kid\": \"connector-vault-content-acme\",\n      \"alias\": \"connector-vault-content-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"connector-vault-manifest-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    },\n    {\n      \"kid\": \"customer-evaluation-imported-key\",\n      \"alias\": \"customer-evaluation-imported-key\",\n      \"providerId\": \"default\",\n      \"origin\": \"external\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\",\n      \"keyEncoding\": \"JOSE\"\n    },\n    {\n      \"kid\": \"idfr:bi:00000000-0000-4000-8000-000000000000\",\n      \"signatureAlgorithm\": \"HMAC_SHA256\",\n      \"alias\": \"idfr:bi:00000000-0000-4000-8000-000000000000\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"idfr:enc:00000000-0000-4000-8000-000000000000\",\n      \"alias\": \"idfr:enc:00000000-0000-4000-8000-000000000000\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"invitation-hmac-kek-00000000-0000-4000-8000-000000000000\",\n      \"alias\": \"invitation-hmac-kek-00000000-0000-4000-8000-000000000000\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"issuer-request-decryption-acme\",\n      \"alias\": \"issuer-request-decryption-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"issuer-signing-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    },\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"oauth2-as-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    },\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"oid4vp-verifier-signing-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "03 Generate key with providerId and alias",
              "request": {
                "method": "POST",
                "url": "{{tenantKmsApiBaseUrl}}/providers/{{kmsRuntimeProviderId}}/keys",
                "description": "Generates a signing key under a tenant-chosen alias. The alias is the durable handle for every later call; the response also carries the public JWK.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"alias\": \"{{kmsRuntimeKeyAlias}}\",\n  \"use\": \"sig\",\n  \"alg\": \"ECDSA_SHA256\",\n  \"keyOperations\": [\n    \"sign\"\n  ]\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('key generated', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const body = pm.response.json();",
                      "const pair = body.keyPair || body;",
                      "pm.expect(pair.alias, 'the response echoes the requested alias').to.eql(pm.collectionVariables.get('kmsRuntimeKeyAlias'));",
                      "// The software provider mints a self-signed certificate for a generated signing key.",
                      "// Requests 11 onwards register that chain, so carry it forward when it is present.",
                      "const x5c = pair.jose && pair.jose.publicJwk && pair.jose.publicJwk.x5c;",
                      "pm.collectionVariables.set(\"kmsRuntimeKeyChain\", Array.isArray(x5c) ? JSON.stringify(x5c) : \"\");"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/kms/v1/providers/default/keys",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"alias\": \"customer-runtime-signing-key\",\n  \"use\": \"sig\",\n  \"alg\": \"ECDSA_SHA256\",\n  \"keyOperations\": [\n    \"sign\"\n  ]\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"keyPair\": {\n    \"providerId\": \"default\",\n    \"alias\": \"customer-runtime-signing-key\",\n    \"cose\": {\n      \"publicCoseKey\": {\n        \"kty\": \"2\",\n        \"kid\": \"<key-id>\",\n        \"crv\": 1,\n        \"x\": \"<public-key-material>\",\n        \"y\": \"<public-key-material>\",\n        \"x5chain\": [\n          \"<certificate>\"\n        ]\n      }\n    },\n    \"jose\": {\n      \"publicJwk\": {\n        \"kty\": \"EC\",\n        \"kid\": \"<key-id>\",\n        \"crv\": \"P-256\",\n        \"x\": \"<public-key-material>\",\n        \"y\": \"<public-key-material>\",\n        \"x5c\": [\n          \"<certificate>\"\n        ]\n      }\n    },\n    \"kid\": \"<key-id>\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "04 Get key by providerId and alias",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/providers/{{kmsRuntimeProviderId}}/keys/{{kmsRuntimeKeyAlias}}",
                "description": "Reads one key by alias, including its public JWK.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('key read by alias', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/kms/v1/providers/default/keys/customer-runtime-signing-key",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"keyInfo\": {\n    \"key\": {\n      \"kty\": \"EC\",\n      \"kid\": \"<key-id>\",\n      \"crv\": \"P-256\",\n      \"x\": \"<public-key-material>\",\n      \"y\": \"<public-key-material>\",\n      \"x5c\": [\n        \"<certificate>\"\n      ]\n    },\n    \"alias\": \"customer-runtime-signing-key\",\n    \"providerId\": \"default\",\n    \"kid\": \"<key-id>\",\n    \"signatureAlgorithm\": \"ECDSA_SHA256\",\n    \"x5c\": [\n      \"<certificate>\"\n    ],\n    \"keyType\": \"EC\",\n    \"keyEncoding\": \"JOSE\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "05 Create raw signature with providerId and alias",
              "request": {
                "method": "POST",
                "url": "{{tenantKmsApiBaseUrl}}/signatures/raw/create",
                "description": "Signs an opaque payload with the named key. Raw signing is the primitive behind the higher level JWS and credential signing surfaces.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"keyInfo\": {\n    \"providerId\": \"{{kmsRuntimeProviderId}}\",\n    \"alias\": \"{{kmsRuntimeKeyAlias}}\"\n  },\n  \"input\": \"aGVsbG8=\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('raw signature created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const signature = pm.response.json().signature;",
                      "pm.expect(signature, 'a signature value is returned').to.be.a('string');",
                      "pm.collectionVariables.set(\"kmsRuntimeSignature\", signature);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/kms/v1/signatures/raw/create",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"keyInfo\": {\n    \"providerId\": \"default\",\n    \"alias\": \"customer-runtime-signing-key\"\n  },\n  \"input\": \"aGVsbG8=\"\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"signature\": \"<signature>\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "06 Verify raw signature with providerId and alias",
              "request": {
                "method": "POST",
                "url": "{{tenantKmsApiBaseUrl}}/signatures/raw/verify",
                "description": "Verifies a signature produced by the same key, closing the sign/verify loop.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"keyInfo\": {\n    \"providerId\": \"{{kmsRuntimeProviderId}}\",\n    \"alias\": \"{{kmsRuntimeKeyAlias}}\"\n  },\n  \"input\": \"aGVsbG8=\",\n  \"signature\": \"{{kmsRuntimeSignature}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('raw signature verified', () => pm.response.to.have.status(200));",
                      "pm.expect(pm.response.json().isValid, 'the signature verifies against its own key').to.eql(true);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/kms/v1/signatures/raw/verify",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"keyInfo\": {\n    \"providerId\": \"default\",\n    \"alias\": \"customer-runtime-signing-key\"\n  },\n  \"input\": \"aGVsbG8=\",\n  \"signature\": \"<signature>\"\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"isValid\": true\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "08 List keys across every provider",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/keys",
                "description": "Lists key metadata across every provider the tenant has, rather than one provider at a time. Each entry names its own providerId. Add ?providerId= to narrow it to a single provider.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('tenant-wide key list returned', () => pm.response.to.have.status(200));",
                      "pm.expect(pm.response.json().keyInfos, 'the response uses the keyInfos envelope').to.be.an('array');"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/kms/v1/keys",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"keyInfos\": [\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"catalog-public-signing-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    },\n    {\n      \"kid\": \"connector-vault-content-acme\",\n      \"alias\": \"connector-vault-content-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"connector-vault-manifest-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    },\n    {\n      \"kid\": \"customer-evaluation-imported-key\",\n      \"alias\": \"customer-evaluation-imported-key\",\n      \"providerId\": \"default\",\n      \"origin\": \"external\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\",\n      \"keyEncoding\": \"JOSE\"\n    },\n    {\n      \"kid\": \"idfr:bi:00000000-0000-4000-8000-000000000000\",\n      \"signatureAlgorithm\": \"HMAC_SHA256\",\n      \"alias\": \"idfr:bi:00000000-0000-4000-8000-000000000000\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"idfr:enc:00000000-0000-4000-8000-000000000000\",\n      \"alias\": \"idfr:enc:00000000-0000-4000-8000-000000000000\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"invitation-hmac-kek-00000000-0000-4000-8000-000000000000\",\n      \"alias\": \"invitation-hmac-kek-00000000-0000-4000-8000-000000000000\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"issuer-request-decryption-acme\",\n      \"alias\": \"issuer-request-decryption-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"OCT\"\n    },\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"issuer-signing-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    },\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"oauth2-as-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    },\n    {\n      \"kid\": \"<key-id>\",\n      \"signatureAlgorithm\": \"ECDSA_SHA256\",\n      \"alias\": \"oid4vp-verifier-signing-acme\",\n      \"providerId\": \"default\",\n      \"origin\": \"managed\",\n      \"controlMode\": \"platform_managed\",\n      \"keyType\": \"EC\"\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "09 Generate a key without naming a provider in the path",
              "request": {
                "method": "POST",
                "url": "{{tenantKmsApiBaseUrl}}/keys",
                "description": "Generates a key through the tenant-wide route. providerId travels in the body here instead of the path; omitting it would use the tenant default provider. The response carries the public JWK and, where the provider mints one, its self-signed certificate.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"alias\": \"{{kmsTenantKeyAlias}}\",\n  \"use\": \"sig\",\n  \"alg\": \"ECDSA_SHA256\",\n  \"keyOperations\": [\n    \"sign\"\n  ],\n  \"providerId\": \"{{kmsRuntimeProviderId}}\"\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('key generated through the tenant-wide route', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const pair = pm.response.json().keyPair;",
                      "pm.expect(pair.alias, 'the response echoes the requested alias').to.eql(pm.collectionVariables.get('kmsTenantKeyAlias'));",
                      "const x5c = pair.jose && pair.jose.publicJwk && pair.jose.publicJwk.x5c;",
                      "pm.expect(x5c, 'the provider mints a certificate for a generated signing key').to.be.an('array').that.is.not.empty;",
                      "pm.collectionVariables.set(\"kmsTenantKeyChain\", JSON.stringify(x5c));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/kms/v1/keys",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"alias\": \"customer-tenant-signing-key\",\n  \"use\": \"sig\",\n  \"alg\": \"ECDSA_SHA256\",\n  \"keyOperations\": [\n    \"sign\"\n  ],\n  \"providerId\": \"default\"\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"keyPair\": {\n    \"providerId\": \"default\",\n    \"alias\": \"customer-tenant-signing-key\",\n    \"cose\": {\n      \"publicCoseKey\": {\n        \"kty\": \"2\",\n        \"kid\": \"<key-id>\",\n        \"crv\": 1,\n        \"x\": \"<public-key-material>\",\n        \"y\": \"<public-key-material>\",\n        \"x5chain\": [\n          \"<certificate>\"\n        ]\n      }\n    },\n    \"jose\": {\n      \"publicJwk\": {\n        \"kty\": \"EC\",\n        \"kid\": \"<key-id>\",\n        \"crv\": \"P-256\",\n        \"x\": \"<public-key-material>\",\n        \"y\": \"<public-key-material>\",\n        \"x5c\": [\n          \"<certificate>\"\n        ]\n      }\n    },\n    \"kid\": \"<key-id>\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "10 Read the key by alias",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/keys/{{kmsTenantKeyAlias}}?providerId={{kmsRuntimeProviderId}}",
                "description": "Reads one key by alias or kid across the tenant. providerId is optional and only needed to disambiguate an alias that exists in more than one provider.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('key read by alias', () => pm.response.to.have.status(200));",
                      "pm.expect(pm.response.json().keyInfo.alias).to.eql(pm.collectionVariables.get('kmsTenantKeyAlias'));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/kms/v1/keys/customer-tenant-signing-key?providerId=default",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"keyInfo\": {\n    \"key\": {\n      \"kty\": \"EC\",\n      \"kid\": \"<key-id>\",\n      \"crv\": \"P-256\",\n      \"x\": \"<public-key-material>\",\n      \"y\": \"<public-key-material>\",\n      \"x5c\": [\n        \"<certificate>\"\n      ]\n    },\n    \"alias\": \"customer-tenant-signing-key\",\n    \"providerId\": \"default\",\n    \"kid\": \"<key-id>\",\n    \"signatureAlgorithm\": \"ECDSA_SHA256\",\n    \"x5c\": [\n      \"<certificate>\"\n    ],\n    \"keyType\": \"EC\",\n    \"keyEncoding\": \"JOSE\"\n  }\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "11 Register the key certificate chain",
              "request": {
                "method": "POST",
                "url": "{{tenantKmsApiBaseUrl}}/certificates/register",
                "description": "Registers public certificate material against the key generated above. stored_public_material carries the chain in the request and needs no provider certificate API, so it works against the software provider. The service checks that the leaf public key matches the linked key before storing the reference.",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json",
                    "type": "text"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"providerId\": \"{{kmsRuntimeProviderId}}\",\n  \"alias\": \"{{kmsTenantCertificateAlias}}\",\n  \"kind\": \"key_certificate_chain\",\n  \"source\": \"stored_public_material\",\n  \"linkedKeyAlias\": \"{{kmsTenantKeyAlias}}\",\n  \"certificateChain\": {{kmsTenantKeyChain}}\n}",
                  "options": {
                    "raw": {
                      "language": "json"
                    }
                  }
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('certificate reference registered', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const created = pm.response.json();",
                      "const id = created.id || (created.reference && created.reference.id);",
                      "pm.expect(id, 'the response carries the reference id').to.be.a('string');",
                      "pm.collectionVariables.set(\"kmsTenantCertificateReferenceId\", id);"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "POST",
                    "url": "https://acme.example.com/api/kms/v1/certificates/register",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"providerId\": \"default\",\n  \"alias\": \"customer-tenant-signing-chain\",\n  \"kind\": \"key_certificate_chain\",\n  \"source\": \"stored_public_material\",\n  \"linkedKeyAlias\": \"customer-tenant-signing-key\",\n  \"certificateChain\": [\n    \"<certificate>\"\n  ]\n}"
                    }
                  },
                  "status": "Created",
                  "code": 201,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"alias\": \"customer-tenant-signing-chain\",\n  \"providerId\": \"default\",\n  \"kind\": \"key_certificate_chain\",\n  \"source\": \"stored_public_material\",\n  \"controlMode\": \"externally_managed\",\n  \"origin\": \"external\",\n  \"linkedKeyReferenceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"certificateChain\": [\n    \"<certificate>\"\n  ],\n  \"certificateFingerprint\": \"<certificate-thumbprint>\",\n  \"publicKeyFingerprint\": \"<certificate-thumbprint>\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "12 List certificate references",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/certificate-references",
                "description": "Lists the tenant's own certificate references. It never enumerates a provider's certificate inventory, and returns public metadata only. Filter with ?providerId=, ?kind= or ?source=.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('certificate references listed', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/kms/v1/certificate-references",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"references\": [\n    {\n      \"id\": \"00000000-0000-4000-8000-000000000000\",\n      \"alias\": \"customer-tenant-signing-chain\",\n      \"providerId\": \"default\",\n      \"kind\": \"key_certificate_chain\",\n      \"source\": \"stored_public_material\",\n      \"controlMode\": \"externally_managed\",\n      \"origin\": \"external\",\n      \"linkedKeyReferenceId\": \"00000000-0000-4000-8000-000000000000\",\n      \"linkedKeyAlias\": \"customer-tenant-signing-key\",\n      \"linkedKeyKid\": \"<key-id>\",\n      \"certificateFingerprint\": \"<certificate-thumbprint>\",\n      \"publicKeyFingerprint\": \"<certificate-thumbprint>\"\n    }\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "13 Read one certificate reference",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/certificate-references/{{kmsTenantCertificateReferenceId}}",
                "description": "Reads the public metadata projection for one reference: provider, alias, kind, source, control mode, the linked key alias and kid, and the public fingerprints. No certificate bytes, no provider credentials.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('certificate reference read', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/kms/v1/certificate-references/00000000-0000-4000-8000-000000000000",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"id\": \"00000000-0000-4000-8000-000000000000\",\n  \"alias\": \"customer-tenant-signing-chain\",\n  \"providerId\": \"default\",\n  \"kind\": \"key_certificate_chain\",\n  \"source\": \"stored_public_material\",\n  \"controlMode\": \"externally_managed\",\n  \"origin\": \"external\",\n  \"linkedKeyReferenceId\": \"00000000-0000-4000-8000-000000000000\",\n  \"linkedKeyAlias\": \"customer-tenant-signing-key\",\n  \"linkedKeyKid\": \"<key-id>\",\n  \"certificateFingerprint\": \"<certificate-thumbprint>\",\n  \"publicKeyFingerprint\": \"<certificate-thumbprint>\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "14 Read the registered chain",
              "request": {
                "method": "GET",
                "url": "{{tenantKmsApiBaseUrl}}/certificate-chains/{{kmsTenantCertificateAlias}}?providerId={{kmsRuntimeProviderId}}",
                "description": "Reads the stored chain back by alias. The certificates array is ordered leaf to root, so the first entry is the one whose public key must match the linked key.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('registered chain read', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/kms/v1/certificate-chains/customer-tenant-signing-chain?providerId=default",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"certificates\": [\n    \"<certificate>\"\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "25 Developer Console Settings",
          "description": "The tenant-scoped Developer Console policy: which console surfaces a tenant exposes and where they are published.",
          "item": [
            {
              "name": "01 Read current console policy",
              "request": {
                "method": "GET",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/developer-console",
                "description": "Reads the effective Developer Console policy for this tenant.",
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('developer console policy read', () => pm.response.to.have.status(200));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "GET",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/developer-console",
                    "header": [
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ]
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"enabled\": true,\n  \"exposureMode\": \"AS_PROTECTED\",\n  \"tools\": {},\n  \"revision\": 0,\n  \"displayUrl\": \"https://acme.example.com/developer-console\"\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            }
          ],
          "event": []
        },
        {
          "name": "20 Authorization code through Keycloak (optional)",
          "description": "Run after folder 09 and the credential metadata request in folder 15. This selects the proxy only for EuPid, so subsequent EuPid pre-authorized offers require removing that override first. Postman handles code, PKCE and access tokens. A real wallet owns its holder proof key; no private signing key is uploaded to a helper service.",
          "item": [
            {
              "name": "01 Select wallet proxy for EuPid authorization code",
              "request": {
                "method": "PUT",
                "url": "{{tenantPlatformConfigApiBaseUrl}}/tenants/{{tenantId}}/oid4vci/issuers/{{issuerId}}/credential-configurations/EuPid/authorization-server",
                "description": "",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"authorizationServerId\": \"{{hostedAuthorizationServerId}}\",\n  \"allowedGrantTypes\": [\n    \"authorization_code\"\n  ],\n  \"expectedRevision\": 0\n}"
                }
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('credential AS override stored', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                      "pm.expect(pm.response.json().authorizationServerId).to.eql(pm.collectionVariables.get('hostedAuthorizationServerId'));",
                      "pm.expect(pm.response.json().revision).to.be.a('number');",
                      "pm.collectionVariables.set('credentialAuthorizationServerOverrideRevision', String(pm.response.json().revision));"
                    ]
                  }
                }
              ],
              "response": [
                {
                  "name": "Previously captured response (sanitized)",
                  "originalRequest": {
                    "method": "PUT",
                    "url": "https://acme.example.com/api/platform/config/v1/tenants/00000000-0000-4000-8000-000000000000/oid4vci/issuers/00000000-0000-4000-8000-000000000000/credential-configurations/EuPid/authorization-server",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      },
                      {
                        "key": "Authorization",
                        "value": "Bearer <token>"
                      },
                      {
                        "key": "Accept",
                        "value": "*/*"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"authorizationServerId\": \"00000000-0000-4000-8000-000000000000\",\n  \"allowedGrantTypes\": [\n    \"authorization_code\"\n  ],\n  \"expectedRevision\": 0\n}"
                    }
                  },
                  "status": "OK",
                  "code": 200,
                  "header": [
                    {
                      "key": "Content-Type",
                      "value": "application/json"
                    }
                  ],
                  "body": "{\n  \"revision\": 1,\n  \"authorizationServerId\": \"00000000-0000-4000-8000-000000000000\",\n  \"allowedGrantTypes\": [\n    \"authorization_code\"\n  ]\n}",
                  "_postman_previewlanguage": "json"
                }
              ]
            },
            {
              "name": "02 Create authorization-code offer",
              "request": {
                "method": "POST",
                "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"credential_configuration_ids\": [\n    \"EuPid\"\n  ],\n  \"grants\": {\n    \"authorization_code\": {\n      \"issuer_state\": \"customer-{{$guid}}\"\n    }\n  },\n  \"correlation_id\": \"postman-authcode-{{$guid}}\",\n  \"credential_subject_data\": {\n    \"family_name\": \"Mustermann\",\n    \"given_name\": \"Erika\",\n    \"birth_date\": \"1964-08-12\",\n    \"age_over_18\": true,\n    \"nationality\": \"DE\",\n    \"issuing_authority\": \"DE\",\n    \"issuing_country\": \"DE\",\n    \"document_number\": \"1234567890\"\n  }\n}"
                },
                "description": "Creates a credential offer that sends the wallet through the OAuth2 authorization code flow with PKCE before credential issuance."
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Offer created', () => pm.expect([200, 201]).to.include(pm.response.code));",
                      "const parseUrl = value => require('url').parse(value, true);",
                      "const httpsOrigin = value => {",
                      "  const parsed = parseUrl(value);",
                      "  if (parsed.protocol !== 'https:' || !parsed.host || parsed.auth) throw new Error('Expected an HTTPS URL without embedded credentials');",
                      "  return parsed.protocol + '//' + parsed.host.toLowerCase();",
                      "};",
                      "const result = pm.response.json();",
                      "const offered = result.credential_offer_uri || result.offer_uri;",
                      "pm.expect(offered).to.be.a('string').and.not.empty;",
                      "const uri = parseUrl(offered);",
                      "const resolved = uri.protocol === 'openid-credential-offer:' ? uri.query.credential_offer_uri : offered;",
                      "pm.expect(httpsOrigin(resolved)).to.eql(httpsOrigin(pm.variables.get('tenantGatewayUrl')));",
                      "pm.collectionVariables.set('walletOfferUri', resolved);"
                    ]
                  }
                }
              ]
            },
            {
              "name": "03 Resolve authorization-code offer",
              "request": {
                "method": "GET",
                "url": "{{walletOfferUri}}",
                "auth": {
                  "type": "noauth"
                },
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));",
                      "const offer = pm.response.json();",
                      "pm.collectionVariables.set('walletIssuerState', offer.grants.authorization_code.issuer_state);",
                      "pm.collectionVariables.set('walletCredentialIssuer', offer.credential_issuer);",
                      "pm.expect(pm.collectionVariables.get('walletIssuerState')).to.be.a('string').and.not.empty;",
                      "const parseUrl = value => require('url').parse(value, true);\nconst httpsOrigin = value => {\n  const parsed = parseUrl(value);\n  if (parsed.protocol !== 'https:' || !parsed.host || parsed.auth) throw new Error('Expected an HTTPS URL without embedded credentials');\n  return parsed.protocol + '//' + parsed.host.toLowerCase();\n};",
                      "const issuer = parseUrl(offer.credential_issuer);",
                      "pm.expect(httpsOrigin(offer.credential_issuer)).to.eql(httpsOrigin(pm.variables.get('tenantGatewayUrl')));",
                      "pm.collectionVariables.set('walletCredentialMetadataUrl', httpsOrigin(offer.credential_issuer) + '/.well-known/openid-credential-issuer' + issuer.pathname.replace(/\\/$/, ''));"
                    ]
                  }
                }
              ]
            },
            {
              "name": "04 Discover hosted wallet authorization server",
              "request": {
                "method": "GET",
                "url": "{{tenantGatewayUrl}}/as/{{authorizationServerSlug}}/.well-known/openid-configuration",
                "auth": {
                  "type": "noauth"
                },
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));",
                      "const metadata = pm.response.json();",
                      "pm.expect(metadata.issuer).to.eql(pm.variables.replaceIn('{{tenantGatewayUrl}}/as/{{authorizationServerSlug}}'));",
                      "pm.collectionVariables.set('walletAuthorizationEndpoint', metadata.authorization_endpoint);",
                      "pm.collectionVariables.set('walletTokenEndpoint', metadata.token_endpoint);"
                    ]
                  }
                }
              ]
            },
            {
              "name": "04a Discover credential issuer endpoints",
              "request": {
                "method": "GET",
                "url": "{{walletCredentialMetadataUrl}}",
                "auth": {
                  "type": "noauth"
                },
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));",
                      "const metadata = pm.response.json();",
                      "pm.expect(metadata.credential_issuer).to.eql(pm.collectionVariables.get('walletCredentialIssuer'));",
                      "pm.expect(metadata.authorization_servers).to.include(pm.variables.replaceIn('{{tenantGatewayUrl}}/as/{{authorizationServerSlug}}'));",
                      "pm.collectionVariables.set('walletCredentialEndpoint', metadata.credential_endpoint);",
                      "pm.collectionVariables.set('walletNonceEndpoint', metadata.nonce_endpoint);"
                    ]
                  }
                }
              ]
            },
            {
              "name": "04b Get a fresh holder-proof nonce",
              "request": {
                "method": "POST",
                "url": "{{walletNonceEndpoint}}",
                "auth": {
                  "type": "noauth"
                },
                "header": []
              },
              "event": [
                {
                  "listen": "test",
                  "script": {
                    "type": "text/javascript",
                    "exec": [
                      "pm.test('Request succeeded', () => pm.response.to.have.status(200));",
                      "pm.collectionVariables.set('walletNonce', pm.response.json().c_nonce);"
                    ]
                  }
                }
              ]
            },
            {
              "name": "05 Wallet credential request",
              "description": "Use Get New Access Token here after steps 01-04, then Use Token. Postman opens the hosted AS, which redirects to Keycloak; Postman exchanges the returned code at the hosted AS. Under Advanced verify issuer_state={{walletIssuerState}} and authorization_details for EuPid. From the token response copy authorization_details[].credential_identifiers[0] to walletCredentialIdentifier (not EuPid). Use the issuer metadata credential_endpoint and nonce_endpoint; create walletProofJwt with your wallet key and current nonce. This is a wallet token, not the tenant application token.",
              "auth": {
                "type": "oauth2",
                "oauth2": [
                  {
                    "key": "tokenName",
                    "value": "Wallet issuance through Keycloak",
                    "type": "string"
                  },
                  {
                    "key": "grant_type",
                    "value": "authorization_code_with_pkce",
                    "type": "string"
                  },
                  {
                    "key": "authUrl",
                    "value": "{{walletAuthorizationEndpoint}}",
                    "type": "string"
                  },
                  {
                    "key": "accessTokenUrl",
                    "value": "{{walletTokenEndpoint}}",
                    "type": "string"
                  },
                  {
                    "key": "clientId",
                    "value": "{{publicHostedClientId}}",
                    "type": "string"
                  },
                  {
                    "key": "redirect_uri",
                    "value": "https://oauth.pstmn.io/v1/browser-callback",
                    "type": "string"
                  },
                  {
                    "key": "scope",
                    "value": "openid profile email",
                    "type": "string"
                  },
                  {
                    "key": "challengeAlgorithm",
                    "value": "S256",
                    "type": "string"
                  },
                  {
                    "key": "state",
                    "value": "{{$guid}}",
                    "type": "string"
                  },
                  {
                    "key": "client_authentication",
                    "value": "none",
                    "type": "string"
                  },
                  {
                    "key": "addTokenTo",
                    "value": "header",
                    "type": "string"
                  },
                  {
                    "key": "headerPrefix",
                    "value": "Bearer",
                    "type": "string"
                  },
                  {
                    "key": "authRequestParams",
                    "type": "any",
                    "value": [
                      {
                        "key": "issuer_state",
                        "value": "{{walletIssuerState}}",
                        "enabled": true,
                        "send_as": "request_url"
                      },
                      {
                        "key": "authorization_details",
                        "value": "[{\"type\":\"openid_credential\",\"credential_configuration_id\":\"EuPid\"}]",
                        "enabled": true,
                        "send_as": "request_url"
                      }
                    ]
                  }
                ]
              },
              "item": [
                {
                  "name": "01 Request credential with wallet proof",
                  "request": {
                    "method": "POST",
                    "url": "{{walletCredentialEndpoint}}",
                    "header": [
                      {
                        "key": "Content-Type",
                        "value": "application/json"
                      }
                    ],
                    "body": {
                      "mode": "raw",
                      "raw": "{\n  \"credential_identifier\": \"{{walletCredentialIdentifier}}\",\n  \"proofs\": {\n    \"jwt\": [\n      \"{{walletProofJwt}}\"\n    ]\n  }\n}",
                      "options": {
                        "raw": {
                          "language": "json"
                        }
                      }
                    }
                  },
                  "event": [
                    {
                      "listen": "test",
                      "script": {
                        "type": "text/javascript",
                        "exec": [
                          "pm.test('Request succeeded', () => pm.response.to.have.status(200));",
                          "pm.expect(pm.response.json().credentials).to.be.an('array').and.not.empty;"
                        ]
                      }
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    },
    {
      "name": "04 Platform - shared Azure vault (optional)",
      "description": "Platform operator owns this resource. Set platformTenantId and platformAzure inputs. Create, attach credentials, validate, then offer to tenantId. Return to tenant application / 08 to accept the offer with tenant authority. Keep platform credentials out of tenant requests.",
      "auth": {
        "type": "oauth2",
        "oauth2": [
          {
            "key": "tokenName",
            "value": "Platform operator",
            "type": "string"
          },
          {
            "key": "grant_type",
            "value": "authorization_code_with_pkce",
            "type": "string"
          },
          {
            "key": "authUrl",
            "value": "{{platformAuthorizationEndpoint}}",
            "type": "string"
          },
          {
            "key": "accessTokenUrl",
            "value": "{{platformTokenEndpoint}}",
            "type": "string"
          },
          {
            "key": "clientId",
            "value": "developer-postman",
            "type": "string"
          },
          {
            "key": "redirect_uri",
            "value": "https://oauth.pstmn.io/v1/browser-callback",
            "type": "string"
          },
          {
            "key": "scope",
            "value": "openid profile email",
            "type": "string"
          },
          {
            "key": "challengeAlgorithm",
            "value": "S256",
            "type": "string"
          },
          {
            "key": "state",
            "value": "{{$guid}}",
            "type": "string"
          },
          {
            "key": "client_authentication",
            "value": "none",
            "type": "string"
          },
          {
            "key": "addTokenTo",
            "value": "header",
            "type": "string"
          },
          {
            "key": "headerPrefix",
            "value": "Bearer",
            "type": "string"
          }
        ]
      },
      "item": [
        {
          "name": "01 Create an Azure Key Vault KMS resource",
          "request": {
            "method": "POST",
            "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{platformTenantId}}/kms/resources",
            "description": "Registers your own Azure Key Vault as a KMS resource of this tenant. providerId is the name you will use for this KMS on the KMS runtime API; applicationId is the label EDK stamps on keys it generates in the vault; tenantId and clientId identify the Entra application EDK signs in with. Keys generated through this resource never leave the vault.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"providerId\": \"{{platformAzureProviderId}}\",\n  \"kind\": \"AZURE_KEY_VAULT\",\n  \"displayName\": \"{{platformAzureDisplayName}}\",\n  \"configuration\": {\n    \"vaultUri\": \"{{platformAzureVaultUri}}\",\n    \"tenantId\": \"{{platformAzureTenantId}}\",\n    \"clientId\": \"{{platformAzureClientId}}\",\n    \"hsmType\": \"KEYVAULT\"\n  }\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Azure Key Vault KMS resource created', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([201]));",
                  "const resource = pm.response.json();",
                  "pm.test('the resource is addressed by an opaque handle and your provider id', () => {",
                  "  pm.expect(resource.handle, 'resource handle').to.match(/^krh_[A-Za-z0-9_-]+$/);",
                  "  pm.expect(resource.providerId, 'provider id').to.eql(pm.variables.get('platformAzureProviderId'));",
                  "  pm.expect(resource.kind, 'kind').to.eql('AZURE_KEY_VAULT');",
                  "  pm.expect(resource.credentialConfigured, 'no credential yet').to.eql(false);",
                  "  pm.expect(resource.credentialSecretRef, 'credential slot reference').to.match(/^kcr_[A-Za-z0-9_-]{20,180}_azure$/);",
                  "});",
                  "pm.collectionVariables.set('platformAzureResourceHandle', resource.handle);",
                  "pm.collectionVariables.set('platformAzureResourceVersion', String(resource.resourceVersion));",
                  "pm.collectionVariables.set('platformAzureCredentialSecretRef', resource.credentialSecretRef);",
                  "pm.collectionVariables.set('platformAzureProviderId', resource.providerId);"
                ]
              }
            }
          ]
        },
        {
          "name": "02 Attach the Azure client secret",
          "request": {
            "method": "PUT",
            "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{platformTenantId}}/kms/resources/{{platformAzureResourceHandle}}/credentials/azure-key-vault",
            "description": "Writes the Entra client secret once. The request names the credential slot the create response returned and the resource version it expects; the response confirms the write without ever returning the secret.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json",
                "type": "text"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"expectedResourceVersion\": \"{{platformAzureResourceVersion}}\",\n  \"clientSecretRef\": \"{{platformAzureCredentialSecretRef}}\",\n  \"clientSecret\": \"{{platformAzureClientSecret}}\"\n}",
              "options": {
                "raw": {
                  "language": "json"
                }
              }
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Azure client secret attached', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200]));",
                  "const result = pm.response.json();",
                  "pm.test('the write advances the resource version and marks the credential present', () => {",
                  "  pm.expect(result.handle, 'resource handle').to.eql(pm.collectionVariables.get('platformAzureResourceHandle'));",
                  "  pm.expect(result.credentialConfigured, 'credential configured').to.eql(true);",
                  "  pm.expect(result.secretRef, 'credential slot reference').to.eql(pm.collectionVariables.get('platformAzureCredentialSecretRef'));",
                  "  pm.expect(result.resourceVersion, 'resource version').to.be.above(Number(pm.collectionVariables.get('platformAzureResourceVersion')));",
                  "});",
                  "const responseText = pm.response.text();",
                  "pm.expect(responseText, 'the response never echoes the supplied secret').to.not.include(pm.variables.get('platformAzureClientSecret'));",
                  "pm.expect(responseText, 'the response carries no secret value field').to.not.match(/\"(?:clientSecret|secretAccessKey|password|secretValue)\"\\s*:/i);",
                  "pm.collectionVariables.set('platformAzureResourceVersion', String(result.resourceVersion));"
                ]
              }
            }
          ]
        },
        {
          "name": "03 Validate the Azure Key Vault resource",
          "request": {
            "method": "POST",
            "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{platformTenantId}}/kms/resources/{{platformAzureResourceHandle}}/validate",
            "description": "Asks the platform to reach the vault with the stored credential. A CONFIGURED state with HEALTHY health means keys can be generated and used there.",
            "header": []
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Azure Key Vault resource validated', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.be.oneOf([200]));",
                  "const result = pm.response.json();",
                  "pm.test('the vault is reachable with the stored credential', () => {",
                  "  pm.expect(result.handle, 'resource handle').to.eql(pm.collectionVariables.get('platformAzureResourceHandle'));",
                  "  pm.expect(result.state, 'state').to.eql('CONFIGURED');",
                  "  pm.expect(['HEALTHY', 'UNKNOWN'], 'health').to.include(result.health);",
                  "});"
                ]
              }
            }
          ]
        },
        {
          "name": "03 Offer the platform KMS as a shared instance",
          "request": {
            "method": "PUT",
            "url": "{{platformUrl}}/api/platform/config/v1/tenants/{{platformTenantId}}/kms/resources/{{platformAzureResourceHandle}}/sharing",
            "description": "Changes the offer from template fulfillment to shared-instance fulfillment. The tenant receives access to the platform-owned provider connection through its own entitlement, while tenant key and certificate references, aliases, listings, and audit identity remain tenant-scoped.",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"fulfillment\": \"SHARED_INSTANCE\",\n  \"tenantIds\": [\n    \"{{tenantId}}\"\n  ],\n  \"suggestedDefault\": false,\n  \"expectedResourceVersion\": {{platformAzureResourceVersion}}\n}"
            }
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('Request succeeded', () => pm.response.to.have.status(200));"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "PUT",
                "url": "https://platform.example.com/api/platform/config/v1/tenants/platform/kms/resources/krh_<opaque>/sharing",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"fulfillment\": \"SHARED_INSTANCE\",\n  \"tenantIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"suggestedDefault\": false,\n  \"expectedResourceVersion\": 1\n}"
                }
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"tenantIds\": [\n    \"00000000-0000-4000-8000-000000000000\"\n  ],\n  \"fulfillment\": \"SHARED_INSTANCE\",\n  \"suggestedDefault\": false\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        }
      ]
    },
    {
      "name": "05 Subtenants",
      "description": "Optional platform administration. Create a child tenant, then repeat tenant owner activation and confidential-client registration with a separate environment for the child. Never reuse the parent application token for child operations.",
      "event": [
        {
          "listen": "prerequest",
          "script": {
            "type": "text/javascript",
            "exec": [
              "// Subtenant slugs are globally unique, not unique per parent, so both levels derive from the",
              "// slug of the tenant folder 03 registered. Tenant URLs are flat: <slug>.<baseDomain>.",
              "const gateway = String(pm.collectionVariables.get('tenantGatewayUrl') || '').trim().replace(/\\/+$/, '');",
              "const rootSlug = String(pm.collectionVariables.get('tenantSubdomain') || '').trim();",
              "if (gateway && rootSlug) {",
              "  const subSlug = rootSlug + '-eu';",
              "  const subSubSlug = rootSlug + '-eu-hr';",
              "  pm.collectionVariables.set('subTenantSlug', subSlug);",
              "  pm.collectionVariables.set('subSubTenantSlug', subSubSlug);",
              "  const parsed = gateway.match(/^([a-z][a-z0-9+.-]*):\\/\\/([^/?#]+)$/i);",
              "  if (parsed) {",
              "    const scheme = parsed[1].toLowerCase();",
              "    const authority = parsed[2];",
              "    const port = (authority.match(/:(\\d+)$/) || [])[1];",
              "    const host = authority.replace(/:\\d+$/, '');",
              "    const domain = host.startsWith(rootSlug + '.') ? host.slice(rootSlug.length + 1) : host;",
              "    const subSubHost = subSubSlug + '.' + domain;",
              "    const subSubAuthority = subSubHost + (port ? ':' + port : '');",
              "    const subSubGateway = scheme + '://' + subSubAuthority;",
              "    // subTenant* addresses acme-eu-hr, the tenant this folder issues from.",
              "    pm.collectionVariables.set('subTenantHost', subSubHost);",
              "    pm.collectionVariables.set('subTenantPublicAuthority', subSubAuthority);",
              "    pm.collectionVariables.set('subTenantGatewayUrl', subSubGateway);",
              "    pm.collectionVariables.set('subTenantIssuerApiBaseUrl', subSubGateway + '/api/oid4vci/v1');",
              "    pm.collectionVariables.set('subTenantPlatformConfigApiBaseUrl', subSubGateway + '/api/platform/config/v1');",
              "  }",
              "}"
            ]
          }
        }
      ],
      "item": [
        {
          "name": "01 Register the acme-eu subtenant",
          "request": {
            "method": "POST",
            "url": "{{platformUrl}}/api/platform/admin/v1/tenants",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"tenant\": {\n    \"tenantType\": \"organization\",\n    \"name\": \"{{tenantName}} EU\",\n    \"description\": \"{{tenantName}} EU subtenant\",\n    \"slug\": \"{{subTenantSlug}}\",\n    \"parentTenantId\": \"{{tenantId}}\",\n    \"initialPlatformSubdomain\": true\n  },\n  \"contacts\": {\n    \"technical\": {\n      \"email\": \"admin@{{subTenantSlug}}.example\",\n      \"displayName\": \"{{tenantName}} EU Technical Contact\"\n    },\n    \"administrativeSameAsTechnical\": true,\n    \"ownerAdmin\": {\n      \"source\": \"technical\"\n    }\n  },\n  \"login\": {\n    \"enabled\": true,\n    \"defaultAuthorizationServerRequired\": true\n  },\n  \"provisioning\": {\n    \"issuer\": true,\n    \"verifier\": true,\n    \"keysAndDids\": true,\n    \"sampleData\": true\n  }\n}"
            },
            "description": "Registers the first subtenant under the tenant of folder 03. `parentTenantId` sits inside the `tenant` section; a null value there would make the registration a root tenant. Slugs are globally unique rather than unique per parent, so the subtenant slug derives from the root slug. The QA licence must allow subtenants, otherwise the platform rejects the registration with `license_subtenants_disallowed`."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('acme-eu registered', () => pm.expect([200, 201], 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.include(pm.response.code));",
                  "const j = pm.response.json();",
                  "const tenant = j.tenant || j;",
                  "pm.test('acme-eu is a child of the expected parent', () => {",
                  "  pm.expect(tenant.id, 'subtenant id').to.be.a('string').and.not.empty;",
                  "  pm.expect(tenant.parentTenantId, 'parentTenantId').to.eql(pm.collectionVariables.get('tenantId'));",
                  "});",
                  "pm.collectionVariables.set('subTenantId', tenant.id);",
                  "const correlationId = j.correlationId || (j.registration && j.registration.correlationId) || tenant.correlationId;",
                  "pm.expect(correlationId, 'tenant onboarding correlation id').to.be.a('string').and.not.empty;",
                  "pm.collectionVariables.set('subTenantOnboardingCorrelationId', correlationId);"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "POST",
                "url": "https://platform.example.com/api/platform/admin/v1/tenants",
                "header": [
                  {
                    "key": "Content-Type",
                    "value": "application/json"
                  },
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ],
                "body": {
                  "mode": "raw",
                  "raw": "{\n  \"tenant\": {\n    \"tenantType\": \"organization\",\n    \"name\": \"Acme Corporation EU\",\n    \"description\": \"Acme Corporation EU subtenant\",\n    \"slug\": \"acme-eu\",\n    \"parentTenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"initialPlatformSubdomain\": true\n  },\n  \"contacts\": {\n    \"technical\": {\n      \"email\": \"admin@acme-eu.example\",\n      \"displayName\": \"Acme Corporation EU Technical Contact\"\n    },\n    \"administrativeSameAsTechnical\": true,\n    \"ownerAdmin\": {\n      \"source\": \"technical\"\n    }\n  },\n  \"login\": {\n    \"enabled\": true,\n    \"defaultAuthorizationServerRequired\": true\n  },\n  \"provisioning\": {\n    \"issuer\": true,\n    \"verifier\": true,\n    \"keysAndDids\": true,\n    \"sampleData\": true\n  }\n}"
                }
              },
              "status": "Created",
              "code": 201,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"tenant\": {\n    \"id\": \"00000000-0000-4000-8000-000000000000\",\n    \"tenantType\": \"organization\",\n    \"name\": \"Acme Corporation EU\",\n    \"description\": \"Acme Corporation EU subtenant\",\n    \"slug\": \"acme-eu\",\n    \"parentTenantId\": \"00000000-0000-4000-8000-000000000000\",\n    \"status\": \"ACTIVE\",\n    \"system\": false,\n    \"ownerPartyId\": null,\n    \"createdAt\": \"2026-01-01T00:00:00Z\",\n    \"createdById\": \"00000000-0000-4000-8000-000000000000\",\n    \"updatedAt\": \"2026-01-01T00:00:00Z\",\n    \"updatedById\": \"00000000-0000-4000-8000-000000000000\",\n    \"deletedAt\": null,\n    \"deletedById\": null\n  },\n  \"tenantUrl\": \"https://acme-eu.example.com\",\n  \"serviceUrls\": {\n    \"authorizationServerUrl\": \"https://acme-eu.example.com/as/acme-eu\",\n    \"issuerUrl\": \"https://acme-eu.example.com/as/acme-eu\",\n    \"oid4vciIssuerUrl\": \"https://acme-eu.example.com/oid4vci/acme-eu\",\n    \"oid4vpVerifierUrl\": \"https://acme-eu.example.com/oid4vp/acme-eu\"\n  },\n  \"correlationId\": \"00000000-0000-4000-8000-000000000000\",\n  \"created\": {\n    \"ownerPartyId\": \"00000000-0000-4000-8000-000000000000\",\n    \"technicalContactPartyId\": \"00000000-0000-4000-8000-000000000000\",\n    \"administrativeContactPartyId\": \"00000000-0000-4000-8000-000000000000\",\n    \"ownerAdminPartyId\": \"00000000-0000-4000-8000-000000000000\",\n    \"ownerAccountId\": \"00000000-0000-4000-8000-000000000000\",\n    \"ownerIdentityId\": \"00000000-0000-4000-8000-000000000000\",\n    \"relationshipIds\": [\n      \"00000000-0000-4000-8000-000000000000\",\n      \"00000000-0000-4000-8000-000000000000\",\n      \"00000000-0000-4000-8000-000000000000\",\n      \"00000000-0000-4000-8000-000000000000\"\n    ]\n  },\n  \"delivery\": {\n    \"status\": \"MANUAL_READY\",\n    \"invitationId\": \"00000000-0000-4000-8000-000000000000\",\n    \"expiresAt\": \"2027-01-01T00:00:00Z\",\n    \"manualActivationLink\": \"https://acme-eu.example.com/as/acme-eu/account-action#<activation-token>\",\n    \"reason\": null\n  }\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        },
        {
          "name": "02 Wait for the acme-eu onboarding to complete",
          "request": {
            "method": "GET",
            "url": "{{platformUrl}}/api/platform/admin/v1/tenant-onboarding/{{subTenantOnboardingCorrelationId}}",
            "description": "Polls the onboarding status row the registration created. The status is one of IN_FLIGHT, COMPLETED, COMPENSATED or ORPHANED; the request re-runs itself while the saga is still in flight. Subtenants receive the same provisioning as roots: hosted authorization server, issuer instance, verifier and a did:web identifier.",
            "header": []
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const attempt = Number(pm.collectionVariables.get('subTenantOnboardingAttempt') || 0);",
                  "pm.collectionVariables.set('subTenantOnboardingAttempt', String(attempt + 1));"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('acme-eu onboarding status returned', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                  "const status = pm.response.json();",
                  "const attempt = Number(pm.collectionVariables.get('subTenantOnboardingAttempt') || 1);",
                  "pm.expect(status.status, 'onboarding status').to.be.oneOf(['IN_FLIGHT', 'COMPLETED', 'COMPENSATED', 'ORPHANED']);",
                  "if (status.status === 'IN_FLIGHT' && attempt < 20) {",
                  "  postman.setNextRequest('02 Wait for the acme-eu onboarding to complete');",
                  "} else {",
                  "  pm.collectionVariables.unset('subTenantOnboardingAttempt');",
                  "  pm.test('acme-eu onboarding completed', () => {",
                  "    pm.expect(status.status, 'terminal onboarding status after ' + attempt + ' poll(s)').to.eql('COMPLETED');",
                  "    pm.expect(status.tenantId, 'tenant id').to.eql(pm.collectionVariables.get('subTenantId'));",
                  "  });",
                  "  const steps = Array.isArray(status.steps) ? status.steps : [];",
                  "  const stepId = (record) => typeof record.step === 'string' ? record.step : (record.step && record.step.id) || record.stepId || record.id;",
                  "  pm.test('acme-eu onboarding provisioned every step without error', () => {",
                  "    pm.expect(steps.length, 'onboarding step timeline').to.be.greaterThan(0);",
                  "    pm.expect(steps.filter((record) => record.error).map((record) => stepId(record) + '=' + record.error), 'failed steps').to.eql([]);",
                  "  });",
                  "}"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "GET",
                "url": "https://platform.example.com/api/platform/admin/v1/tenant-onboarding/00000000-0000-4000-8000-000000000000",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ]
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"correlationId\": \"00000000-0000-4000-8000-000000000000\",\n  \"tenantId\": \"00000000-0000-4000-8000-000000000000\",\n  \"status\": \"COMPLETED\",\n  \"startedAt\": \"2026-01-01T00:00:00Z\",\n  \"updatedAt\": \"2026-01-01T00:00:00Z\",\n  \"completedAt\": \"2026-01-01T00:00:00Z\",\n  \"lastError\": null,\n  \"steps\": [\n    {\n      \"step\": {\n        \"id\": \"as-endpoint-bound\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"as-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"contacts-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"default-kms-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"default-settings-applied\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"deployment-kms-offers-applied\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"did-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"did-state-migrated\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"internal-client-credential-catalog-v2-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"isolation-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"issuer-endpoint-bound\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"issuer-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"opaque-internal-client-credentials-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"organization-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"owner-invitation-minted\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"owner-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"relationships-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"routing-inserted\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"sample-data-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"software-catalog-reconciled\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"software-resource-authorization-server-authority-migrated\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"software-resource-oid4vci-issuer-authorization-bound\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"tenant-schemas-ensured\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"tenant-workload-clients-migrated\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"verifier-endpoint-bound\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    },\n    {\n      \"step\": {\n        \"id\": \"verifier-provisioned\"\n      },\n      \"startedAt\": \"2026-01-01T00:00:00Z\",\n      \"completedAt\": \"2026-01-01T00:00:00Z\",\n      \"error\": null\n    }\n  ]\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        },
        {
          "name": "05 List the children of the root tenant",
          "request": {
            "method": "GET",
            "url": "{{platformUrl}}/api/platform/admin/v1/tenants/{{tenantId}}/children?page=0&size=50",
            "description": "Lists the immediate children of the root tenant as a paginated envelope. Only acme-eu is an immediate child; acme-eu-hr hangs off acme-eu and is therefore not in this page.",
            "header": []
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('root tenant children listed', () => pm.expect(pm.response.code, 'body: ' + String(pm.response.text() || '').slice(0, 300)).to.eql(200));",
                  "const j = pm.response.json();",
                  "const children = j.data || j.items || (Array.isArray(j) ? j : []);",
                  "const subTenantId = pm.collectionVariables.get('subTenantId');",
                  "const subSubTenantId = pm.collectionVariables.get('subSubTenantId');",
                  "pm.test('the root tenant lists acme-eu as its immediate child', () => {",
                  "  const child = children.find((entry) => entry.id === subTenantId);",
                  "  pm.expect(child, 'acme-eu child row').to.be.an('object');",
                  "  pm.expect(child.slug, 'child slug').to.eql(pm.collectionVariables.get('subTenantSlug'));",
                  "  pm.expect(child.parentTenantId, 'child parent').to.eql(pm.collectionVariables.get('tenantId'));",
                  "});",
                  "pm.test('the children listing is immediate, not transitive', () => {",
                  "  pm.expect(children.map((entry) => entry.id), 'acme-eu-hr must not appear under the root').to.not.include(subSubTenantId);",
                  "});"
                ]
              }
            }
          ],
          "response": [
            {
              "name": "Previously captured response (sanitized)",
              "originalRequest": {
                "method": "GET",
                "url": "https://platform.example.com/api/platform/admin/v1/tenants/00000000-0000-4000-8000-000000000000/children?page=0&size=50",
                "header": [
                  {
                    "key": "Authorization",
                    "value": "Bearer <token>"
                  },
                  {
                    "key": "Accept",
                    "value": "*/*"
                  }
                ]
              },
              "status": "OK",
              "code": 200,
              "header": [
                {
                  "key": "Content-Type",
                  "value": "application/json"
                }
              ],
              "body": "{\n  \"data\": [\n    {\n      \"id\": \"00000000-0000-4000-8000-000000000000\",\n      \"tenantType\": \"organization\",\n      \"name\": \"Acme Corporation EU\",\n      \"description\": \"Acme Corporation EU subtenant\",\n      \"slug\": \"acme-eu\",\n      \"parentTenantId\": \"00000000-0000-4000-8000-000000000000\",\n      \"status\": \"ACTIVE\",\n      \"system\": false,\n      \"ownerPartyId\": null,\n      \"createdAt\": \"2026-01-01T00:00:00Z\",\n      \"createdById\": \"00000000-0000-4000-8000-000000000000\",\n      \"updatedAt\": \"2026-01-01T00:00:00Z\",\n      \"updatedById\": \"00000000-0000-4000-8000-000000000000\",\n      \"deletedAt\": null,\n      \"deletedById\": null\n    }\n  ],\n  \"pagination\": {\n    \"limit\": 50,\n    \"offset\": 0,\n    \"page\": 0,\n    \"size\": 50,\n    \"total\": 1,\n    \"totalPages\": 1,\n    \"hasMore\": false\n  }\n}",
              "_postman_previewlanguage": "json"
            }
          ]
        }
      ],
      "auth": {
        "type": "oauth2",
        "oauth2": [
          {
            "key": "tokenName",
            "value": "Platform operator",
            "type": "string"
          },
          {
            "key": "grant_type",
            "value": "authorization_code_with_pkce",
            "type": "string"
          },
          {
            "key": "authUrl",
            "value": "{{platformAuthorizationEndpoint}}",
            "type": "string"
          },
          {
            "key": "accessTokenUrl",
            "value": "{{platformTokenEndpoint}}",
            "type": "string"
          },
          {
            "key": "clientId",
            "value": "developer-postman",
            "type": "string"
          },
          {
            "key": "redirect_uri",
            "value": "https://oauth.pstmn.io/v1/browser-callback",
            "type": "string"
          },
          {
            "key": "scope",
            "value": "openid profile email",
            "type": "string"
          },
          {
            "key": "challengeAlgorithm",
            "value": "S256",
            "type": "string"
          },
          {
            "key": "state",
            "value": "{{$guid}}",
            "type": "string"
          },
          {
            "key": "client_authentication",
            "value": "none",
            "type": "string"
          },
          {
            "key": "addTokenTo",
            "value": "header",
            "type": "string"
          },
          {
            "key": "headerPrefix",
            "value": "Bearer",
            "type": "string"
          }
        ]
      }
    }
  ],
  "variable": [
    {
      "key": "kmsResourceHandle",
      "value": "",
      "type": "string",
      "description": "Opaque tenant KMS resource handle (krh_...) discovered from the typed KMS resource list. This is a platform management/setup identifier only; tenant runtime KMS REST operations use providerId plus the provider-native key alias."
    },
    {
      "key": "statusListDidKmsResourceHandle",
      "value": "",
      "type": "string",
      "description": "Exact KMS resource selected by the provisioned EuPid credential configuration."
    },
    {
      "key": "statusListDidKmsKeyAlias",
      "value": "",
      "type": "string",
      "description": "Exact KMS key selected by the provisioned EuPid credential configuration."
    },
    {
      "key": "statusListDidVerificationMethodId",
      "value": "",
      "type": "string",
      "description": "Exact DID assertionMethod selected by the provisioned EuPid credential configuration."
    },
    {
      "key": "statusListX509KmsResourceHandle",
      "value": "",
      "type": "string",
      "description": "Exact KMS resource selected by the provisioned mDL credential configuration."
    },
    {
      "key": "statusListX509KmsKeyAlias",
      "value": "",
      "type": "string",
      "description": "Exact X.509-backed KMS key selected by the provisioned mDL credential configuration."
    },
    {
      "key": "kmsResourceProviderId",
      "value": "",
      "type": "string",
      "description": "Provider id of the tenant setup KMS resource, read from the typed KMS resource list. The runtime KMS REST API addresses the same KMS by this id, and the admin console joins the two planes on it."
    },
    {
      "key": "verifierId",
      "value": "",
      "type": "string",
      "description": "Resolved from the platform OID4VP verifier instance list after tenant onboarding."
    },
    {
      "key": "issuerId",
      "value": ""
    },
    {
      "key": "verifierInstanceId",
      "value": "",
      "description": "Runtime verifier instance id resolved separately from the verifier party UUID."
    },
    {
      "key": "platformTenantId",
      "value": "",
      "type": "string",
      "description": "Platform tenant the operator token binds to. KMS sharing is authored only by the tenant that owns the KMS."
    },
    {
      "key": "tenantKmsApiBaseUrl",
      "value": "",
      "type": "string",
      "description": "Tenant KMS API base, <tenantGatewayUrl>/api/kms/v1. Derived before every request and kept in collection scope."
    },
    {
      "key": "externalKeyAlias",
      "value": "customer-external-key",
      "type": "string",
      "description": "Exact provider-native alias of the existing external key. EDK stores it unchanged in this tenant's reference index; it is not a private key or secret handle. For a platform-shared AWS or Azure provider, the cloud object must have sphereon-tenant-id set to this collection's tenantId before registration."
    },
    {
      "key": "externalAzureCertificateAlias",
      "value": "customer-azure-leaf-certificate",
      "type": "string",
      "description": "Exact existing Azure Key Vault alias of the provider-native leaf certificate. EDK stores it unchanged in this tenant's certificate reference. For a platform-shared provider, the Azure certificate must have sphereon-tenant-id set to this collection's tenantId."
    },
    {
      "key": "authorizationServerSlug",
      "value": "wallet-proxy"
    },
    {
      "key": "hostedAuthorizationServerId",
      "value": ""
    },
    {
      "key": "hostedAuthorizationServerRevision",
      "value": ""
    },
    {
      "key": "externalAuthorizationServerId",
      "value": ""
    },
    {
      "key": "externalAuthorizationServerRevision",
      "value": ""
    },
    {
      "key": "publicHostedClientId",
      "value": "postman-wallet"
    },
    {
      "key": "federationBindingId",
      "value": ""
    },
    {
      "key": "federationBindingRevision",
      "value": ""
    },
    {
      "key": "federationClientId",
      "value": "walkthrough-federation-client"
    },
    {
      "key": "federationClientSecret",
      "value": ""
    },
    {
      "key": "issuerAuthorizationServerBindingId",
      "value": ""
    },
    {
      "key": "credentialAuthorizationServerOverrideRevision",
      "value": ""
    },
    {
      "key": "baseDomain",
      "value": "",
      "type": "string",
      "description": "Base domain of the installation, optionally with :port. Supplied by the environment; every URL derives from it."
    },
    {
      "key": "platformUrl",
      "value": "",
      "type": "string",
      "description": "Platform origin, https://platform.<baseDomain>. Derived before every request."
    },
    {
      "key": "tenantGatewayUrl",
      "value": "",
      "type": "string",
      "description": "Tenant origin, https://<tenantSubdomain>.<baseDomain>. Derived before every request."
    },
    {
      "key": "tenantSubdomain",
      "value": "",
      "type": "string",
      "description": "Tenant subdomain this run registers and works in. Supplied by the environment."
    },
    {
      "key": "tenantName",
      "value": "",
      "type": "string",
      "description": "Display name of the tenant this run registers. Supplied by the environment."
    },
    {
      "key": "tenantServiceClientId",
      "value": "tenant-api",
      "type": "string",
      "description": "Client id of the confidential tenant service client. Defaults to <tenantSubdomain>-service; an environment value overrides it."
    },
    {
      "key": "tenantServiceClientSecret",
      "value": "",
      "type": "secret",
      "description": "Write-once secret of the tenant service client. Generated by 04 / 07b unless the environment supplies one; never returned by an API."
    },
    {
      "key": "subTenantId",
      "value": "",
      "description": "Tenant id of the acme-eu subtenant registered under the tenant of folder 03. Set by folder 03b; the children listings and the second registration address it."
    },
    {
      "key": "subSubTenantId",
      "value": "",
      "description": "Tenant id of the acme-eu-hr sub-subtenant registered under acme-eu. Set by folder 03b; its own authorization server, issuer and credential configuration are addressed with it."
    },
    {
      "key": "kmsTenantKeyAlias",
      "value": ""
    },
    {
      "key": "kmsTenantCertificateAlias",
      "value": ""
    },
    {
      "key": "kmsTenantKeyChain",
      "value": ""
    },
    {
      "key": "kmsTenantCertificateReferenceId",
      "value": ""
    },
    {
      "key": "brandingAssetsHosted",
      "value": "",
      "description": "Run state: 'true' once hosted branding assets were observed. Set by 10 / 01."
    },
    {
      "key": "tenantAzureProviderId",
      "value": "customer-azure-vault",
      "description": "Provider id you choose for your Azure Key Vault on the KMS runtime API. Lowercase letters, digits and hyphens."
    },
    {
      "key": "tenantAzureDisplayName",
      "value": "Customer Azure Key Vault",
      "description": "Display name of your Azure Key Vault KMS resource."
    },
    {
      "key": "tenantAzureVaultUri",
      "value": "replace-with-https://<vault-name>.vault.azure.net",
      "description": "HTTPS URI of your Key Vault."
    },
    {
      "key": "tenantAzureTenantId",
      "value": "replace-with-entra-tenant-id",
      "description": "Entra tenant id of the application EDK signs in with."
    },
    {
      "key": "tenantAzureClientId",
      "value": "replace-with-entra-client-id",
      "description": "Client id of the Entra application EDK signs in with."
    },
    {
      "key": "tenantAzureClientSecret",
      "value": "replace-with-entra-client-secret",
      "description": "Client secret of that application. Written once by 07 / 01 / 02 and never returned by an API."
    },
    {
      "key": "tenantAzureResourceHandle",
      "value": "",
      "description": "Opaque handle of your Azure Key Vault KMS resource. Set by 07 / 01 / 01."
    },
    {
      "key": "tenantAzureResourceVersion",
      "value": "",
      "description": "Resource version used as the compare-and-set precondition of credential writes. Set by 07 / 01 / 01 and advanced by 07 / 01 / 02."
    },
    {
      "key": "tenantAzureCredentialSecretRef",
      "value": "",
      "description": "Reference of the credential slot the platform derived for your vault credential. Set by 07 / 01 / 01."
    },
    {
      "key": "tenantCloudKmsProviderId",
      "value": "",
      "description": "Provider id of the cloud KMS resource created last in 07 / 01; 07 / 01 / 07 makes it the tenant default."
    },
    {
      "key": "customerTrustListSourceId",
      "value": "customer-trust-list",
      "description": "Source id you choose for your published TS 119 612 trust list."
    },
    {
      "key": "customerTrustListUrl",
      "value": "https://trust.example.com/trust-list.xml",
      "description": "HTTPS URL of the trust list you publish. Replace with your own; the platform fetches it on validation and refresh."
    },
    {
      "key": "customerTrustListSchemeIdentity",
      "value": "https://trust.example.com/trust-list-scheme",
      "description": "Scheme identity URI your trust list declares."
    },
    {
      "key": "customerTrustListHost",
      "value": "",
      "description": "Host of customerTrustListUrl, used as the egress allow-list. Derived by 23 / 17a."
    },
    {
      "key": "customerLoteSourceId",
      "value": "customer-lote",
      "description": "Source id you choose for your published list of trusted entities."
    },
    {
      "key": "customerLoteUrl",
      "value": "https://trust.example.com/lote.jws",
      "description": "HTTPS URL of the JAdES-signed list of trusted entities you publish. Replace with your own."
    },
    {
      "key": "customerLoteHost",
      "value": "",
      "description": "Host of customerLoteUrl, used as the egress allow-list. Derived by 23 / 17c."
    },
    {
      "key": "customerLoteEtag",
      "value": "",
      "description": "Etag of the LoTE source as last read; present it as If-Match on the next mutation of the source."
    },
    {
      "key": "bitstringStatusListId",
      "value": "",
      "description": "Captured from the response of '12 Status Lists / Bitstring VCDM / 01 Create the bitstring status list'."
    },
    {
      "key": "cwtStatusListId",
      "value": "",
      "description": "Captured from the response of '12 Status Lists / CWT mdoc / 01 Create the CWT token status list'."
    },
    {
      "key": "credentialEndpoint",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc / 03 Fetch OID4VCI metadata'."
    },
    {
      "key": "nonceEndpoint",
      "value": "",
      "description": "The singular OID4VCI nonce endpoint discovered from the active credential issuer metadata; its response supplies the current c_nonce."
    },
    {
      "key": "credentialIdentifier",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc / 04 Exchange pre-authorized code for token'."
    },
    {
      "key": "credentialOfferUri",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc / 01 Create EuPid offer'."
    },
    {
      "key": "cwtStatusListUri",
      "value": "",
      "description": "Captured from the response of '12 Status Lists / CWT mdoc / 01 Create the CWT token status list'."
    },
    {
      "key": "cwtStatusListValidUntil",
      "value": "",
      "type": "string",
      "description": "Expiry the CWT mdoc status list is created with; computed by the create request as one year from the run."
    },
    {
      "key": "did",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "didEncoded",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "didJsonUrl",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "walletAccessToken",
      "value": "",
      "description": "Captured from the response of '17 Issue W3C VCDM 1.1 / 05 Exchange the EmployeeBadge pre-authorized code'."
    },
    {
      "key": "employeeBadgeCredentialEndpoint",
      "value": "",
      "description": "Captured from the response of '17 Issue W3C VCDM 1.1 / 04 Fetch the VCDM 1.1 OID4VCI metadata'."
    },
    {
      "key": "employeeBadgeCredentialIdentifier",
      "value": "",
      "description": "Captured from the response of '17 Issue W3C VCDM 1.1 / 05 Exchange the EmployeeBadge pre-authorized code'."
    },
    {
      "key": "employeeBadgeMetadataUrl",
      "value": "",
      "description": "Captured from the response of '17 Issue W3C VCDM 1.1 / 03 Resolve the EmployeeBadge offer'."
    },
    {
      "key": "employeeBadgeOfferUri",
      "value": "",
      "description": "Captured from the response of '17 Issue W3C VCDM 1.1 / 02 Create the EmployeeBadge offer'."
    },
    {
      "key": "employeeBadgePreAuthCode",
      "value": "",
      "description": "Captured from the response of '17 Issue W3C VCDM 1.1 / 03 Resolve the EmployeeBadge offer'."
    },
    {
      "key": "employeeBadgeStatusIndex",
      "value": "",
      "description": "Captured from the response of '17 Issue W3C VCDM 1.1 / 06 Request the EmployeeBadge credential'."
    },
    {
      "key": "employeeBadgeTokenEndpoint",
      "value": "",
      "description": "Captured from the response of '17 Issue W3C VCDM 1.1 / 04 Fetch the VCDM 1.1 OID4VCI metadata'."
    },
    {
      "key": "eupidDesignId",
      "value": "",
      "description": "Captured from the response of '11 Credential Designs / 01 Create EuPid SD-JWT design'."
    },
    {
      "key": "eupidLogoHashLeaf",
      "value": "",
      "description": "Captured from the response of '14 Hosted Branding Verification / 01 Fetch hosted VCT metadata'."
    },
    {
      "key": "eupidLogoIntegrity",
      "value": "",
      "description": "Captured from the response of '11 Credential Designs / 02 Upload EuPid logo asset'."
    },
    {
      "key": "eupidLogoUri",
      "value": "",
      "description": "Captured from the response of '11 Credential Designs / 02 Upload EuPid logo asset'."
    },
    {
      "key": "eupidVariantEnId",
      "value": "",
      "description": "Captured from the response of '11 Credential Designs / 03 Create EuPid render variant (en)'."
    },
    {
      "key": "eupidVariantNlId",
      "value": "",
      "description": "Captured from the response of '11 Credential Designs / 04 Create EuPid render variant (nl)'."
    },
    {
      "key": "issuerDesignId",
      "value": "",
      "description": "Captured from the response of '10 Issuer Configuration / 01 Create issuer design'."
    },
    {
      "key": "issuerLogoIntegrity",
      "value": "",
      "description": "Captured from the response of '10 Issuer Configuration / 02 Upload issuer logo asset'."
    },
    {
      "key": "issuerLogoUri",
      "value": "",
      "description": "Captured from the response of '10 Issuer Configuration / 02 Upload issuer logo asset'."
    },
    {
      "key": "issuerMetadataUrl",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc / 02 Resolve credential offer'."
    },
    {
      "key": "issuerVariantId",
      "value": "",
      "description": "Captured from the response of '10 Issuer Configuration / 03 Create issuer render variant'."
    },
    {
      "key": "kmsRuntimeKeyAlias",
      "value": "",
      "description": "Captured from the response of '24 KMS Runtime API / 01 List runtime providers'."
    },
    {
      "key": "kmsRuntimeProviderId",
      "value": "",
      "description": "Captured from the response of '24 KMS Runtime API / 01 List runtime providers'."
    },
    {
      "key": "kmsRuntimeSignature",
      "value": "",
      "description": "Captured from the response of '24 KMS Runtime API / 05 Create raw signature with providerId and alias'."
    },
    {
      "key": "mdlCredentialIdentifier",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc / 09 Exchange Mdl code for token'."
    },
    {
      "key": "mdlCredentialOfferUri",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc / 07 Create Mdl offer'."
    },
    {
      "key": "mdlDesignId",
      "value": "",
      "description": "Captured from the response of '11 Credential Designs / 06 Create Mdl mdoc design'."
    },
    {
      "key": "mdlLogoIntegrity",
      "value": "",
      "description": "Captured from the response of '11 Credential Designs / 07 Upload Mdl logo asset'."
    },
    {
      "key": "mdlLogoUri",
      "value": "",
      "description": "Captured from the response of '11 Credential Designs / 07 Upload Mdl logo asset'."
    },
    {
      "key": "mdlPreAuthCode",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc / 08 Resolve Mdl offer'."
    },
    {
      "key": "mdlSettingsResourceId",
      "value": "",
      "description": "Captured from the response of '13 Credential Configurations / 02 Read the Mdl credential configuration'."
    },
    {
      "key": "mdlSettingsScope",
      "value": "",
      "description": "Captured from the response of '13 Credential Configurations / 02 Read the Mdl credential configuration'."
    },
    {
      "key": "mdlVariantEnId",
      "value": "",
      "description": "Captured from the response of '11 Credential Designs / 08 Create Mdl render variant (en)'."
    },
    {
      "key": "membershipCredentialEndpoint",
      "value": "",
      "description": "Captured from the response of '18 Issue W3C VCDM 2.0 / 04 Fetch the VCDM 2.0 OID4VCI metadata'."
    },
    {
      "key": "membershipCredentialIdentifier",
      "value": "",
      "description": "Captured from the response of '18 Issue W3C VCDM 2.0 / 05 Exchange the Membership pre-authorized code'."
    },
    {
      "key": "membershipMetadataUrl",
      "value": "",
      "description": "Captured from the response of '18 Issue W3C VCDM 2.0 / 03 Resolve the Membership offer'."
    },
    {
      "key": "membershipOfferUri",
      "value": "",
      "description": "Captured from the response of '18 Issue W3C VCDM 2.0 / 02 Create the Membership offer'."
    },
    {
      "key": "membershipPreAuthCode",
      "value": "",
      "description": "Captured from the response of '18 Issue W3C VCDM 2.0 / 03 Resolve the Membership offer'."
    },
    {
      "key": "membershipStatusIndex",
      "value": "",
      "description": "Captured from the response of '18 Issue W3C VCDM 2.0 / 06 Request the Membership credential'."
    },
    {
      "key": "membershipTokenEndpoint",
      "value": "",
      "description": "Captured from the response of '18 Issue W3C VCDM 2.0 / 04 Fetch the VCDM 2.0 OID4VCI metadata'."
    },
    {
      "key": "operatorRedirectUri",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "platformAzureClientId",
      "value": "replace-with-entra-client-id",
      "description": "Client id of that application (operators only)."
    },
    {
      "key": "platformAzureClientSecret",
      "value": "replace-with-entra-client-secret",
      "description": "Client secret of that application, written once and never returned (operators only)."
    },
    {
      "key": "platformAzureCredentialSecretRef",
      "value": "",
      "description": "Captured from the response of '07 Bring Your Own KMS / 03 Platform Azure Key Vault (operators, optional) / 01 Resolve exact platform Azure resource'."
    },
    {
      "key": "platformAzureDisplayName",
      "value": "Platform Azure Key Vault signing",
      "description": "Display name of the platform tenant's Azure Key Vault resource (operators only)."
    },
    {
      "key": "platformAzureProviderId",
      "value": "azure-shared-signing",
      "description": "Provider id of the platform tenant's Azure Key Vault resource (operators only)."
    },
    {
      "key": "platformAzureResourceHandle",
      "value": "",
      "description": "Captured from the response of '07 Bring Your Own KMS / 03 Platform Azure Key Vault (operators, optional) / 01 Resolve exact platform Azure resource'."
    },
    {
      "key": "platformAzureResourceVersion",
      "value": "",
      "description": "Captured from the response of '07 Bring Your Own KMS / 03 Platform Azure Key Vault (operators, optional) / 01 Resolve exact platform Azure resource'."
    },
    {
      "key": "platformAzureTenantId",
      "value": "replace-with-entra-tenant-id",
      "description": "Entra tenant id of the application the platform signs in with (operators only)."
    },
    {
      "key": "platformAzureVaultUri",
      "value": "replace-with-https://<vault-name>.vault.azure.net",
      "description": "HTTPS URI of the platform tenant's Key Vault (operators only)."
    },
    {
      "key": "preAuthCode",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc / 02 Resolve credential offer'."
    },
    {
      "key": "proofJwt",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc'."
    },
    {
      "key": "requestObjectUri",
      "value": "",
      "description": "Captured from the response of '22 Verification / 01 Create verification request'."
    },
    {
      "key": "statusListId",
      "value": "",
      "description": "Captured from the response of '12 Status Lists / 01 Create token status list'."
    },
    {
      "key": "statusListUri",
      "value": "",
      "description": "Captured from the response of '12 Status Lists / 01 Create token status list'."
    },
    {
      "key": "subTenantOnboardingCorrelationId",
      "value": "",
      "description": "Captured from the response of '05 Subtenants / 01 Register the acme-eu subtenant'."
    },
    {
      "key": "subTenantSlug",
      "value": "",
      "description": "Captured from the response of '05 Subtenants'."
    },
    {
      "key": "tenantAuthorizationEndpoint",
      "value": "",
      "description": "Captured from the response of '03 Tenant Owner Activation and Sign-in / 03 Start tenant owner authorization'."
    },
    {
      "key": "tenantAuthorizationServerOrigin",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tenantCredentialDesignApiBaseUrl",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tenantDcqlApiBaseUrl",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tenantDidApiBaseUrl",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tenantHostedAuthorizationServerId",
      "value": "",
      "description": "Captured from the response of '03 Tenant Owner Activation and Sign-in / 07a Resolve tenant hosted authorization server'."
    },
    {
      "key": "tenantId",
      "value": "",
      "description": "Captured from the response of '02 Tenant Onboarding / 01 Register tenant'."
    },
    {
      "key": "tenantIssuerApiBaseUrl",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tenantPlatformConfigApiBaseUrl",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tenantPublicAuthority",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tenantRegistrationCorrelationId",
      "value": "",
      "description": "Captured from the response of '02 Tenant Onboarding / 01 Register tenant'."
    },
    {
      "key": "tenantStatusListApiBaseUrl",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tenantAccessTokenEndpoint",
      "value": "",
      "description": "Captured from 04 Tenant Service Token / 01 Resolve tenant token endpoint; never guessed or populated asynchronously during token request dispatch."
    },
    {
      "key": "tenantTrustDomainApiBaseUrl",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tenantVerifierBackendBaseUrl",
      "value": "",
      "description": "Derived before every request from baseDomain and tenantSubdomain."
    },
    {
      "key": "tokenEndpoint",
      "value": "",
      "description": "Captured from the response of '15 Issue SD-JWT VC and mdoc / 03 Fetch OID4VCI metadata'."
    },
    {
      "key": "transactionCode",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 01 Create transaction-code EuPid offer'."
    },
    {
      "key": "transactionCorrelationId",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 01 Create transaction-code EuPid offer'."
    },
    {
      "key": "transactionCredentialEndpoint",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 03 Fetch transaction-code OID4VCI metadata'."
    },
    {
      "key": "transactionCredentialIdentifier",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 05 Exchange transaction code for token'."
    },
    {
      "key": "transactionCredentialStatusUri",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 06 Issue transaction-code EuPid credential'."
    },
    {
      "key": "transactionIssuerMetadataUrl",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 02 Resolve transaction-code EuPid offer'."
    },
    {
      "key": "transactionOfferUri",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 01 Create transaction-code EuPid offer'."
    },
    {
      "key": "transactionPreAuthCode",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 02 Resolve transaction-code EuPid offer'."
    },
    {
      "key": "transactionStatusUri",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 01 Create transaction-code EuPid offer'."
    },
    {
      "key": "transactionTokenEndpoint",
      "value": "",
      "description": "Captured from the response of '16 Issue with Transaction Code / 03 Fetch transaction-code OID4VCI metadata'."
    },
    {
      "key": "trustAnchorId",
      "value": "",
      "description": "Captured from the response of '23 Trust Domains and Trust Lists / 02 List anchors of the seeded domain'."
    },
    {
      "key": "trustDomainId",
      "value": "",
      "description": "Captured from the response of '23 Trust Domains and Trust Lists / 01 List trust domains'."
    },
    {
      "key": "trustX509IdentityIdentifierId",
      "value": "",
      "description": "Captured from the response of '23 Trust Domains and Trust Lists / 02 List anchors of the seeded domain'."
    },
    {
      "key": "verifyCorrelationId",
      "value": "",
      "description": "Captured from the response of '22 Verification / 01 Create verification request'."
    },
    {
      "key": "vicalAnchorId",
      "value": "",
      "description": "Captured from the response of '23 Trust Domains and Trust Lists / 11 Create a VICAL signer anchor'."
    },
    {
      "key": "vicalAnchorVersion",
      "value": "",
      "description": "Captured from the response of '23 Trust Domains and Trust Lists / 11 Create a VICAL signer anchor'."
    },
    {
      "key": "vicalDomainId",
      "value": "",
      "description": "Captured from the response of '23 Trust Domains and Trust Lists / 07 Create a second trust domain'."
    },
    {
      "key": "vicalDomainVersion",
      "value": "",
      "description": "Captured from the response of '23 Trust Domains and Trust Lists / 07 Create a second trust domain'."
    },
    {
      "key": "x5cStatusListUri",
      "value": "",
      "description": "Captured from the response of '12 Status Lists / 04a Create X.509 token status list'."
    }
  ]
}
