{
  "info": {
    "name": "EDK Credential Status Profiles (local or approved test target)",
    "_postman_id": "0d3f7b2c-5e8a-4b6f-9c10-2d7e4a8b6f11",
    "description": "Customer-neutral deterministic request set for four credential/status profiles and an opt-in Azure provider reference runbook. Configure deployment coordinates and run-time proof inputs in an external environment; secrets and cloud mutations are never stored here. Manual wallet/verifier and mdoc decoder checkpoints are intentionally explicit.",
    "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
  },
  "variable": [
    {
      "key": "tenantToken",
      "value": ""
    },
    {
      "key": "tenantId",
      "value": ""
    },
    {
      "key": "tenantGatewayUrl",
      "value": "http://localhost:8080"
    },
    {
      "key": "tenantStatusListApiBaseUrl",
      "value": ""
    },
    {
      "key": "tenantCredentialDesignApiBaseUrl",
      "value": ""
    },
    {
      "key": "tenantKmsApiBaseUrl",
      "value": ""
    },
    {
      "key": "platformConfigApiBaseUrl",
      "value": ""
    },
    {
      "key": "tenantIssuerApiBaseUrl",
      "value": ""
    },
    {
      "key": "tenantIssuerMetadataUrl",
      "value": ""
    },
    {
      "key": "runId",
      "value": ""
    },
    {
      "key": "statusListKmsResourceHandle",
      "value": ""
    },
    {
      "key": "statusListVerificationMethodId",
      "value": "did:web:issuer.example.com#status-list-signing"
    },
    {
      "key": "providerId",
      "value": ""
    },
    {
      "key": "providerNativeKeyAlias",
      "value": ""
    },
    {
      "key": "providerNativeCertificateId",
      "value": ""
    },
    {
      "key": "sdJwtProofJwt",
      "value": ""
    },
    {
      "key": "mdocProofJwt",
      "value": ""
    },
    {
      "key": "vcdm11ProofJwt",
      "value": ""
    },
    {
      "key": "vcdm20ProofJwt",
      "value": ""
    },
    {
      "key": "sdJwtStatusListId",
      "value": ""
    },
    {
      "key": "sdJwtStatusListUri",
      "value": ""
    },
    {
      "key": "sdJwtIssuedStatusListUri",
      "value": ""
    },
    {
      "key": "sdJwtIssuedStatusListIndex",
      "value": ""
    },
    {
      "key": "sdJwtIssuedCredentialDigest",
      "value": ""
    },
    {
      "key": "sdJwtTrustedVerificationAttestation",
      "value": ""
    },
    {
      "key": "sdJwtPostRevokeRejectionEvidence",
      "value": ""
    },
    {
      "key": "sdJwtStatusListDecoderEvidence",
      "value": ""
    },
    {
      "key": "mdocStatusListId",
      "value": ""
    },
    {
      "key": "mdocStatusListUri",
      "value": ""
    },
    {
      "key": "mdocIssuedStatusListUri",
      "value": ""
    },
    {
      "key": "mdocIssuedStatusListIndex",
      "value": ""
    },
    {
      "key": "mdocIssuedCredentialDigest",
      "value": ""
    },
    {
      "key": "mdocTrustedVerificationAttestation",
      "value": ""
    },
    {
      "key": "mdocPostRevokeRejectionEvidence",
      "value": ""
    },
    {
      "key": "vcdm11StatusListId",
      "value": ""
    },
    {
      "key": "vcdm11StatusListUri",
      "value": ""
    },
    {
      "key": "vcdm11IssuedStatusListUri",
      "value": ""
    },
    {
      "key": "vcdm11IssuedStatusListIndex",
      "value": ""
    },
    {
      "key": "vcdm11IssuedCredentialDigest",
      "value": ""
    },
    {
      "key": "vcdm11TrustedVerificationAttestation",
      "value": ""
    },
    {
      "key": "vcdm11PostRevokeRejectionEvidence",
      "value": ""
    },
    {
      "key": "vcdm11StatusListDecoderEvidence",
      "value": ""
    },
    {
      "key": "vcdm20StatusListId",
      "value": ""
    },
    {
      "key": "vcdm20StatusListUri",
      "value": ""
    },
    {
      "key": "vcdm20IssuedStatusListUri",
      "value": ""
    },
    {
      "key": "vcdm20IssuedStatusListIndex",
      "value": ""
    },
    {
      "key": "vcdm20IssuedCredentialDigest",
      "value": ""
    },
    {
      "key": "vcdm20TrustedVerificationAttestation",
      "value": ""
    },
    {
      "key": "vcdm20PostRevokeRejectionEvidence",
      "value": ""
    },
    {
      "key": "vcdm20StatusListDecoderEvidence",
      "value": ""
    },
    {
      "key": "mdocInitialStatusDecoderEvidence",
      "value": ""
    },
    {
      "key": "mdocStatusDecoderEvidence",
      "value": ""
    }
  ],
  "item": [
    {
      "name": "01 JWT Token Status List + SD-JWT VC",
      "description": "01 JWT Token Status List + SD-JWT VC lifecycle. The order is create the status list, fetch its exact returned public URI, create and resolve the offer, read issuer metadata, discover the authorization server, exchange the code, issue with a supplied wallet proof, perform the explicit trusted verification checkpoint, revoke the issued index, and refresh the same URI. The public media type is application/statuslist+jwt; signed content, freshness, hash change, status URI/index, and profile encoding are checked where a local decoder is available.  Cloud mutations, wallet proof, trust verification, and mdoc decoding remain explicit run-time boundaries.",
      "item": [
        {
          "name": "Create 01 JWT Token Status List + SD-JWT VC status list",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"correlationId\": \"employee-sd-jwt-revocation\",\n  \"spec\": \"token_status_list\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"proofFormat\": \"jwt\",\n  \"hostingMode\": \"hosted\",\n  \"issuer\": \"did:web:issuer.example.com\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"{{statusListVerificationMethodId}}\",\n  \"kmsResourceHandle\": \"{{statusListKmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"status-list-signing\",\n  \"statusListUri\": \"{{tenantGatewayUrl}}/public/statuslists/employee-sd-jwt-revocation\",\n  \"length\": 131072,\n  \"bitsPerStatus\": 1,\n  \"ttlSeconds\": 300\n}"
            },
            "url": "{{tenantStatusListApiBaseUrl}}/statuslists",
            "description": "Create the profile status publication. The response DTO is authoritative: retain its exact id and statusListUri."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.variables.unset('sdJwtStatusListId'); pm.environment.unset('sdJwtStatusListId');",
                  "pm.variables.unset('sdJwtStatusListUri'); pm.environment.unset('sdJwtStatusListUri');",
                  "pm.variables.unset('sdJwtStatusPublicationReady'); pm.environment.unset('sdJwtStatusPublicationReady');",
                  "pm.variables.unset('sdJwtInitialStatusListHash'); pm.environment.unset('sdJwtInitialStatusListHash');",
                  "pm.variables.unset('sdJwtRefreshedStatusListHash'); pm.environment.unset('sdJwtRefreshedStatusListHash');",
                  "pm.variables.unset('sdJwtIssuedStatusListUri'); pm.environment.unset('sdJwtIssuedStatusListUri');",
                  "pm.variables.unset('sdJwtIssuedStatusListIndex'); pm.environment.unset('sdJwtIssuedStatusListIndex');",
                  "pm.variables.unset('sdJwtIssuedCredential'); pm.environment.unset('sdJwtIssuedCredential');",
                  "pm.variables.unset('sdJwtIssuedCredentialDigest'); pm.environment.unset('sdJwtIssuedCredentialDigest');",
                  "pm.variables.unset('sdJwtTrustedVerificationAttestation'); pm.environment.unset('sdJwtTrustedVerificationAttestation');",
                  "pm.variables.unset('sdJwtPostRevokeRejectionEvidence'); pm.environment.unset('sdJwtPostRevokeRejectionEvidence');",
                  "pm.variables.unset('sdJwtStatusListDecoderEvidence'); pm.environment.unset('sdJwtStatusListDecoderEvidence');"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = [200, 201].includes(pm.response.code);",
                  "pm.test('status list created', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "  const result = pm.response.json();",
                  "  pm.expect(result.id, 'StatusListResult.id').to.be.a('string').and.not.empty;",
                  "  pm.expect(result.statusListUri, 'StatusListResult.statusListUri').to.be.a('string').and.not.empty;",
                  "  pm.variables.set('sdJwtStatusListId', result.id);",
                  "  pm.variables.set('sdJwtStatusListUri', result.statusListUri);",
                  "  pm.environment.set('sdJwtStatusListId', result.id);",
                  "  pm.environment.set('sdJwtStatusListUri', result.statusListUri);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Fetch 01 JWT Token Status List + SD-JWT VC status list",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/statuslist+jwt"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{sdJwtStatusListUri}}",
            "description": "Fetch the exact statusListUri returned by createStatusList. This public request has no management bearer. Check content type, signature, freshness, hash, and the profile encoding."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['StatusPublicationReady', 'InitialStatusListHash', 'RefreshedStatusListHash'].forEach((suffix) => { pm.variables.unset('sdJwt' + suffix); pm.environment.unset('sdJwt' + suffix); });"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('public status publication served', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "pm.test('status publication has the declared media type', () => pm.expect(pm.response.headers.get('Content-Type') || '').to.include('application/statuslist+jwt'));",
                  "const publication = pm.response.text();",
                  "pm.expect(publication, 'non-empty signed status publication').to.not.be.empty;",
                  "const hash = CryptoJS.SHA256(publication).toString(CryptoJS.enc.Hex);",
                  "pm.variables.set('sdJwtInitialStatusListHash', hash);",
                  "pm.environment.set('sdJwtInitialStatusListHash', hash);",
                  "const tokenParts = pm.response.text().split('.');",
                  "pm.expect(tokenParts.length, 'signed status JWT').to.equal(3);",
                  "const tokenPayloadPart = tokenParts[1].replace(/-/g, '+').replace(/_/g, '/');",
                  "const tokenPayload = JSON.parse(Buffer.from(tokenPayloadPart + '='.repeat((4 - tokenPayloadPart.length % 4) % 4), 'base64').toString('utf8'));",
                  "pm.expect(tokenPayload.iss, 'Token Status List issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(tokenPayload.sub, 'Token Status List subject').to.equal(pm.variables.get('sdJwtStatusListUri'));",
                  "pm.expect(Number.isSafeInteger(tokenPayload.iat), 'Token Status List iat').to.equal(true);",
                  "pm.expect(Number.isSafeInteger(tokenPayload.exp) && tokenPayload.exp > Math.floor(Date.now() / 1000), 'Token Status List expiry').to.equal(true);",
                  "pm.expect(tokenPayload.status_list, 'Token Status List envelope').to.be.an('object');",
                  "pm.expect(Number.isInteger(tokenPayload.status_list.bits) && [1, 2, 4, 8].includes(tokenPayload.status_list.bits), 'Token Status List bits').to.equal(true);",
                  "pm.variables.set('sdJwtStatusPublicationReady', 'true'); pm.environment.set('sdJwtStatusPublicationReady', 'true');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 01 JWT Token Status List + SD-JWT VC issuer status binding",
          "description": "Before creating the offer, configure the issuer credential configuration EuPid in the supported tenant configuration surface. Set credentials.[EuPid].status.statusListId to the exact sdJwtStatusListId returned by createStatusList and verify the corresponding root statuslists entry has the same public statusListUri (sdJwtStatusListUri). Confirm issuer metadata advertises this configuration and the same status publication before continuing. This collection has no generic status-binding endpoint; stop if the id, URI, configuration, or advertised status association differs.",
          "item": []
        },
        {
          "name": "Create 01 JWT Token Status List + SD-JWT VC offer",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credential_configuration_ids\": [\n    \"EuPid\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {},\n  \"correlation_id\": \"sdJwt-{{runId}}\"\n}"
            },
            "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
            "description": "Create an offer through the issuer backend DTO. The wallet resolves the returned offer_uri; this request does not fabricate a public grant URI."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('offer created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                  "const result = pm.response.json();",
                  "pm.expect(result.offer_uri, 'offer_uri').to.be.a('string').and.not.empty;",
                  "pm.expect(result.correlation_id, 'correlation_id').to.be.a('string').and.not.empty;",
                  "pm.variables.set('sdJwtOfferUri', result.offer_uri);",
                  "const offerMatch = result.offer_uri.match(/[?&]credential_offer_uri=([^&]+)/); pm.expect(offerMatch && offerMatch[1], 'credential_offer_uri').to.be.a('string').and.not.empty; pm.variables.set('sdJwtCredentialOfferUri', decodeURIComponent(offerMatch[1]));"
                ]
              }
            }
          ]
        },
        {
          "name": "Resolve 01 JWT Token Status List + SD-JWT VC offer",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{sdJwtCredentialOfferUri}}",
            "description": "Resolve the offer as a wallet. Require the issuer, exact configuration id, and the canonical OID4VCI pre-authorized grant namespace."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('offer resolved', () => pm.response.to.have.status(200));",
                  "const offer = pm.response.json();",
                  "pm.expect(offer.credential_issuer, 'credential_issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(offer.credential_configuration_ids, 'credential_configuration_ids').to.include('EuPid');",
                  "const grant = offer.grants && offer.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'];",
                  "pm.expect(grant, 'canonical pre-authorized grant').to.be.an('object');",
                  "pm.expect(grant['pre-authorized_code'], 'pre-authorized_code').to.be.a('string').and.not.empty;",
                  "pm.variables.set('sdJwtCredentialIssuer', offer.credential_issuer);",
                  "pm.variables.set('sdJwtPreAuthCode', grant['pre-authorized_code']);"
                ]
              }
            }
          ]
        },
        {
          "name": "Fetch 01 JWT Token Status List + SD-JWT VC issuer metadata",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{tenantIssuerMetadataUrl}}",
            "description": "Read the exact issuer metadata URL supplied by the approved tenant bootstrap. Use its advertised credential_endpoint and authorization_servers; no well-known path is invented from a host name."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('issuer metadata served', () => pm.response.to.have.status(200));",
                  "const metadata = pm.response.json();",
                  "pm.expect(metadata.credential_issuer, 'metadata credential_issuer').to.equal(pm.variables.get('sdJwtCredentialIssuer'));",
                  "pm.expect(metadata.credential_endpoint, 'metadata credential_endpoint').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.authorization_servers, 'metadata authorization_servers').to.be.an('array').and.not.empty;",
                  "const profile = metadata.credential_configurations_supported && metadata.credential_configurations_supported['EuPid'];",
                  "pm.expect(profile, 'advertised credential configuration').to.be.an('object');",
                  "pm.expect(profile.format, 'credential format').to.equal('dc+sd-jwt');",
                  "pm.variables.set('sdJwtCredentialEndpoint', metadata.credential_endpoint);",
                  "pm.variables.set('sdJwtAuthorizationServer', metadata.authorization_servers[0]);"
                ]
              }
            }
          ]
        },
        {
          "name": "Discover 01 JWT Token Status List + SD-JWT VC authorization server",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{tenantGatewayUrl}}/.well-known/oauth-authorization-server",
            "description": "Discover the authorization server at the tenant well-known endpoint and retain the advertised token_endpoint. The collection never appends /token."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('authorization server metadata served', () => pm.response.to.have.status(200));",
                  "const metadata = pm.response.json();",
                  "pm.expect(metadata.issuer, 'authorization-server issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.token_endpoint, 'advertised token_endpoint').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.issuer, 'issuer matches credential metadata').to.equal(pm.variables.get('sdJwtAuthorizationServer'));",
                  "pm.variables.set('sdJwtTokenEndpoint', metadata.token_endpoint);"
                ]
              }
            }
          ]
        },
        {
          "name": "Exchange 01 JWT Token Status List + SD-JWT VC pre-authorized code",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/x-www-form-urlencoded"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
                },
                {
                  "key": "pre-authorized_code",
                  "value": "{{sdJwtPreAuthCode}}"
                }
              ]
            },
            "url": "{{sdJwtTokenEndpoint}}",
            "description": "Exchange the offer-derived code at the token_endpoint advertised by authorization-server discovery. Keep the access token in run-local variables only."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('token exchanged', () => pm.response.to.have.status(200));",
                  "const tokenResponse = pm.response.json();",
                  "pm.expect(tokenResponse.access_token, 'access_token').to.be.a('string').and.not.empty;",
                  "pm.expect(tokenResponse.authorization_details, 'authorization_details').to.be.an('array').and.not.empty;",
                  "const authorization = tokenResponse.authorization_details.find((entry) => entry.type === 'openid_credential' && entry.credential_configuration_id === 'EuPid');",
                  "pm.expect(authorization, 'profile authorization detail').to.be.an('object');",
                  "pm.expect(authorization.credential_identifiers, 'credential_identifiers').to.be.an('array').and.not.empty;",
                  "pm.variables.set('sdJwtAccessToken', tokenResponse.access_token);",
                  "pm.variables.set('sdJwtCredentialIdentifier', authorization.credential_identifiers[0]);"
                ]
              }
            }
          ]
        },
        {
          "name": "Issue 01 JWT Token Status List + SD-JWT VC",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{sdJwtAccessToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credential_identifier\": \"{{sdJwtCredentialIdentifier}}\",\n  \"proofs\": {\n    \"jwt\": [\n      \"{{sdJwtProofJwt}}\"\n    ]\n  }\n}"
            },
            "url": "{{sdJwtCredentialEndpoint}}",
            "description": "Issue the dc+sd-jwt credential using the profile credential identifier returned in authorization_details. Supply a real wallet proof at run time; no proof or identifier is fabricated here."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['IssuedStatusListUri', 'IssuedStatusListIndex', 'IssuedCredential', 'IssuedCredentialDigest', 'TrustedVerificationAttestation'].forEach((suffix) => { pm.variables.unset('sdJwt' + suffix); pm.environment.unset('sdJwt' + suffix); });",
                  "const issuanceReady = Boolean(pm.variables.get('sdJwtAccessToken') && pm.variables.get('sdJwtCredentialIdentifier') && (pm.variables.get('sdJwtProofJwt') || pm.environment.get('sdJwtProofJwt')));",
                  "pm.test('issuance inputs are present', () => pm.expect(issuanceReady, 'access token, profile credential identifier, and run-time proof are required').to.equal(true));",
                  "if (!issuanceReady) { pm.execution.skipRequest(); }"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('credential issued', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "const response = pm.response.json();",
                  "const credential = response.credentials && response.credentials[0] && response.credentials[0].credential;",
                  "pm.expect(credential, 'issued credential').to.be.a('string').and.not.empty;",
                  "pm.variables.set('sdJwtIssuedCredential', credential);",
                  "const parts = credential.split('~')[0].split('.');",
                  "pm.expect(parts.length, 'compact JWT payload').to.be.greaterThan(1);",
                  "const encoded = parts[1].replace(/-/g, '+').replace(/_/g, '/');",
                  "const padded = encoded + '='.repeat((4 - encoded.length % 4) % 4);",
                  "const payload = JSON.parse(Buffer.from(padded, 'base64').toString('utf8'));",
                  "pm.expect(payload.status && payload.status.status_list, 'SD-JWT Token Status List claim').to.be.an('object');",
                  "const status = payload.status && payload.status.status_list;",
                  "pm.expect(status, 'issued credential status').to.be.an('object');",
                  "pm.expect(status.uri, 'issued status URI').to.be.a('string').and.not.empty;",
                  "const rawIssuedIndex = status.idx; const issuedIndex = Number(rawIssuedIndex); const validIssuedIndex = (typeof rawIssuedIndex === 'number' && Number.isSafeInteger(rawIssuedIndex)) || (typeof rawIssuedIndex === 'string' && /^\\d+$/.test(rawIssuedIndex)); pm.expect(validIssuedIndex && issuedIndex >= 0 && issuedIndex < 131072, 'issued status index must be a non-negative in-range integer').to.equal(true);",
                  "pm.variables.set('sdJwtIssuedStatusListUri', status.uri);",
                  "pm.variables.set('sdJwtIssuedStatusListIndex', String(issuedIndex));",
                  "pm.variables.set('sdJwtIssuedCredentialDigest', CryptoJS.SHA256(credential).toString(CryptoJS.enc.Hex));",
                  "pm.environment.set('sdJwtIssuedStatusListUri', status.uri);",
                  "pm.environment.set('sdJwtIssuedStatusListIndex', String(issuedIndex));",
                  "pm.environment.set('sdJwtIssuedCredentialDigest', CryptoJS.SHA256(credential).toString(CryptoJS.enc.Hex));",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 01 JWT Token Status List + SD-JWT VC trusted pre-revoke verification",
          "description": "Stop here for a supported wallet/verifier checkpoint. Verify the just-issued dc+sd-jwt credential with the configured trust anchors. For the JWT profiles, provide a run-local JSON attestation in sdJwtTrustedVerificationAttestation. The trusted result must contain result=trusted, credentialDigest=the SHA-256 digest of this issued credential, runId, statusListUri, and statusListIndex. Reject missing, expired, malformed, wrong-type, untrusted, stale, and wrong-issuer credentials. The revoke preflight rejects absent or mismatched evidence; this collection has no generic inspector endpoint and must not claim this evidence automatically.",
          "item": []
        },
        {
          "name": "Revoke 01 JWT Token Status List + SD-JWT VC status entry",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"statusListIndex\": \"{{sdJwtIssuedStatusListIndex}}\",\n  \"value\": 1\n}"
            },
            "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{sdJwtStatusListId}}/status",
            "description": "Revoke the index extracted from this profile’s issued credential. The preflight binds the returned status URI, trusted credential identifier, and list id; a stale or mismatched issuance skips the mutation."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const createdUri = pm.variables.get('sdJwtStatusListUri') || pm.environment.get('sdJwtStatusListUri'); const issuedDigest = pm.variables.get('sdJwtIssuedCredentialDigest') || pm.environment.get('sdJwtIssuedCredentialDigest'); const publicationReady = (pm.variables.get('sdJwtStatusPublicationReady') || pm.environment.get('sdJwtStatusPublicationReady')) === 'true'; const attestationText = pm.variables.get('sdJwtTrustedVerificationAttestation') || pm.environment.get('sdJwtTrustedVerificationAttestation'); let attestation; try { attestation = JSON.parse(attestationText || ''); } catch { attestation = undefined; } const issuedUri = pm.variables.get('sdJwtIssuedStatusListUri') || pm.environment.get('sdJwtIssuedStatusListUri'); const issuedIndex = pm.variables.get('sdJwtIssuedStatusListIndex') || pm.environment.get('sdJwtIssuedStatusListIndex');",
                  "const issuedIndexNumber = Number(issuedIndex); const indexText = String(issuedIndex); const indexValid = ((typeof issuedIndex === 'number' && Number.isSafeInteger(issuedIndex)) || (typeof issuedIndex === 'string' && /^\\d+$/.test(indexText))) && issuedIndexNumber >= 0 && issuedIndexNumber < 131072;",
                  "const validAttestation = Boolean(publicationReady && issuedUri && issuedUri === createdUri && indexValid && issuedDigest && attestation && attestation.result === 'trusted' && attestation.credentialDigest === issuedDigest && attestation.runId === pm.environment.get('runId') && attestation.statusListUri === issuedUri && String(attestation.statusListIndex) === String(issuedIndex));",
                  "pm.test('trusted verification attestation is bound to this issuance', () => pm.expect(validAttestation, 'missing, stale, or mismatched trusted verification evidence').to.equal(true)); if (!validAttestation) { pm.execution.skipRequest(); }",
                  "if (validAttestation) { const statusRequestBody = JSON.parse(pm.request.body.raw); statusRequestBody.statusListIndex = issuedIndexNumber; pm.request.body.update(JSON.stringify(statusRequestBody)); }"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('status entry revoked', () => pm.expect(pm.response.code).to.equal(200));",
                  "const result = pm.response.json();",
                  "pm.expect(String(result.statusListId), 'returned list id').to.equal(pm.variables.get('sdJwtStatusListId'));",
                  "pm.expect(String(result.statusListIndex), 'returned index').to.equal(String(pm.variables.get('sdJwtIssuedStatusListIndex')));",
                  "pm.expect(result.value, 'returned status value').to.equal(1);"
                ]
              }
            }
          ]
        },
        {
          "name": "Refresh 01 JWT Token Status List + SD-JWT VC status list",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/statuslist+jwt"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{sdJwtStatusListUri}}",
            "description": "Fetch the exact statusListUri returned by createStatusList. This public request has no management bearer. Check content type, signature, freshness, hash, and the profile encoding."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['StatusPublicationReady', 'RefreshedStatusListHash'].forEach((suffix) => { pm.variables.unset('sdJwt' + suffix); pm.environment.unset('sdJwt' + suffix); });"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('public status publication served', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "pm.test('status publication has the declared media type', () => pm.expect(pm.response.headers.get('Content-Type') || '').to.include('application/statuslist+jwt'));",
                  "const publication = pm.response.text();",
                  "pm.expect(publication, 'non-empty signed status publication').to.not.be.empty;",
                  "const refreshedHash = CryptoJS.SHA256(publication).toString(CryptoJS.enc.Hex);",
                  "pm.expect(refreshedHash, 'fresh publication hash').to.not.equal(pm.variables.get('sdJwtInitialStatusListHash'));",
                  "pm.variables.set('sdJwtRefreshedStatusListHash', refreshedHash);",
                  "pm.environment.set('sdJwtRefreshedStatusListHash', refreshedHash);",
                  "const tokenParts = pm.response.text().split('.');",
                  "pm.expect(tokenParts.length, 'signed status JWT').to.equal(3);",
                  "const tokenPayloadPart = tokenParts[1].replace(/-/g, '+').replace(/_/g, '/');",
                  "const tokenPayload = JSON.parse(Buffer.from(tokenPayloadPart + '='.repeat((4 - tokenPayloadPart.length % 4) % 4), 'base64').toString('utf8'));",
                  "pm.expect(tokenPayload.iss, 'Token Status List issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(tokenPayload.sub, 'Token Status List subject').to.equal(pm.variables.get('sdJwtStatusListUri'));",
                  "pm.expect(Number.isSafeInteger(tokenPayload.iat), 'Token Status List iat').to.equal(true);",
                  "pm.expect(Number.isSafeInteger(tokenPayload.exp) && tokenPayload.exp > Math.floor(Date.now() / 1000), 'Token Status List expiry').to.equal(true);",
                  "pm.expect(tokenPayload.status_list, 'Token Status List envelope').to.be.an('object');",
                  "pm.expect(Number.isInteger(tokenPayload.status_list.bits) && [1, 2, 4, 8].includes(tokenPayload.status_list.bits), 'Token Status List bits').to.equal(true);",
                  "const encodedList = tokenPayload.status_list && tokenPayload.status_list.lst;",
                  "pm.expect(encodedList, 'encoded status list').to.be.a('string').and.not.empty;",
                  "const encodedValue = encodedList;",
                  "const encodedBytes = encodedValue.replace(/-/g, '+').replace(/_/g, '/');",
                  "const compressed = Buffer.from(encodedBytes + '='.repeat((4 - encodedBytes.length % 4) % 4), 'base64');",
                  "let bytes; try { const zlib = require('zlib'); bytes = zlib.inflateSync(compressed); } catch { bytes = undefined; }",
                  "const issuedIndex = Number(pm.variables.get('sdJwtIssuedStatusListIndex') || pm.environment.get('sdJwtIssuedStatusListIndex')); if (bytes) { const availableEntries = Math.floor(bytes.length * 8 / 1); pm.expect(Number.isSafeInteger(issuedIndex) && issuedIndex >= 0 && issuedIndex < availableEntries, 'issued status index is in range').to.equal(true);",
                  "const bitOffset = issuedIndex * 1; let statusValue = 0; for (let bit = 0; bit < 1; bit += 1) { const absolute = bitOffset + bit; const bitValue = (bytes[Math.floor(absolute / 8)] & (1 << (absolute % 8))) ? 1 : 0; statusValue = (statusValue | (bitValue << bit)); } pm.expect(statusValue, 'revoked status value').to.equal(1); } else if (pm.environment.get('stagedNewman') !== '1') { const evidenceText = pm.variables.get('sdJwtStatusListDecoderEvidence') || pm.environment.get('sdJwtStatusListDecoderEvidence'); let evidence; try { evidence = JSON.parse(evidenceText || ''); } catch { evidence = undefined; } pm.expect(evidence && evidence.result === 'decoded', 'supported local status decoder evidence').to.equal(true); pm.expect(evidence.credentialDigest, 'decoder credential binding').to.equal(pm.variables.get('sdJwtIssuedCredentialDigest')); pm.expect(evidence.runId, 'decoder run binding').to.equal(pm.environment.get('runId')); pm.expect(evidence.statusListUri, 'decoder URI binding').to.equal(pm.variables.get('sdJwtIssuedStatusListUri')); pm.expect(String(evidence.statusListIndex), 'decoder index binding').to.equal(String(issuedIndex)); pm.expect(evidence.publicationHash, 'decoded publication hash').to.equal(CryptoJS.SHA256(pm.response.text()).toString(CryptoJS.enc.Hex)); pm.expect(evidence.statusValue, 'decoded revoked status value').to.equal(1); pm.expect(evidence.revoked, 'decoded revoked bit').to.equal(true); }",
                  "pm.variables.set('sdJwtStatusPublicationReady', 'true'); pm.environment.set('sdJwtStatusPublicationReady', 'true');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 01 JWT Token Status List + SD-JWT VC post-revoke rejection",
          "description": "After the refresh request returns, use the supported wallet/verifier to present the same credential and place an ephemeral sdJwtPostRevokeRejectionEvidence JSON object in the run environment. It must contain result=rejected, a non-empty reason, credentialDigest, runId, statusListUri, statusListIndex, and publicationHash equal to the refreshed response hash. For mdoc, add mdocStatusDecoderEvidence with result=decoded, statusValue=1, and the same refreshed publicationHash after decoding that exact private refreshed CWT artifact. Validate those witnesses with the staged helper without fetching the publication again. No manually populated old index is sufficient, and no undocumented HTTP inspector is called. Remove the ephemeral evidence after the run.",
          "item": []
        }
      ]
    },
    {
      "name": "02 CWT Token Status List + ISO mDoc",
      "description": "02 CWT Token Status List + ISO mDoc lifecycle. The order is create the status list, fetch its exact returned public URI, create and resolve the offer, read issuer metadata, discover the authorization server, exchange the code, issue with a supplied wallet proof, perform the explicit trusted verification checkpoint, revoke the issued index, and refresh the same URI. The public media type is application/statuslist+cwt; signed content, freshness, hash change, status URI/index, and profile encoding are checked where a local decoder is available.  Cloud mutations, wallet proof, trust verification, and mdoc decoding remain explicit run-time boundaries.",
      "item": [
        {
          "name": "Create 02 CWT Token Status List + ISO mDoc status list",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"correlationId\": \"employee-mdoc-revocation\",\n  \"spec\": \"token_status_list\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"proofFormat\": \"cwt\",\n  \"hostingMode\": \"hosted\",\n  \"issuer\": \"https://issuer.example.com\",\n  \"signingKeyMode\": \"x5c\",\n  \"signingVerificationMethodId\": \"{{statusListVerificationMethodId}}\",\n  \"kmsResourceHandle\": \"{{statusListKmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"mdoc-status-signing\",\n  \"statusListUri\": \"{{tenantGatewayUrl}}/public/statuslists/employee-mdoc-revocation\",\n  \"length\": 256,\n  \"bitsPerStatus\": 1,\n  \"ttlSeconds\": 300,\n  \"validUntil\": \"{{mdocStatusListValidUntil}}\",\n  \"mdocProfile\": \"status_list\"\n}"
            },
            "url": "{{tenantStatusListApiBaseUrl}}/statuslists",
            "description": "Create the profile status publication. The response DTO is authoritative: retain its exact id and statusListUri."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.variables.unset('mdocStatusListId'); pm.environment.unset('mdocStatusListId');",
                  "pm.variables.unset('mdocStatusListUri'); pm.environment.unset('mdocStatusListUri');",
                  "pm.variables.unset('mdocStatusPublicationReady'); pm.environment.unset('mdocStatusPublicationReady');",
                  "pm.variables.unset('mdocInitialStatusListHash'); pm.environment.unset('mdocInitialStatusListHash');",
                  "pm.variables.unset('mdocRefreshedStatusListHash'); pm.environment.unset('mdocRefreshedStatusListHash');",
                  "pm.variables.unset('mdocIssuedStatusListUri'); pm.environment.unset('mdocIssuedStatusListUri');",
                  "pm.variables.unset('mdocIssuedStatusListIndex'); pm.environment.unset('mdocIssuedStatusListIndex');",
                  "pm.variables.unset('mdocIssuedCredential'); pm.environment.unset('mdocIssuedCredential');",
                  "pm.variables.unset('mdocIssuedCredentialDigest'); pm.environment.unset('mdocIssuedCredentialDigest');",
                  "pm.variables.unset('mdocTrustedVerificationAttestation'); pm.environment.unset('mdocTrustedVerificationAttestation');",
                  "pm.variables.unset('mdocPostRevokeRejectionEvidence'); pm.environment.unset('mdocPostRevokeRejectionEvidence');",
                  "pm.variables.unset('mdocStatusListDecoderEvidence'); pm.environment.unset('mdocStatusListDecoderEvidence');",
                  "pm.variables.unset('mdocInitialStatusDecoderEvidence'); pm.environment.unset('mdocInitialStatusDecoderEvidence');",
                  "pm.variables.unset('mdocInitialStatusDecoderEvidence'); pm.environment.unset('mdocInitialStatusDecoderEvidence'); pm.variables.unset('mdocStatusDecoderEvidence'); pm.environment.unset('mdocStatusDecoderEvidence');",
                  "const mdocStatusListValidUntil = new Date(Date.now() + 60 * 60 * 1000).toISOString(); pm.variables.set('mdocStatusListValidUntil', mdocStatusListValidUntil);"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = [200, 201].includes(pm.response.code);",
                  "pm.test('status list created', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "  const result = pm.response.json();",
                  "  pm.expect(result.id, 'StatusListResult.id').to.be.a('string').and.not.empty;",
                  "  pm.expect(result.statusListUri, 'StatusListResult.statusListUri').to.be.a('string').and.not.empty;",
                  "  pm.variables.set('mdocStatusListId', result.id);",
                  "  pm.variables.set('mdocStatusListUri', result.statusListUri);",
                  "  pm.environment.set('mdocStatusListId', result.id);",
                  "  pm.environment.set('mdocStatusListUri', result.statusListUri);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Fetch 02 CWT Token Status List + ISO mDoc status list",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/statuslist+cwt"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{mdocStatusListUri}}",
            "description": "Fetch the exact statusListUri returned by createStatusList. This public request has no management bearer. Check content type, signature, freshness, hash, and the profile encoding."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['StatusPublicationReady', 'InitialStatusListHash', 'RefreshedStatusListHash'].forEach((suffix) => { pm.variables.unset('mdoc' + suffix); pm.environment.unset('mdoc' + suffix); });"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('public status publication served', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "pm.test('status publication has the declared media type', () => pm.expect(pm.response.headers.get('Content-Type') || '').to.include('application/statuslist+cwt'));",
                  "const publication = pm.response.text();",
                  "pm.expect(publication, 'non-empty signed status publication').to.not.be.empty;",
                  "const hash = CryptoJS.SHA256(publication).toString(CryptoJS.enc.Hex);",
                  "pm.variables.set('mdocInitialStatusListHash', hash);",
                  "pm.environment.set('mdocInitialStatusListHash', hash);",
                  "pm.variables.set('mdocStatusPublicationReady', 'true'); pm.environment.set('mdocStatusPublicationReady', 'true');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 02 CWT Token Status List + ISO mDoc issuer status binding",
          "description": "Before creating the offer, configure the issuer credential configuration Mdl in the supported tenant configuration surface. Set credentials.[Mdl].status.statusListId to the exact mdocStatusListId returned by createStatusList and verify the corresponding root statuslists entry has the same public statusListUri (mdocStatusListUri). Confirm issuer metadata advertises this configuration and the same status publication before continuing. This collection has no generic status-binding endpoint; stop if the id, URI, configuration, or advertised status association differs.",
          "item": []
        },
        {
          "name": "Create 02 CWT Token Status List + ISO mDoc offer",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credential_configuration_ids\": [\n    \"Mdl\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {},\n  \"correlation_id\": \"mdoc-{{runId}}\"\n}"
            },
            "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
            "description": "Create an offer through the issuer backend DTO. The wallet resolves the returned offer_uri; this request does not fabricate a public grant URI."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('offer created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                  "const result = pm.response.json();",
                  "pm.expect(result.offer_uri, 'offer_uri').to.be.a('string').and.not.empty;",
                  "pm.expect(result.correlation_id, 'correlation_id').to.be.a('string').and.not.empty;",
                  "pm.variables.set('mdocOfferUri', result.offer_uri);",
                  "const offerMatch = result.offer_uri.match(/[?&]credential_offer_uri=([^&]+)/); pm.expect(offerMatch && offerMatch[1], 'credential_offer_uri').to.be.a('string').and.not.empty; pm.variables.set('mdocCredentialOfferUri', decodeURIComponent(offerMatch[1]));"
                ]
              }
            }
          ]
        },
        {
          "name": "Resolve 02 CWT Token Status List + ISO mDoc offer",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{mdocCredentialOfferUri}}",
            "description": "Resolve the offer as a wallet. Require the issuer, exact configuration id, and the canonical OID4VCI pre-authorized grant namespace."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('offer resolved', () => pm.response.to.have.status(200));",
                  "const offer = pm.response.json();",
                  "pm.expect(offer.credential_issuer, 'credential_issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(offer.credential_configuration_ids, 'credential_configuration_ids').to.include('Mdl');",
                  "const grant = offer.grants && offer.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'];",
                  "pm.expect(grant, 'canonical pre-authorized grant').to.be.an('object');",
                  "pm.expect(grant['pre-authorized_code'], 'pre-authorized_code').to.be.a('string').and.not.empty;",
                  "pm.variables.set('mdocCredentialIssuer', offer.credential_issuer);",
                  "pm.variables.set('mdocPreAuthCode', grant['pre-authorized_code']);"
                ]
              }
            }
          ]
        },
        {
          "name": "Fetch 02 CWT Token Status List + ISO mDoc issuer metadata",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{tenantIssuerMetadataUrl}}",
            "description": "Read the exact issuer metadata URL supplied by the approved tenant bootstrap. Use its advertised credential_endpoint and authorization_servers; no well-known path is invented from a host name."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('issuer metadata served', () => pm.response.to.have.status(200));",
                  "const metadata = pm.response.json();",
                  "pm.expect(metadata.credential_issuer, 'metadata credential_issuer').to.equal(pm.variables.get('mdocCredentialIssuer'));",
                  "pm.expect(metadata.credential_endpoint, 'metadata credential_endpoint').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.authorization_servers, 'metadata authorization_servers').to.be.an('array').and.not.empty;",
                  "const profile = metadata.credential_configurations_supported && metadata.credential_configurations_supported['Mdl'];",
                  "pm.expect(profile, 'advertised credential configuration').to.be.an('object');",
                  "pm.expect(profile.format, 'credential format').to.equal('mso_mdoc');",
                  "pm.variables.set('mdocCredentialEndpoint', metadata.credential_endpoint);",
                  "pm.variables.set('mdocAuthorizationServer', metadata.authorization_servers[0]);"
                ]
              }
            }
          ]
        },
        {
          "name": "Discover 02 CWT Token Status List + ISO mDoc authorization server",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{tenantGatewayUrl}}/.well-known/oauth-authorization-server",
            "description": "Discover the authorization server at the tenant well-known endpoint and retain the advertised token_endpoint. The collection never appends /token."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('authorization server metadata served', () => pm.response.to.have.status(200));",
                  "const metadata = pm.response.json();",
                  "pm.expect(metadata.issuer, 'authorization-server issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.token_endpoint, 'advertised token_endpoint').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.issuer, 'issuer matches credential metadata').to.equal(pm.variables.get('mdocAuthorizationServer'));",
                  "pm.variables.set('mdocTokenEndpoint', metadata.token_endpoint);"
                ]
              }
            }
          ]
        },
        {
          "name": "Exchange 02 CWT Token Status List + ISO mDoc pre-authorized code",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/x-www-form-urlencoded"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
                },
                {
                  "key": "pre-authorized_code",
                  "value": "{{mdocPreAuthCode}}"
                }
              ]
            },
            "url": "{{mdocTokenEndpoint}}",
            "description": "Exchange the offer-derived code at the token_endpoint advertised by authorization-server discovery. Keep the access token in run-local variables only."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('token exchanged', () => pm.response.to.have.status(200));",
                  "const tokenResponse = pm.response.json();",
                  "pm.expect(tokenResponse.access_token, 'access_token').to.be.a('string').and.not.empty;",
                  "pm.expect(tokenResponse.authorization_details, 'authorization_details').to.be.an('array').and.not.empty;",
                  "const authorization = tokenResponse.authorization_details.find((entry) => entry.type === 'openid_credential' && entry.credential_configuration_id === 'Mdl');",
                  "pm.expect(authorization, 'profile authorization detail').to.be.an('object');",
                  "pm.expect(authorization.credential_identifiers, 'credential_identifiers').to.be.an('array').and.not.empty;",
                  "pm.variables.set('mdocAccessToken', tokenResponse.access_token);",
                  "pm.variables.set('mdocCredentialIdentifier', authorization.credential_identifiers[0]);"
                ]
              }
            }
          ]
        },
        {
          "name": "Issue 02 CWT Token Status List + ISO mDoc",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{mdocAccessToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credential_identifier\": \"{{mdocCredentialIdentifier}}\",\n  \"proofs\": {\n    \"jwt\": [\n      \"{{mdocProofJwt}}\"\n    ]\n  }\n}"
            },
            "url": "{{mdocCredentialEndpoint}}",
            "description": "Issue the mso_mdoc credential using the profile credential identifier returned in authorization_details. Supply a real wallet proof at run time; no proof or identifier is fabricated here."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['IssuedStatusListUri', 'IssuedStatusListIndex', 'IssuedCredential', 'IssuedCredentialDigest', 'TrustedVerificationAttestation'].forEach((suffix) => { pm.variables.unset('mdoc' + suffix); pm.environment.unset('mdoc' + suffix); });",
                  "pm.variables.unset('mdocInitialStatusDecoderEvidence'); pm.environment.unset('mdocInitialStatusDecoderEvidence'); pm.variables.unset('mdocStatusDecoderEvidence'); pm.environment.unset('mdocStatusDecoderEvidence');",
                  "const issuanceReady = Boolean(pm.variables.get('mdocAccessToken') && pm.variables.get('mdocCredentialIdentifier') && (pm.variables.get('mdocProofJwt') || pm.environment.get('mdocProofJwt')));",
                  "pm.test('issuance inputs are present', () => pm.expect(issuanceReady, 'access token, profile credential identifier, and run-time proof are required').to.equal(true));",
                  "if (!issuanceReady) { pm.execution.skipRequest(); }"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('credential issued', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "const response = pm.response.json();",
                  "const credential = response.credentials && response.credentials[0] && response.credentials[0].credential;",
                  "pm.expect(credential, 'issued credential').to.be.a('string').and.not.empty;",
                  "pm.variables.set('mdocIssuedCredential', credential);",
                  "pm.variables.set('mdocIssuedCredentialDigest', CryptoJS.SHA256(credential).toString(CryptoJS.enc.Hex)); pm.environment.set('mdocIssuedCredentialDigest', CryptoJS.SHA256(credential).toString(CryptoJS.enc.Hex));",
                  "pm.expect(credential, 'mdoc is retained for the explicit decoder checkpoint').to.be.a('string').and.not.empty;",
                  "pm.environment.set('mdocIssuedCredentialDigest', CryptoJS.SHA256(credential).toString(CryptoJS.enc.Hex));",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 02 CWT Token Status List + ISO mDoc trusted pre-revoke verification",
          "description": "Stop here for a supported wallet/verifier checkpoint. Verify the just-issued mso_mdoc credential with the configured trust anchors. For mso_mdoc, use the private initial CWT publication handed off after prepare and the same issued credential handed off after issue; pass both to the approved local CBOR/COSE decoder and place a JSON result with result=decoded, statusValue=0, the issued credentialDigest, runId, statusListUri, statusListIndex, and initial publicationHash in mdocInitialStatusDecoderEvidence before resuming. The trusted result must contain result=trusted, credentialDigest=the SHA-256 digest of this issued credential, runId, statusListUri, and statusListIndex. Reject missing, expired, malformed, wrong-type, untrusted, stale, and wrong-issuer credentials. The revoke preflight rejects absent or mismatched evidence; this collection has no generic inspector endpoint and must not claim this evidence automatically.",
          "item": []
        },
        {
          "name": "Revoke 02 CWT Token Status List + ISO mDoc status entry",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"statusListIndex\": \"{{mdocIssuedStatusListIndex}}\",\n  \"value\": 1\n}"
            },
            "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{mdocStatusListId}}/status",
            "description": "Revoke the index extracted from this profile’s issued credential. The preflight binds the returned status URI, trusted credential identifier, and list id; a stale or mismatched issuance skips the mutation."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const createdUri = pm.variables.get('mdocStatusListUri') || pm.environment.get('mdocStatusListUri'); const issuedDigest = pm.variables.get('mdocIssuedCredentialDigest') || pm.environment.get('mdocIssuedCredentialDigest'); const publicationReady = (pm.variables.get('mdocStatusPublicationReady') || pm.environment.get('mdocStatusPublicationReady')) === 'true'; const attestationText = pm.variables.get('mdocTrustedVerificationAttestation') || pm.environment.get('mdocTrustedVerificationAttestation'); let attestation; try { attestation = JSON.parse(attestationText || ''); } catch { attestation = undefined; } const decoderText = pm.variables.get('mdocInitialStatusDecoderEvidence') || pm.environment.get('mdocInitialStatusDecoderEvidence'); let decoder; try { decoder = JSON.parse(decoderText || ''); } catch { decoder = undefined; } const issuedUri = decoder && decoder.statusListUri; const issuedIndex = decoder && decoder.statusListIndex; const decoderBound = Boolean(decoder && decoder.result === 'decoded' && decoder.credentialDigest === issuedDigest && decoder.runId === pm.environment.get('runId') && issuedUri === createdUri && decoder.publicationHash === (pm.variables.get('mdocInitialStatusListHash') || pm.environment.get('mdocInitialStatusListHash')) && decoder.statusValue === 0); if (decoderBound) { pm.variables.set('mdocIssuedStatusListUri', issuedUri); pm.variables.set('mdocIssuedStatusListIndex', String(issuedIndex)); pm.environment.set('mdocIssuedStatusListUri', issuedUri); pm.environment.set('mdocIssuedStatusListIndex', String(issuedIndex)); }",
                  "const issuedIndexNumber = Number(issuedIndex); const indexText = String(issuedIndex); const indexValid = ((typeof issuedIndex === 'number' && Number.isSafeInteger(issuedIndex)) || (typeof issuedIndex === 'string' && /^\\d+$/.test(indexText))) && issuedIndexNumber >= 0 && issuedIndexNumber < 256;",
                  "const validAttestation = Boolean(publicationReady && issuedUri && issuedUri === createdUri && indexValid && issuedDigest && attestation && attestation.result === 'trusted' && attestation.credentialDigest === issuedDigest && attestation.runId === pm.environment.get('runId') && attestation.statusListUri === issuedUri && String(attestation.statusListIndex) === String(issuedIndex) && decoderBound);",
                  "pm.test('trusted verification attestation is bound to this issuance', () => pm.expect(validAttestation, 'missing, stale, or mismatched trusted verification evidence').to.equal(true)); if (!validAttestation) { pm.execution.skipRequest(); }",
                  "if (validAttestation) { const statusRequestBody = JSON.parse(pm.request.body.raw); statusRequestBody.statusListIndex = issuedIndexNumber; pm.request.body.update(JSON.stringify(statusRequestBody)); }"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('status entry revoked', () => pm.expect(pm.response.code).to.equal(200));",
                  "const result = pm.response.json();",
                  "pm.expect(String(result.statusListId), 'returned list id').to.equal(pm.variables.get('mdocStatusListId'));",
                  "pm.expect(String(result.statusListIndex), 'returned index').to.equal(String(pm.variables.get('mdocIssuedStatusListIndex')));",
                  "pm.expect(result.value, 'returned status value').to.equal(1);"
                ]
              }
            }
          ]
        },
        {
          "name": "Refresh 02 CWT Token Status List + ISO mDoc status list",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/statuslist+cwt"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{mdocStatusListUri}}",
            "description": "Fetch the exact statusListUri returned by createStatusList. This public request has no management bearer. Check content type, signature, freshness, hash, and the profile encoding."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['StatusPublicationReady', 'RefreshedStatusListHash'].forEach((suffix) => { pm.variables.unset('mdoc' + suffix); pm.environment.unset('mdoc' + suffix); });"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('public status publication served', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "pm.test('status publication has the declared media type', () => pm.expect(pm.response.headers.get('Content-Type') || '').to.include('application/statuslist+cwt'));",
                  "const publication = pm.response.text();",
                  "pm.expect(publication, 'non-empty signed status publication').to.not.be.empty;",
                  "const refreshedHash = CryptoJS.SHA256(publication).toString(CryptoJS.enc.Hex);",
                  "pm.expect(refreshedHash, 'fresh publication hash').to.not.equal(pm.variables.get('mdocInitialStatusListHash'));",
                  "pm.variables.set('mdocRefreshedStatusListHash', refreshedHash);",
                  "pm.environment.set('mdocRefreshedStatusListHash', refreshedHash);",
                  "const rawHash = CryptoJS.SHA256(pm.response.text()).toString(CryptoJS.enc.Hex); pm.variables.set('mdocRefreshedStatusListHash', rawHash); pm.environment.set('mdocRefreshedStatusListHash', rawHash);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 02 CWT Token Status List + ISO mDoc post-revoke rejection",
          "description": "After the refresh request returns, use the supported wallet/verifier to present the same credential and place an ephemeral mdocPostRevokeRejectionEvidence JSON object in the run environment. It must contain result=rejected, a non-empty reason, credentialDigest, runId, statusListUri, statusListIndex, and publicationHash equal to the refreshed response hash. For mdoc, add mdocStatusDecoderEvidence with result=decoded, statusValue=1, and the same refreshed publicationHash after decoding that exact private refreshed CWT artifact. Validate those witnesses with the staged helper without fetching the publication again. No manually populated old index is sufficient, and no undocumented HTTP inspector is called. Remove the ephemeral evidence after the run.",
          "item": []
        }
      ]
    },
    {
      "name": "03 W3C VCDM 1.1 + Bitstring Status List",
      "description": "03 W3C VCDM 1.1 + Bitstring Status List lifecycle. The order is create the status list, fetch its exact returned public URI, create and resolve the offer, read issuer metadata, discover the authorization server, exchange the code, issue with a supplied wallet proof, perform the explicit trusted verification checkpoint, revoke the issued index, and refresh the same URI. The public media type is application/vc+jwt; signed content, freshness, hash change, status URI/index, and profile encoding are checked where a local decoder is available. The current runtime vocabulary is BitstringStatusListEntry with the revocation status purpose. Cloud mutations, wallet proof, trust verification, and mdoc decoding remain explicit run-time boundaries.",
      "item": [
        {
          "name": "Create 03 W3C VCDM 1.1 + Bitstring Status List status list",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"correlationId\": \"employee-vcdm-11-revocation\",\n  \"spec\": \"bitstring_status_list\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"proofFormat\": \"vc+jwt\",\n  \"hostingMode\": \"hosted\",\n  \"issuer\": \"did:web:issuer.example.com\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"{{statusListVerificationMethodId}}\",\n  \"kmsResourceHandle\": \"{{statusListKmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"employee-vcdm-11-signing\",\n  \"statusListUri\": \"{{tenantGatewayUrl}}/public/statuslists/employee-vcdm-11-revocation\",\n  \"length\": 131072,\n  \"bitsPerStatus\": 1,\n  \"ttlSeconds\": 300\n}"
            },
            "url": "{{tenantStatusListApiBaseUrl}}/statuslists",
            "description": "Create the profile status publication. The response DTO is authoritative: retain its exact id and statusListUri."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.variables.unset('vcdm11StatusListId'); pm.environment.unset('vcdm11StatusListId');",
                  "pm.variables.unset('vcdm11StatusListUri'); pm.environment.unset('vcdm11StatusListUri');",
                  "pm.variables.unset('vcdm11StatusPublicationReady'); pm.environment.unset('vcdm11StatusPublicationReady');",
                  "pm.variables.unset('vcdm11InitialStatusListHash'); pm.environment.unset('vcdm11InitialStatusListHash');",
                  "pm.variables.unset('vcdm11RefreshedStatusListHash'); pm.environment.unset('vcdm11RefreshedStatusListHash');",
                  "pm.variables.unset('vcdm11IssuedStatusListUri'); pm.environment.unset('vcdm11IssuedStatusListUri');",
                  "pm.variables.unset('vcdm11IssuedStatusListIndex'); pm.environment.unset('vcdm11IssuedStatusListIndex');",
                  "pm.variables.unset('vcdm11IssuedCredential'); pm.environment.unset('vcdm11IssuedCredential');",
                  "pm.variables.unset('vcdm11IssuedCredentialDigest'); pm.environment.unset('vcdm11IssuedCredentialDigest');",
                  "pm.variables.unset('vcdm11TrustedVerificationAttestation'); pm.environment.unset('vcdm11TrustedVerificationAttestation');",
                  "pm.variables.unset('vcdm11PostRevokeRejectionEvidence'); pm.environment.unset('vcdm11PostRevokeRejectionEvidence');",
                  "pm.variables.unset('vcdm11StatusListDecoderEvidence'); pm.environment.unset('vcdm11StatusListDecoderEvidence');"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = [200, 201].includes(pm.response.code);",
                  "pm.test('status list created', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "  const result = pm.response.json();",
                  "  pm.expect(result.id, 'StatusListResult.id').to.be.a('string').and.not.empty;",
                  "  pm.expect(result.statusListUri, 'StatusListResult.statusListUri').to.be.a('string').and.not.empty;",
                  "  pm.variables.set('vcdm11StatusListId', result.id);",
                  "  pm.variables.set('vcdm11StatusListUri', result.statusListUri);",
                  "  pm.environment.set('vcdm11StatusListId', result.id);",
                  "  pm.environment.set('vcdm11StatusListUri', result.statusListUri);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Fetch 03 W3C VCDM 1.1 + Bitstring Status List status list",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/vc+jwt"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{vcdm11StatusListUri}}",
            "description": "Fetch the exact statusListUri returned by createStatusList. This public request has no management bearer. Check content type, signature, freshness, hash, and the profile encoding."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['StatusPublicationReady', 'InitialStatusListHash', 'RefreshedStatusListHash'].forEach((suffix) => { pm.variables.unset('vcdm11' + suffix); pm.environment.unset('vcdm11' + suffix); });"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('public status publication served', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "pm.test('status publication has the declared media type', () => pm.expect(pm.response.headers.get('Content-Type') || '').to.include('application/vc+jwt'));",
                  "const publication = pm.response.text();",
                  "pm.expect(publication, 'non-empty signed status publication').to.not.be.empty;",
                  "const hash = CryptoJS.SHA256(publication).toString(CryptoJS.enc.Hex);",
                  "pm.variables.set('vcdm11InitialStatusListHash', hash);",
                  "pm.environment.set('vcdm11InitialStatusListHash', hash);",
                  "const tokenParts = pm.response.text().split('.');",
                  "pm.expect(tokenParts.length, 'signed status JWT').to.equal(3);",
                  "const tokenPayloadPart = tokenParts[1].replace(/-/g, '+').replace(/_/g, '/');",
                  "const tokenPayload = JSON.parse(Buffer.from(tokenPayloadPart + '='.repeat((4 - tokenPayloadPart.length % 4) % 4), 'base64').toString('utf8'));",
                  "pm.expect(tokenPayload['@context'], 'W3C status context').to.be.an('array').and.to.include('https://www.w3.org/ns/credentials/v2');",
                  "pm.expect(tokenPayload['@context'], 'W3C status vocabulary').to.include('https://www.w3.org/ns/credentials/status/v1');",
                  "pm.expect(tokenPayload.type, 'W3C status type').to.be.an('array').and.to.include('VerifiableCredential');",
                  "pm.expect(tokenPayload.type, 'W3C status type').to.include('BitstringStatusListCredential');",
                  "const subject = tokenPayload.credentialSubject; pm.expect(subject, 'W3C credentialSubject').to.be.an('object');",
                  "pm.expect(subject.id, 'W3C status subject id').to.equal(pm.variables.get('vcdm11StatusListUri') + '#list');",
                  "pm.expect(subject.type, 'W3C status subject type').to.equal('BitstringStatusList');",
                  "pm.expect(subject.statusPurpose, 'W3C status purpose').to.equal('revocation');",
                  "pm.expect(Number(subject.statusSize || 1), 'statusSize').to.equal(1);",
                  "pm.expect(Date.parse(tokenPayload.validFrom), 'W3C validFrom').to.be.at.most(Date.now());",
                  "if (tokenPayload.validUntil !== undefined) pm.expect(Date.parse(tokenPayload.validUntil), 'W3C validUntil').to.be.greaterThan(Date.now());",
                  "const structuralEncoded = subject.encodedList; pm.expect(structuralEncoded, 'W3C encodedList').to.be.a('string').and.not.empty; pm.expect(structuralEncoded[0], 'W3C multibase base64url marker').to.equal('u');",
                  "pm.variables.set('vcdm11StatusPublicationReady', 'true'); pm.environment.set('vcdm11StatusPublicationReady', 'true');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Create VCDM 1.1 credential design",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credentialType\": {\n    \"format\": \"W3C_VC\",\n    \"type\": \"UniversityDegreeCredential\",\n    \"@context\": \"https://www.w3.org/2018/credentials/v1\"\n  },\n  \"bindings\": [\n    {\n      \"type\": \"UniversityDegreeCredential\",\n      \"@context\": \"https://www.w3.org/2018/credentials/v1\",\n      \"credentialConfigurationId\": \"Vcdm11Jwt\"\n    }\n  ],\n  \"alias\": \"EmployeeCredentialV11\",\n  \"hostingMode\": \"LOCAL\"\n}"
            },
            "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials",
            "description": "Create the VCDM 1.1 design before its offer. The binding id and context match the issuer configuration used by this profile."
          }
        },
        {
          "name": "Manual 03 W3C VCDM 1.1 + Bitstring Status List issuer status binding",
          "description": "Before creating the offer, configure the issuer credential configuration Vcdm11Jwt in the supported tenant configuration surface. Set credentials.[Vcdm11Jwt].status.statusListId to the exact vcdm11StatusListId returned by createStatusList and verify the corresponding root statuslists entry has the same public statusListUri (vcdm11StatusListUri). Confirm issuer metadata advertises this configuration and the same status publication before continuing. This collection has no generic status-binding endpoint; stop if the id, URI, configuration, or advertised status association differs.",
          "item": []
        },
        {
          "name": "Create 03 W3C VCDM 1.1 + Bitstring Status List offer",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credential_configuration_ids\": [\n    \"Vcdm11Jwt\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"id\": \"did:example:alice\",\n    \"type\": \"UniversityDegreeCredential\",\n    \"name\": \"Alice\"\n  },\n  \"correlation_id\": \"vcdm11-{{runId}}\"\n}"
            },
            "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
            "description": "Create an offer through the issuer backend DTO. The wallet resolves the returned offer_uri; this request does not fabricate a public grant URI."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('offer created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                  "const result = pm.response.json();",
                  "pm.expect(result.offer_uri, 'offer_uri').to.be.a('string').and.not.empty;",
                  "pm.expect(result.correlation_id, 'correlation_id').to.be.a('string').and.not.empty;",
                  "pm.variables.set('vcdm11OfferUri', result.offer_uri);",
                  "const offerMatch = result.offer_uri.match(/[?&]credential_offer_uri=([^&]+)/); pm.expect(offerMatch && offerMatch[1], 'credential_offer_uri').to.be.a('string').and.not.empty; pm.variables.set('vcdm11CredentialOfferUri', decodeURIComponent(offerMatch[1]));"
                ]
              }
            }
          ]
        },
        {
          "name": "Resolve 03 W3C VCDM 1.1 + Bitstring Status List offer",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{vcdm11CredentialOfferUri}}",
            "description": "Resolve the offer as a wallet. Require the issuer, exact configuration id, and the canonical OID4VCI pre-authorized grant namespace."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('offer resolved', () => pm.response.to.have.status(200));",
                  "const offer = pm.response.json();",
                  "pm.expect(offer.credential_issuer, 'credential_issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(offer.credential_configuration_ids, 'credential_configuration_ids').to.include('Vcdm11Jwt');",
                  "const grant = offer.grants && offer.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'];",
                  "pm.expect(grant, 'canonical pre-authorized grant').to.be.an('object');",
                  "pm.expect(grant['pre-authorized_code'], 'pre-authorized_code').to.be.a('string').and.not.empty;",
                  "pm.variables.set('vcdm11CredentialIssuer', offer.credential_issuer);",
                  "pm.variables.set('vcdm11PreAuthCode', grant['pre-authorized_code']);"
                ]
              }
            }
          ]
        },
        {
          "name": "Fetch 03 W3C VCDM 1.1 + Bitstring Status List issuer metadata",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{tenantIssuerMetadataUrl}}",
            "description": "Read the exact issuer metadata URL supplied by the approved tenant bootstrap. Use its advertised credential_endpoint and authorization_servers; no well-known path is invented from a host name."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('issuer metadata served', () => pm.response.to.have.status(200));",
                  "const metadata = pm.response.json();",
                  "pm.expect(metadata.credential_issuer, 'metadata credential_issuer').to.equal(pm.variables.get('vcdm11CredentialIssuer'));",
                  "pm.expect(metadata.credential_endpoint, 'metadata credential_endpoint').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.authorization_servers, 'metadata authorization_servers').to.be.an('array').and.not.empty;",
                  "const profile = metadata.credential_configurations_supported && metadata.credential_configurations_supported['Vcdm11Jwt'];",
                  "pm.expect(profile, 'advertised credential configuration').to.be.an('object');",
                  "pm.expect(profile.format, 'credential format').to.equal('jwt_vc_json');",
                  "pm.variables.set('vcdm11CredentialEndpoint', metadata.credential_endpoint);",
                  "pm.variables.set('vcdm11AuthorizationServer', metadata.authorization_servers[0]);"
                ]
              }
            }
          ]
        },
        {
          "name": "Discover 03 W3C VCDM 1.1 + Bitstring Status List authorization server",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{tenantGatewayUrl}}/.well-known/oauth-authorization-server",
            "description": "Discover the authorization server at the tenant well-known endpoint and retain the advertised token_endpoint. The collection never appends /token."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('authorization server metadata served', () => pm.response.to.have.status(200));",
                  "const metadata = pm.response.json();",
                  "pm.expect(metadata.issuer, 'authorization-server issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.token_endpoint, 'advertised token_endpoint').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.issuer, 'issuer matches credential metadata').to.equal(pm.variables.get('vcdm11AuthorizationServer'));",
                  "pm.variables.set('vcdm11TokenEndpoint', metadata.token_endpoint);"
                ]
              }
            }
          ]
        },
        {
          "name": "Exchange 03 W3C VCDM 1.1 + Bitstring Status List pre-authorized code",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/x-www-form-urlencoded"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
                },
                {
                  "key": "pre-authorized_code",
                  "value": "{{vcdm11PreAuthCode}}"
                }
              ]
            },
            "url": "{{vcdm11TokenEndpoint}}",
            "description": "Exchange the offer-derived code at the token_endpoint advertised by authorization-server discovery. Keep the access token in run-local variables only."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('token exchanged', () => pm.response.to.have.status(200));",
                  "const tokenResponse = pm.response.json();",
                  "pm.expect(tokenResponse.access_token, 'access_token').to.be.a('string').and.not.empty;",
                  "pm.expect(tokenResponse.authorization_details, 'authorization_details').to.be.an('array').and.not.empty;",
                  "const authorization = tokenResponse.authorization_details.find((entry) => entry.type === 'openid_credential' && entry.credential_configuration_id === 'Vcdm11Jwt');",
                  "pm.expect(authorization, 'profile authorization detail').to.be.an('object');",
                  "pm.expect(authorization.credential_identifiers, 'credential_identifiers').to.be.an('array').and.not.empty;",
                  "pm.variables.set('vcdm11AccessToken', tokenResponse.access_token);",
                  "pm.variables.set('vcdm11CredentialIdentifier', authorization.credential_identifiers[0]);"
                ]
              }
            }
          ]
        },
        {
          "name": "Issue 03 W3C VCDM 1.1 + Bitstring Status List",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{vcdm11AccessToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credential_identifier\": \"{{vcdm11CredentialIdentifier}}\",\n  \"proofs\": {\n    \"jwt\": [\n      \"{{vcdm11ProofJwt}}\"\n    ]\n  }\n}"
            },
            "url": "{{vcdm11CredentialEndpoint}}",
            "description": "Issue the jwt_vc_json credential using the profile credential identifier returned in authorization_details. Supply a real wallet proof at run time; no proof or identifier is fabricated here."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['IssuedStatusListUri', 'IssuedStatusListIndex', 'IssuedCredential', 'IssuedCredentialDigest', 'TrustedVerificationAttestation'].forEach((suffix) => { pm.variables.unset('vcdm11' + suffix); pm.environment.unset('vcdm11' + suffix); });",
                  "const issuanceReady = Boolean(pm.variables.get('vcdm11AccessToken') && pm.variables.get('vcdm11CredentialIdentifier') && (pm.variables.get('vcdm11ProofJwt') || pm.environment.get('vcdm11ProofJwt')));",
                  "pm.test('issuance inputs are present', () => pm.expect(issuanceReady, 'access token, profile credential identifier, and run-time proof are required').to.equal(true));",
                  "if (!issuanceReady) { pm.execution.skipRequest(); }"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('credential issued', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "const response = pm.response.json();",
                  "const credential = response.credentials && response.credentials[0] && response.credentials[0].credential;",
                  "pm.expect(credential, 'issued credential').to.be.a('string').and.not.empty;",
                  "pm.variables.set('vcdm11IssuedCredential', credential);",
                  "const parts = credential.split('~')[0].split('.');",
                  "pm.expect(parts.length, 'compact JWT payload').to.be.greaterThan(1);",
                  "const encoded = parts[1].replace(/-/g, '+').replace(/_/g, '/');",
                  "const padded = encoded + '='.repeat((4 - encoded.length % 4) % 4);",
                  "const payload = JSON.parse(Buffer.from(padded, 'base64').toString('utf8'));",
                  "pm.expect(payload.vc && payload.vc['@context'], 'VCDM 1.1 context').to.include('https://www.w3.org/2018/credentials/v1');",
                  "pm.expect(payload.vc && payload.vc.type, 'VCDM 1.1 type').to.include('UniversityDegreeCredential');",
                  "pm.expect((payload.vc && payload.vc.credentialStatus || {}).type, 'BitstringStatusListEntry type').to.equal('BitstringStatusListEntry');",
                  "const status = payload.vc && payload.vc.credentialStatus;",
                  "pm.expect(status, 'issued credential status').to.be.an('object');",
                  "pm.expect(status.statusListCredential, 'issued status URI').to.be.a('string').and.not.empty;",
                  "const rawIssuedIndex = status.statusListIndex; const issuedIndex = Number(rawIssuedIndex); const validIssuedIndex = (typeof rawIssuedIndex === 'number' && Number.isSafeInteger(rawIssuedIndex)) || (typeof rawIssuedIndex === 'string' && /^\\d+$/.test(rawIssuedIndex)); pm.expect(validIssuedIndex && issuedIndex >= 0 && issuedIndex < 131072, 'issued status index must be a non-negative in-range integer').to.equal(true);",
                  "pm.variables.set('vcdm11IssuedStatusListUri', status.statusListCredential);",
                  "pm.variables.set('vcdm11IssuedStatusListIndex', String(issuedIndex));",
                  "pm.variables.set('vcdm11IssuedCredentialDigest', CryptoJS.SHA256(credential).toString(CryptoJS.enc.Hex));",
                  "pm.environment.set('vcdm11IssuedStatusListUri', status.statusListCredential);",
                  "pm.environment.set('vcdm11IssuedStatusListIndex', String(issuedIndex));",
                  "pm.environment.set('vcdm11IssuedCredentialDigest', CryptoJS.SHA256(credential).toString(CryptoJS.enc.Hex));",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 03 W3C VCDM 1.1 + Bitstring Status List trusted pre-revoke verification",
          "description": "Stop here for a supported wallet/verifier checkpoint. Verify the just-issued jwt_vc_json credential with the configured trust anchors. For the JWT profiles, provide a run-local JSON attestation in vcdm11TrustedVerificationAttestation. The trusted result must contain result=trusted, credentialDigest=the SHA-256 digest of this issued credential, runId, statusListUri, and statusListIndex. Reject missing, expired, malformed, wrong-type, untrusted, stale, and wrong-issuer credentials. The revoke preflight rejects absent or mismatched evidence; this collection has no generic inspector endpoint and must not claim this evidence automatically.",
          "item": []
        },
        {
          "name": "Revoke 03 W3C VCDM 1.1 + Bitstring Status List status entry",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"statusListIndex\": \"{{vcdm11IssuedStatusListIndex}}\",\n  \"value\": 1\n}"
            },
            "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{vcdm11StatusListId}}/status",
            "description": "Revoke the index extracted from this profile’s issued credential. The preflight binds the returned status URI, trusted credential identifier, and list id; a stale or mismatched issuance skips the mutation."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const createdUri = pm.variables.get('vcdm11StatusListUri') || pm.environment.get('vcdm11StatusListUri'); const issuedDigest = pm.variables.get('vcdm11IssuedCredentialDigest') || pm.environment.get('vcdm11IssuedCredentialDigest'); const publicationReady = (pm.variables.get('vcdm11StatusPublicationReady') || pm.environment.get('vcdm11StatusPublicationReady')) === 'true'; const attestationText = pm.variables.get('vcdm11TrustedVerificationAttestation') || pm.environment.get('vcdm11TrustedVerificationAttestation'); let attestation; try { attestation = JSON.parse(attestationText || ''); } catch { attestation = undefined; } const issuedUri = pm.variables.get('vcdm11IssuedStatusListUri') || pm.environment.get('vcdm11IssuedStatusListUri'); const issuedIndex = pm.variables.get('vcdm11IssuedStatusListIndex') || pm.environment.get('vcdm11IssuedStatusListIndex');",
                  "const issuedIndexNumber = Number(issuedIndex); const indexText = String(issuedIndex); const indexValid = ((typeof issuedIndex === 'number' && Number.isSafeInteger(issuedIndex)) || (typeof issuedIndex === 'string' && /^\\d+$/.test(indexText))) && issuedIndexNumber >= 0 && issuedIndexNumber < 131072;",
                  "const validAttestation = Boolean(publicationReady && issuedUri && issuedUri === createdUri && indexValid && issuedDigest && attestation && attestation.result === 'trusted' && attestation.credentialDigest === issuedDigest && attestation.runId === pm.environment.get('runId') && attestation.statusListUri === issuedUri && String(attestation.statusListIndex) === String(issuedIndex));",
                  "pm.test('trusted verification attestation is bound to this issuance', () => pm.expect(validAttestation, 'missing, stale, or mismatched trusted verification evidence').to.equal(true)); if (!validAttestation) { pm.execution.skipRequest(); }",
                  "if (validAttestation) { const statusRequestBody = JSON.parse(pm.request.body.raw); statusRequestBody.statusListIndex = issuedIndexNumber; pm.request.body.update(JSON.stringify(statusRequestBody)); }"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('status entry revoked', () => pm.expect(pm.response.code).to.equal(200));",
                  "const result = pm.response.json();",
                  "pm.expect(String(result.statusListId), 'returned list id').to.equal(pm.variables.get('vcdm11StatusListId'));",
                  "pm.expect(String(result.statusListIndex), 'returned index').to.equal(String(pm.variables.get('vcdm11IssuedStatusListIndex')));",
                  "pm.expect(result.value, 'returned status value').to.equal(1);"
                ]
              }
            }
          ]
        },
        {
          "name": "Refresh 03 W3C VCDM 1.1 + Bitstring Status List status list",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/vc+jwt"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{vcdm11StatusListUri}}",
            "description": "Fetch the exact statusListUri returned by createStatusList. This public request has no management bearer. Check content type, signature, freshness, hash, and the profile encoding."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['StatusPublicationReady', 'RefreshedStatusListHash'].forEach((suffix) => { pm.variables.unset('vcdm11' + suffix); pm.environment.unset('vcdm11' + suffix); });"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('public status publication served', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "pm.test('status publication has the declared media type', () => pm.expect(pm.response.headers.get('Content-Type') || '').to.include('application/vc+jwt'));",
                  "const publication = pm.response.text();",
                  "pm.expect(publication, 'non-empty signed status publication').to.not.be.empty;",
                  "const refreshedHash = CryptoJS.SHA256(publication).toString(CryptoJS.enc.Hex);",
                  "pm.expect(refreshedHash, 'fresh publication hash').to.not.equal(pm.variables.get('vcdm11InitialStatusListHash'));",
                  "pm.variables.set('vcdm11RefreshedStatusListHash', refreshedHash);",
                  "pm.environment.set('vcdm11RefreshedStatusListHash', refreshedHash);",
                  "const tokenParts = pm.response.text().split('.');",
                  "pm.expect(tokenParts.length, 'signed status JWT').to.equal(3);",
                  "const tokenPayloadPart = tokenParts[1].replace(/-/g, '+').replace(/_/g, '/');",
                  "const tokenPayload = JSON.parse(Buffer.from(tokenPayloadPart + '='.repeat((4 - tokenPayloadPart.length % 4) % 4), 'base64').toString('utf8'));",
                  "pm.expect(tokenPayload['@context'], 'W3C status context').to.be.an('array').and.to.include('https://www.w3.org/ns/credentials/v2');",
                  "pm.expect(tokenPayload['@context'], 'W3C status vocabulary').to.include('https://www.w3.org/ns/credentials/status/v1');",
                  "pm.expect(tokenPayload.type, 'W3C status type').to.be.an('array').and.to.include('VerifiableCredential');",
                  "pm.expect(tokenPayload.type, 'W3C status type').to.include('BitstringStatusListCredential');",
                  "const subject = tokenPayload.credentialSubject; pm.expect(subject, 'W3C credentialSubject').to.be.an('object');",
                  "pm.expect(subject.id, 'W3C status subject id').to.equal(pm.variables.get('vcdm11StatusListUri') + '#list');",
                  "pm.expect(subject.type, 'W3C status subject type').to.equal('BitstringStatusList');",
                  "pm.expect(subject.statusPurpose, 'W3C status purpose').to.equal('revocation');",
                  "pm.expect(Number(subject.statusSize || 1), 'statusSize').to.equal(1);",
                  "pm.expect(Date.parse(tokenPayload.validFrom), 'W3C validFrom').to.be.at.most(Date.now());",
                  "if (tokenPayload.validUntil !== undefined) pm.expect(Date.parse(tokenPayload.validUntil), 'W3C validUntil').to.be.greaterThan(Date.now());",
                  "const structuralEncoded = subject.encodedList; pm.expect(structuralEncoded, 'W3C encodedList').to.be.a('string').and.not.empty; pm.expect(structuralEncoded[0], 'W3C multibase base64url marker').to.equal('u');",
                  "const encodedList = tokenPayload.credentialSubject && tokenPayload.credentialSubject.encodedList;",
                  "pm.expect(encodedList, 'encoded status list').to.be.a('string').and.not.empty;",
                  "pm.expect(encodedList[0], 'multibase base64url marker').to.equal('u');",
                  "const encodedValue = encodedList.slice(1);",
                  "const encodedBytes = encodedValue.replace(/-/g, '+').replace(/_/g, '/');",
                  "const compressed = Buffer.from(encodedBytes + '='.repeat((4 - encodedBytes.length % 4) % 4), 'base64');",
                  "let bytes; try { const zlib = require('zlib'); bytes = zlib.gunzipSync(compressed); } catch { bytes = undefined; }",
                  "if (bytes) pm.expect(bytes.length, 'minimum Bitstring Status List byte length').to.be.at.least(16384);",
                  "const issuedIndex = Number(pm.variables.get('vcdm11IssuedStatusListIndex') || pm.environment.get('vcdm11IssuedStatusListIndex')); if (bytes) { const availableEntries = Math.floor(bytes.length * 8 / 1); pm.expect(Number.isSafeInteger(issuedIndex) && issuedIndex >= 0 && issuedIndex < availableEntries, 'issued status index is in range').to.equal(true);",
                  "const bitOffset = issuedIndex * 1; let statusValue = 0; for (let bit = 0; bit < 1; bit += 1) { const absolute = bitOffset + bit; const bitValue = (bytes[Math.floor(absolute / 8)] & (1 << (7 - (absolute % 8)))) ? 1 : 0; statusValue = (statusValue << 1) | bitValue; } pm.expect(statusValue, 'revoked status value').to.equal(1); } else if (pm.environment.get('stagedNewman') !== '1') { const evidenceText = pm.variables.get('vcdm11StatusListDecoderEvidence') || pm.environment.get('vcdm11StatusListDecoderEvidence'); let evidence; try { evidence = JSON.parse(evidenceText || ''); } catch { evidence = undefined; } pm.expect(evidence && evidence.result === 'decoded', 'supported local status decoder evidence').to.equal(true); pm.expect(evidence.credentialDigest, 'decoder credential binding').to.equal(pm.variables.get('vcdm11IssuedCredentialDigest')); pm.expect(evidence.runId, 'decoder run binding').to.equal(pm.environment.get('runId')); pm.expect(evidence.statusListUri, 'decoder URI binding').to.equal(pm.variables.get('vcdm11IssuedStatusListUri')); pm.expect(String(evidence.statusListIndex), 'decoder index binding').to.equal(String(issuedIndex)); pm.expect(evidence.publicationHash, 'decoded publication hash').to.equal(CryptoJS.SHA256(pm.response.text()).toString(CryptoJS.enc.Hex)); pm.expect(evidence.statusValue, 'decoded revoked status value').to.equal(1); pm.expect(evidence.revoked, 'decoded revoked bit').to.equal(true); }",
                  "pm.variables.set('vcdm11StatusPublicationReady', 'true'); pm.environment.set('vcdm11StatusPublicationReady', 'true');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 03 W3C VCDM 1.1 + Bitstring Status List post-revoke rejection",
          "description": "After the refresh request returns, use the supported wallet/verifier to present the same credential and place an ephemeral vcdm11PostRevokeRejectionEvidence JSON object in the run environment. It must contain result=rejected, a non-empty reason, credentialDigest, runId, statusListUri, statusListIndex, and publicationHash equal to the refreshed response hash. For mdoc, add mdocStatusDecoderEvidence with result=decoded, statusValue=1, and the same refreshed publicationHash after decoding that exact private refreshed CWT artifact. Validate those witnesses with the staged helper without fetching the publication again. No manually populated old index is sufficient, and no undocumented HTTP inspector is called. Remove the ephemeral evidence after the run.",
          "item": []
        }
      ]
    },
    {
      "name": "04 W3C VCDM 2.0 + Bitstring Status List",
      "description": "04 W3C VCDM 2.0 + Bitstring Status List lifecycle. The order is create the status list, fetch its exact returned public URI, create and resolve the offer, read issuer metadata, discover the authorization server, exchange the code, issue with a supplied wallet proof, perform the explicit trusted verification checkpoint, revoke the issued index, and refresh the same URI. The public media type is application/vc+jwt; signed content, freshness, hash change, status URI/index, and profile encoding are checked where a local decoder is available. The current runtime vocabulary is BitstringStatusListEntry with the revocation status purpose. Cloud mutations, wallet proof, trust verification, and mdoc decoding remain explicit run-time boundaries.",
      "item": [
        {
          "name": "Create 04 W3C VCDM 2.0 + Bitstring Status List status list",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"correlationId\": \"employee-vcdm-20-revocation\",\n  \"spec\": \"bitstring_status_list\",\n  \"purposes\": [\n    \"revocation\"\n  ],\n  \"proofFormat\": \"vc+jwt\",\n  \"hostingMode\": \"hosted\",\n  \"issuer\": \"did:web:issuer.example.com\",\n  \"signingKeyMode\": \"did:web\",\n  \"signingVerificationMethodId\": \"{{statusListVerificationMethodId}}\",\n  \"kmsResourceHandle\": \"{{statusListKmsResourceHandle}}\",\n  \"kmsKeyAlias\": \"employee-vcdm-20-signing\",\n  \"statusListUri\": \"{{tenantGatewayUrl}}/public/statuslists/employee-vcdm-20-revocation\",\n  \"length\": 131072,\n  \"bitsPerStatus\": 1,\n  \"ttlSeconds\": 300\n}"
            },
            "url": "{{tenantStatusListApiBaseUrl}}/statuslists",
            "description": "Create the profile status publication. The response DTO is authoritative: retain its exact id and statusListUri."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.variables.unset('vcdm20StatusListId'); pm.environment.unset('vcdm20StatusListId');",
                  "pm.variables.unset('vcdm20StatusListUri'); pm.environment.unset('vcdm20StatusListUri');",
                  "pm.variables.unset('vcdm20StatusPublicationReady'); pm.environment.unset('vcdm20StatusPublicationReady');",
                  "pm.variables.unset('vcdm20InitialStatusListHash'); pm.environment.unset('vcdm20InitialStatusListHash');",
                  "pm.variables.unset('vcdm20RefreshedStatusListHash'); pm.environment.unset('vcdm20RefreshedStatusListHash');",
                  "pm.variables.unset('vcdm20IssuedStatusListUri'); pm.environment.unset('vcdm20IssuedStatusListUri');",
                  "pm.variables.unset('vcdm20IssuedStatusListIndex'); pm.environment.unset('vcdm20IssuedStatusListIndex');",
                  "pm.variables.unset('vcdm20IssuedCredential'); pm.environment.unset('vcdm20IssuedCredential');",
                  "pm.variables.unset('vcdm20IssuedCredentialDigest'); pm.environment.unset('vcdm20IssuedCredentialDigest');",
                  "pm.variables.unset('vcdm20TrustedVerificationAttestation'); pm.environment.unset('vcdm20TrustedVerificationAttestation');",
                  "pm.variables.unset('vcdm20PostRevokeRejectionEvidence'); pm.environment.unset('vcdm20PostRevokeRejectionEvidence');",
                  "pm.variables.unset('vcdm20StatusListDecoderEvidence'); pm.environment.unset('vcdm20StatusListDecoderEvidence');"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = [200, 201].includes(pm.response.code);",
                  "pm.test('status list created', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "  const result = pm.response.json();",
                  "  pm.expect(result.id, 'StatusListResult.id').to.be.a('string').and.not.empty;",
                  "  pm.expect(result.statusListUri, 'StatusListResult.statusListUri').to.be.a('string').and.not.empty;",
                  "  pm.variables.set('vcdm20StatusListId', result.id);",
                  "  pm.variables.set('vcdm20StatusListUri', result.statusListUri);",
                  "  pm.environment.set('vcdm20StatusListId', result.id);",
                  "  pm.environment.set('vcdm20StatusListUri', result.statusListUri);",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Fetch 04 W3C VCDM 2.0 + Bitstring Status List status list",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/vc+jwt"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{vcdm20StatusListUri}}",
            "description": "Fetch the exact statusListUri returned by createStatusList. This public request has no management bearer. Check content type, signature, freshness, hash, and the profile encoding."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['StatusPublicationReady', 'InitialStatusListHash', 'RefreshedStatusListHash'].forEach((suffix) => { pm.variables.unset('vcdm20' + suffix); pm.environment.unset('vcdm20' + suffix); });"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('public status publication served', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "pm.test('status publication has the declared media type', () => pm.expect(pm.response.headers.get('Content-Type') || '').to.include('application/vc+jwt'));",
                  "const publication = pm.response.text();",
                  "pm.expect(publication, 'non-empty signed status publication').to.not.be.empty;",
                  "const hash = CryptoJS.SHA256(publication).toString(CryptoJS.enc.Hex);",
                  "pm.variables.set('vcdm20InitialStatusListHash', hash);",
                  "pm.environment.set('vcdm20InitialStatusListHash', hash);",
                  "const tokenParts = pm.response.text().split('.');",
                  "pm.expect(tokenParts.length, 'signed status JWT').to.equal(3);",
                  "const tokenPayloadPart = tokenParts[1].replace(/-/g, '+').replace(/_/g, '/');",
                  "const tokenPayload = JSON.parse(Buffer.from(tokenPayloadPart + '='.repeat((4 - tokenPayloadPart.length % 4) % 4), 'base64').toString('utf8'));",
                  "pm.expect(tokenPayload['@context'], 'W3C status context').to.be.an('array').and.to.include('https://www.w3.org/ns/credentials/v2');",
                  "pm.expect(tokenPayload['@context'], 'W3C status vocabulary').to.include('https://www.w3.org/ns/credentials/status/v1');",
                  "pm.expect(tokenPayload.type, 'W3C status type').to.be.an('array').and.to.include('VerifiableCredential');",
                  "pm.expect(tokenPayload.type, 'W3C status type').to.include('BitstringStatusListCredential');",
                  "const subject = tokenPayload.credentialSubject; pm.expect(subject, 'W3C credentialSubject').to.be.an('object');",
                  "pm.expect(subject.id, 'W3C status subject id').to.equal(pm.variables.get('vcdm20StatusListUri') + '#list');",
                  "pm.expect(subject.type, 'W3C status subject type').to.equal('BitstringStatusList');",
                  "pm.expect(subject.statusPurpose, 'W3C status purpose').to.equal('revocation');",
                  "pm.expect(Number(subject.statusSize || 1), 'statusSize').to.equal(1);",
                  "pm.expect(Date.parse(tokenPayload.validFrom), 'W3C validFrom').to.be.at.most(Date.now());",
                  "if (tokenPayload.validUntil !== undefined) pm.expect(Date.parse(tokenPayload.validUntil), 'W3C validUntil').to.be.greaterThan(Date.now());",
                  "const structuralEncoded = subject.encodedList; pm.expect(structuralEncoded, 'W3C encodedList').to.be.a('string').and.not.empty; pm.expect(structuralEncoded[0], 'W3C multibase base64url marker').to.equal('u');",
                  "pm.variables.set('vcdm20StatusPublicationReady', 'true'); pm.environment.set('vcdm20StatusPublicationReady', 'true');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Create VCDM 2.0 credential design",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credentialType\": {\n    \"format\": \"W3C_VC\",\n    \"type\": \"EmploymentCredential\",\n    \"@context\": \"https://www.w3.org/ns/credentials/v2\"\n  },\n  \"bindings\": [\n    {\n      \"type\": \"EmploymentCredential\",\n      \"@context\": \"https://www.w3.org/ns/credentials/v2\",\n      \"credentialConfigurationId\": \"Vcdm20JwtLd\"\n    }\n  ],\n  \"alias\": \"EmployeeCredentialV20\",\n  \"hostingMode\": \"LOCAL\"\n}"
            },
            "url": "{{tenantCredentialDesignApiBaseUrl}}/designs/credentials",
            "description": "Create the VCDM 2.0 design before its offer. The binding id and context match the issuer configuration used by this profile."
          }
        },
        {
          "name": "Manual 04 W3C VCDM 2.0 + Bitstring Status List issuer status binding",
          "description": "Before creating the offer, configure the issuer credential configuration Vcdm20JwtLd in the supported tenant configuration surface. Set credentials.[Vcdm20JwtLd].status.statusListId to the exact vcdm20StatusListId returned by createStatusList and verify the corresponding root statuslists entry has the same public statusListUri (vcdm20StatusListUri). Confirm issuer metadata advertises this configuration and the same status publication before continuing. This collection has no generic status-binding endpoint; stop if the id, URI, configuration, or advertised status association differs.",
          "item": []
        },
        {
          "name": "Create 04 W3C VCDM 2.0 + Bitstring Status List offer",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credential_configuration_ids\": [\n    \"Vcdm20JwtLd\"\n  ],\n  \"grants\": {\n    \"pre_authorized_code\": {}\n  },\n  \"credential_subject_data\": {\n    \"id\": \"did:example:bob\",\n    \"type\": \"EmploymentCredential\",\n    \"name\": \"Bob\"\n  },\n  \"correlation_id\": \"vcdm20-{{runId}}\"\n}"
            },
            "url": "{{tenantIssuerApiBaseUrl}}/backend/credential/offers",
            "description": "Create an offer through the issuer backend DTO. The wallet resolves the returned offer_uri; this request does not fabricate a public grant URI."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('offer created', () => pm.expect(pm.response.code).to.be.oneOf([200, 201]));",
                  "const result = pm.response.json();",
                  "pm.expect(result.offer_uri, 'offer_uri').to.be.a('string').and.not.empty;",
                  "pm.expect(result.correlation_id, 'correlation_id').to.be.a('string').and.not.empty;",
                  "pm.variables.set('vcdm20OfferUri', result.offer_uri);",
                  "const offerMatch = result.offer_uri.match(/[?&]credential_offer_uri=([^&]+)/); pm.expect(offerMatch && offerMatch[1], 'credential_offer_uri').to.be.a('string').and.not.empty; pm.variables.set('vcdm20CredentialOfferUri', decodeURIComponent(offerMatch[1]));"
                ]
              }
            }
          ]
        },
        {
          "name": "Resolve 04 W3C VCDM 2.0 + Bitstring Status List offer",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{vcdm20CredentialOfferUri}}",
            "description": "Resolve the offer as a wallet. Require the issuer, exact configuration id, and the canonical OID4VCI pre-authorized grant namespace."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('offer resolved', () => pm.response.to.have.status(200));",
                  "const offer = pm.response.json();",
                  "pm.expect(offer.credential_issuer, 'credential_issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(offer.credential_configuration_ids, 'credential_configuration_ids').to.include('Vcdm20JwtLd');",
                  "const grant = offer.grants && offer.grants['urn:ietf:params:oauth:grant-type:pre-authorized_code'];",
                  "pm.expect(grant, 'canonical pre-authorized grant').to.be.an('object');",
                  "pm.expect(grant['pre-authorized_code'], 'pre-authorized_code').to.be.a('string').and.not.empty;",
                  "pm.variables.set('vcdm20CredentialIssuer', offer.credential_issuer);",
                  "pm.variables.set('vcdm20PreAuthCode', grant['pre-authorized_code']);"
                ]
              }
            }
          ]
        },
        {
          "name": "Fetch 04 W3C VCDM 2.0 + Bitstring Status List issuer metadata",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{tenantIssuerMetadataUrl}}",
            "description": "Read the exact issuer metadata URL supplied by the approved tenant bootstrap. Use its advertised credential_endpoint and authorization_servers; no well-known path is invented from a host name."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('issuer metadata served', () => pm.response.to.have.status(200));",
                  "const metadata = pm.response.json();",
                  "pm.expect(metadata.credential_issuer, 'metadata credential_issuer').to.equal(pm.variables.get('vcdm20CredentialIssuer'));",
                  "pm.expect(metadata.credential_endpoint, 'metadata credential_endpoint').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.authorization_servers, 'metadata authorization_servers').to.be.an('array').and.not.empty;",
                  "const profile = metadata.credential_configurations_supported && metadata.credential_configurations_supported['Vcdm20JwtLd'];",
                  "pm.expect(profile, 'advertised credential configuration').to.be.an('object');",
                  "pm.expect(profile.format, 'credential format').to.equal('jwt_vc_json-ld');",
                  "pm.variables.set('vcdm20CredentialEndpoint', metadata.credential_endpoint);",
                  "pm.variables.set('vcdm20AuthorizationServer', metadata.authorization_servers[0]);"
                ]
              }
            }
          ]
        },
        {
          "name": "Discover 04 W3C VCDM 2.0 + Bitstring Status List authorization server",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "*/*"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{tenantGatewayUrl}}/.well-known/oauth-authorization-server",
            "description": "Discover the authorization server at the tenant well-known endpoint and retain the advertised token_endpoint. The collection never appends /token."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('authorization server metadata served', () => pm.response.to.have.status(200));",
                  "const metadata = pm.response.json();",
                  "pm.expect(metadata.issuer, 'authorization-server issuer').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.token_endpoint, 'advertised token_endpoint').to.be.a('string').and.not.empty;",
                  "pm.expect(metadata.issuer, 'issuer matches credential metadata').to.equal(pm.variables.get('vcdm20AuthorizationServer'));",
                  "pm.variables.set('vcdm20TokenEndpoint', metadata.token_endpoint);"
                ]
              }
            }
          ]
        },
        {
          "name": "Exchange 04 W3C VCDM 2.0 + Bitstring Status List pre-authorized code",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Content-Type",
                "value": "application/x-www-form-urlencoded"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "body": {
              "mode": "urlencoded",
              "urlencoded": [
                {
                  "key": "grant_type",
                  "value": "urn:ietf:params:oauth:grant-type:pre-authorized_code"
                },
                {
                  "key": "pre-authorized_code",
                  "value": "{{vcdm20PreAuthCode}}"
                }
              ]
            },
            "url": "{{vcdm20TokenEndpoint}}",
            "description": "Exchange the offer-derived code at the token_endpoint advertised by authorization-server discovery. Keep the access token in run-local variables only."
          },
          "event": [
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('token exchanged', () => pm.response.to.have.status(200));",
                  "const tokenResponse = pm.response.json();",
                  "pm.expect(tokenResponse.access_token, 'access_token').to.be.a('string').and.not.empty;",
                  "pm.expect(tokenResponse.authorization_details, 'authorization_details').to.be.an('array').and.not.empty;",
                  "const authorization = tokenResponse.authorization_details.find((entry) => entry.type === 'openid_credential' && entry.credential_configuration_id === 'Vcdm20JwtLd');",
                  "pm.expect(authorization, 'profile authorization detail').to.be.an('object');",
                  "pm.expect(authorization.credential_identifiers, 'credential_identifiers').to.be.an('array').and.not.empty;",
                  "pm.variables.set('vcdm20AccessToken', tokenResponse.access_token);",
                  "pm.variables.set('vcdm20CredentialIdentifier', authorization.credential_identifiers[0]);"
                ]
              }
            }
          ]
        },
        {
          "name": "Issue 04 W3C VCDM 2.0 + Bitstring Status List",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{vcdm20AccessToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "body": {
              "mode": "raw",
              "raw": "{\n  \"credential_identifier\": \"{{vcdm20CredentialIdentifier}}\",\n  \"proofs\": {\n    \"jwt\": [\n      \"{{vcdm20ProofJwt}}\"\n    ]\n  }\n}"
            },
            "url": "{{vcdm20CredentialEndpoint}}",
            "description": "Issue the jwt_vc_json-ld credential using the profile credential identifier returned in authorization_details. Supply a real wallet proof at run time; no proof or identifier is fabricated here."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['IssuedStatusListUri', 'IssuedStatusListIndex', 'IssuedCredential', 'IssuedCredentialDigest', 'TrustedVerificationAttestation'].forEach((suffix) => { pm.variables.unset('vcdm20' + suffix); pm.environment.unset('vcdm20' + suffix); });",
                  "const issuanceReady = Boolean(pm.variables.get('vcdm20AccessToken') && pm.variables.get('vcdm20CredentialIdentifier') && (pm.variables.get('vcdm20ProofJwt') || pm.environment.get('vcdm20ProofJwt')));",
                  "pm.test('issuance inputs are present', () => pm.expect(issuanceReady, 'access token, profile credential identifier, and run-time proof are required').to.equal(true));",
                  "if (!issuanceReady) { pm.execution.skipRequest(); }"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('credential issued', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "const response = pm.response.json();",
                  "const credential = response.credentials && response.credentials[0] && response.credentials[0].credential;",
                  "pm.expect(credential, 'issued credential').to.be.a('string').and.not.empty;",
                  "pm.variables.set('vcdm20IssuedCredential', credential);",
                  "const parts = credential.split('~')[0].split('.');",
                  "pm.expect(parts.length, 'compact JWT payload').to.be.greaterThan(1);",
                  "const encoded = parts[1].replace(/-/g, '+').replace(/_/g, '/');",
                  "const padded = encoded + '='.repeat((4 - encoded.length % 4) % 4);",
                  "const payload = JSON.parse(Buffer.from(padded, 'base64').toString('utf8'));",
                  "pm.expect(payload['@context'], 'VCDM 2.0 context').to.include('https://www.w3.org/ns/credentials/v2');",
                  "pm.expect(payload.type, 'VCDM 2.0 type').to.include('EmploymentCredential');",
                  "pm.expect((payload.credentialStatus || {}).type, 'BitstringStatusListEntry type').to.equal('BitstringStatusListEntry');",
                  "const status = payload.credentialStatus;",
                  "pm.expect(status, 'issued credential status').to.be.an('object');",
                  "pm.expect(status.statusListCredential, 'issued status URI').to.be.a('string').and.not.empty;",
                  "const rawIssuedIndex = status.statusListIndex; const issuedIndex = Number(rawIssuedIndex); const validIssuedIndex = (typeof rawIssuedIndex === 'number' && Number.isSafeInteger(rawIssuedIndex)) || (typeof rawIssuedIndex === 'string' && /^\\d+$/.test(rawIssuedIndex)); pm.expect(validIssuedIndex && issuedIndex >= 0 && issuedIndex < 131072, 'issued status index must be a non-negative in-range integer').to.equal(true);",
                  "pm.variables.set('vcdm20IssuedStatusListUri', status.statusListCredential);",
                  "pm.variables.set('vcdm20IssuedStatusListIndex', String(issuedIndex));",
                  "pm.variables.set('vcdm20IssuedCredentialDigest', CryptoJS.SHA256(credential).toString(CryptoJS.enc.Hex));",
                  "pm.environment.set('vcdm20IssuedStatusListUri', status.statusListCredential);",
                  "pm.environment.set('vcdm20IssuedStatusListIndex', String(issuedIndex));",
                  "pm.environment.set('vcdm20IssuedCredentialDigest', CryptoJS.SHA256(credential).toString(CryptoJS.enc.Hex));",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 04 W3C VCDM 2.0 + Bitstring Status List trusted pre-revoke verification",
          "description": "Stop here for a supported wallet/verifier checkpoint. Verify the just-issued jwt_vc_json-ld credential with the configured trust anchors. For the JWT profiles, provide a run-local JSON attestation in vcdm20TrustedVerificationAttestation. The trusted result must contain result=trusted, credentialDigest=the SHA-256 digest of this issued credential, runId, statusListUri, and statusListIndex. Reject missing, expired, malformed, wrong-type, untrusted, stale, and wrong-issuer credentials. The revoke preflight rejects absent or mismatched evidence; this collection has no generic inspector endpoint and must not claim this evidence automatically.",
          "item": []
        },
        {
          "name": "Revoke 04 W3C VCDM 2.0 + Bitstring Status List status entry",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"statusListIndex\": \"{{vcdm20IssuedStatusListIndex}}\",\n  \"value\": 1\n}"
            },
            "url": "{{tenantStatusListApiBaseUrl}}/statuslists/{{vcdm20StatusListId}}/status",
            "description": "Revoke the index extracted from this profile’s issued credential. The preflight binds the returned status URI, trusted credential identifier, and list id; a stale or mismatched issuance skips the mutation."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const createdUri = pm.variables.get('vcdm20StatusListUri') || pm.environment.get('vcdm20StatusListUri'); const issuedDigest = pm.variables.get('vcdm20IssuedCredentialDigest') || pm.environment.get('vcdm20IssuedCredentialDigest'); const publicationReady = (pm.variables.get('vcdm20StatusPublicationReady') || pm.environment.get('vcdm20StatusPublicationReady')) === 'true'; const attestationText = pm.variables.get('vcdm20TrustedVerificationAttestation') || pm.environment.get('vcdm20TrustedVerificationAttestation'); let attestation; try { attestation = JSON.parse(attestationText || ''); } catch { attestation = undefined; } const issuedUri = pm.variables.get('vcdm20IssuedStatusListUri') || pm.environment.get('vcdm20IssuedStatusListUri'); const issuedIndex = pm.variables.get('vcdm20IssuedStatusListIndex') || pm.environment.get('vcdm20IssuedStatusListIndex');",
                  "const issuedIndexNumber = Number(issuedIndex); const indexText = String(issuedIndex); const indexValid = ((typeof issuedIndex === 'number' && Number.isSafeInteger(issuedIndex)) || (typeof issuedIndex === 'string' && /^\\d+$/.test(indexText))) && issuedIndexNumber >= 0 && issuedIndexNumber < 131072;",
                  "const validAttestation = Boolean(publicationReady && issuedUri && issuedUri === createdUri && indexValid && issuedDigest && attestation && attestation.result === 'trusted' && attestation.credentialDigest === issuedDigest && attestation.runId === pm.environment.get('runId') && attestation.statusListUri === issuedUri && String(attestation.statusListIndex) === String(issuedIndex));",
                  "pm.test('trusted verification attestation is bound to this issuance', () => pm.expect(validAttestation, 'missing, stale, or mismatched trusted verification evidence').to.equal(true)); if (!validAttestation) { pm.execution.skipRequest(); }",
                  "if (validAttestation) { const statusRequestBody = JSON.parse(pm.request.body.raw); statusRequestBody.statusListIndex = issuedIndexNumber; pm.request.body.update(JSON.stringify(statusRequestBody)); }"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "pm.test('status entry revoked', () => pm.expect(pm.response.code).to.equal(200));",
                  "const result = pm.response.json();",
                  "pm.expect(String(result.statusListId), 'returned list id').to.equal(pm.variables.get('vcdm20StatusListId'));",
                  "pm.expect(String(result.statusListIndex), 'returned index').to.equal(String(pm.variables.get('vcdm20IssuedStatusListIndex')));",
                  "pm.expect(result.value, 'returned status value').to.equal(1);"
                ]
              }
            }
          ]
        },
        {
          "name": "Refresh 04 W3C VCDM 2.0 + Bitstring Status List status list",
          "request": {
            "method": "GET",
            "header": [
              {
                "key": "Accept",
                "value": "application/vc+jwt"
              }
            ],
            "auth": {
              "type": "noauth"
            },
            "url": "{{vcdm20StatusListUri}}",
            "description": "Fetch the exact statusListUri returned by createStatusList. This public request has no management bearer. Check content type, signature, freshness, hash, and the profile encoding."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "['StatusPublicationReady', 'RefreshedStatusListHash'].forEach((suffix) => { pm.variables.unset('vcdm20' + suffix); pm.environment.unset('vcdm20' + suffix); });"
                ]
              }
            },
            {
              "listen": "test",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "const success = pm.response.code === 200;",
                  "pm.test('public status publication served', () => pm.expect(success).to.equal(true));",
                  "if (success) {",
                  "pm.test('status publication has the declared media type', () => pm.expect(pm.response.headers.get('Content-Type') || '').to.include('application/vc+jwt'));",
                  "const publication = pm.response.text();",
                  "pm.expect(publication, 'non-empty signed status publication').to.not.be.empty;",
                  "const refreshedHash = CryptoJS.SHA256(publication).toString(CryptoJS.enc.Hex);",
                  "pm.expect(refreshedHash, 'fresh publication hash').to.not.equal(pm.variables.get('vcdm20InitialStatusListHash'));",
                  "pm.variables.set('vcdm20RefreshedStatusListHash', refreshedHash);",
                  "pm.environment.set('vcdm20RefreshedStatusListHash', refreshedHash);",
                  "const tokenParts = pm.response.text().split('.');",
                  "pm.expect(tokenParts.length, 'signed status JWT').to.equal(3);",
                  "const tokenPayloadPart = tokenParts[1].replace(/-/g, '+').replace(/_/g, '/');",
                  "const tokenPayload = JSON.parse(Buffer.from(tokenPayloadPart + '='.repeat((4 - tokenPayloadPart.length % 4) % 4), 'base64').toString('utf8'));",
                  "pm.expect(tokenPayload['@context'], 'W3C status context').to.be.an('array').and.to.include('https://www.w3.org/ns/credentials/v2');",
                  "pm.expect(tokenPayload['@context'], 'W3C status vocabulary').to.include('https://www.w3.org/ns/credentials/status/v1');",
                  "pm.expect(tokenPayload.type, 'W3C status type').to.be.an('array').and.to.include('VerifiableCredential');",
                  "pm.expect(tokenPayload.type, 'W3C status type').to.include('BitstringStatusListCredential');",
                  "const subject = tokenPayload.credentialSubject; pm.expect(subject, 'W3C credentialSubject').to.be.an('object');",
                  "pm.expect(subject.id, 'W3C status subject id').to.equal(pm.variables.get('vcdm20StatusListUri') + '#list');",
                  "pm.expect(subject.type, 'W3C status subject type').to.equal('BitstringStatusList');",
                  "pm.expect(subject.statusPurpose, 'W3C status purpose').to.equal('revocation');",
                  "pm.expect(Number(subject.statusSize || 1), 'statusSize').to.equal(1);",
                  "pm.expect(Date.parse(tokenPayload.validFrom), 'W3C validFrom').to.be.at.most(Date.now());",
                  "if (tokenPayload.validUntil !== undefined) pm.expect(Date.parse(tokenPayload.validUntil), 'W3C validUntil').to.be.greaterThan(Date.now());",
                  "const structuralEncoded = subject.encodedList; pm.expect(structuralEncoded, 'W3C encodedList').to.be.a('string').and.not.empty; pm.expect(structuralEncoded[0], 'W3C multibase base64url marker').to.equal('u');",
                  "const encodedList = tokenPayload.credentialSubject && tokenPayload.credentialSubject.encodedList;",
                  "pm.expect(encodedList, 'encoded status list').to.be.a('string').and.not.empty;",
                  "pm.expect(encodedList[0], 'multibase base64url marker').to.equal('u');",
                  "const encodedValue = encodedList.slice(1);",
                  "const encodedBytes = encodedValue.replace(/-/g, '+').replace(/_/g, '/');",
                  "const compressed = Buffer.from(encodedBytes + '='.repeat((4 - encodedBytes.length % 4) % 4), 'base64');",
                  "let bytes; try { const zlib = require('zlib'); bytes = zlib.gunzipSync(compressed); } catch { bytes = undefined; }",
                  "if (bytes) pm.expect(bytes.length, 'minimum Bitstring Status List byte length').to.be.at.least(16384);",
                  "const issuedIndex = Number(pm.variables.get('vcdm20IssuedStatusListIndex') || pm.environment.get('vcdm20IssuedStatusListIndex')); if (bytes) { const availableEntries = Math.floor(bytes.length * 8 / 1); pm.expect(Number.isSafeInteger(issuedIndex) && issuedIndex >= 0 && issuedIndex < availableEntries, 'issued status index is in range').to.equal(true);",
                  "const bitOffset = issuedIndex * 1; let statusValue = 0; for (let bit = 0; bit < 1; bit += 1) { const absolute = bitOffset + bit; const bitValue = (bytes[Math.floor(absolute / 8)] & (1 << (7 - (absolute % 8)))) ? 1 : 0; statusValue = (statusValue << 1) | bitValue; } pm.expect(statusValue, 'revoked status value').to.equal(1); } else if (pm.environment.get('stagedNewman') !== '1') { const evidenceText = pm.variables.get('vcdm20StatusListDecoderEvidence') || pm.environment.get('vcdm20StatusListDecoderEvidence'); let evidence; try { evidence = JSON.parse(evidenceText || ''); } catch { evidence = undefined; } pm.expect(evidence && evidence.result === 'decoded', 'supported local status decoder evidence').to.equal(true); pm.expect(evidence.credentialDigest, 'decoder credential binding').to.equal(pm.variables.get('vcdm20IssuedCredentialDigest')); pm.expect(evidence.runId, 'decoder run binding').to.equal(pm.environment.get('runId')); pm.expect(evidence.statusListUri, 'decoder URI binding').to.equal(pm.variables.get('vcdm20IssuedStatusListUri')); pm.expect(String(evidence.statusListIndex), 'decoder index binding').to.equal(String(issuedIndex)); pm.expect(evidence.publicationHash, 'decoded publication hash').to.equal(CryptoJS.SHA256(pm.response.text()).toString(CryptoJS.enc.Hex)); pm.expect(evidence.statusValue, 'decoded revoked status value').to.equal(1); pm.expect(evidence.revoked, 'decoded revoked bit').to.equal(true); }",
                  "pm.variables.set('vcdm20StatusPublicationReady', 'true'); pm.environment.set('vcdm20StatusPublicationReady', 'true');",
                  "}"
                ]
              }
            }
          ]
        },
        {
          "name": "Manual 04 W3C VCDM 2.0 + Bitstring Status List post-revoke rejection",
          "description": "After the refresh request returns, use the supported wallet/verifier to present the same credential and place an ephemeral vcdm20PostRevokeRejectionEvidence JSON object in the run environment. It must contain result=rejected, a non-empty reason, credentialDigest, runId, statusListUri, statusListIndex, and publicationHash equal to the refreshed response hash. For mdoc, add mdocStatusDecoderEvidence with result=decoded, statusValue=1, and the same refreshed publicationHash after decoding that exact private refreshed CWT artifact. Validate those witnesses with the staged helper without fetching the publication again. No manually populated old index is sufficient, and no undocumented HTTP inspector is called. Remove the ephemeral evidence after the run.",
          "item": []
        }
      ]
    },
    {
      "name": "05 Azure KMS, BYOK, and BYOC (opt-in)",
      "description": "Optional provider reference registrations. These requests execute only when the external Newman environment sets ALLOW_CLOUD_MUTATIONS=1. The default run uses Postman skipRequest and must produce zero sends. Use only tenant-owned non-secret references; this collection never contains credentials.",
      "item": [
        {
          "name": "Attach Azure KMS resource",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"providerId\": \"azure-test\",\n  \"kind\": \"AZURE_KEY_VAULT\",\n  \"displayName\": \"Azure test KMS\",\n  \"configuration\": {\n    \"vaultUri\": \"https://example-vault.vault.azure.net/\",\n    \"applicationId\": \"<workload-application-id>\",\n    \"tenantId\": \"<entra-directory-tenant-id>\",\n    \"clientId\": \"<workload-client-id>\",\n    \"hsmType\": \"SOFTWARE\"\n  }\n}"
            },
            "url": "{{platformConfigApiBaseUrl}}/tenants/{{tenantId}}/kms/resources:attach",
            "description": "Opt-in only. Attach a tenant-owned Azure Key Vault coordinate after explicit approval."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.environment.get('ALLOW_CLOUD_MUTATIONS') !== '1') { pm.execution.skipRequest(); }"
                ]
              }
            }
          ]
        },
        {
          "name": "Register BYOK key",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"providerId\": \"{{providerId}}\",\n  \"alias\": \"{{providerNativeKeyAlias}}\",\n  \"kid\": \"<provider-canonical-key-id>\"\n}"
            },
            "url": "{{tenantKmsApiBaseUrl}}/keys/register",
            "description": "Opt-in only. Register a provider-native key reference; private key material never crosses this API."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.environment.get('ALLOW_CLOUD_MUTATIONS') !== '1') { pm.execution.skipRequest(); }"
                ]
              }
            }
          ]
        },
        {
          "name": "Register BYOC provider-native certificate",
          "request": {
            "method": "POST",
            "header": [
              {
                "key": "Authorization",
                "value": "Bearer {{tenantToken}}"
              },
              {
                "key": "Content-Type",
                "value": "application/json"
              }
            ],
            "body": {
              "mode": "raw",
              "raw": "{\n  \"providerId\": \"{{providerId}}\",\n  \"alias\": \"issuer-document-signer-leaf\",\n  \"providerCertificateId\": \"{{providerNativeCertificateId}}\",\n  \"kind\": \"trusted_certificate\",\n  \"source\": \"provider_native\"\n}"
            },
            "url": "{{tenantKmsApiBaseUrl}}/certificates/register",
            "description": "Opt-in only. Register a provider-native public certificate reference."
          },
          "event": [
            {
              "listen": "prerequest",
              "script": {
                "type": "text/javascript",
                "exec": [
                  "if (pm.environment.get('ALLOW_CLOUD_MUTATIONS') !== '1') { pm.execution.skipRequest(); }"
                ]
              }
            }
          ]
        }
      ]
    }
  ]
}
