Interpreting Results — Gateway

What Is the ID Token?

At the end of a successful Gateway flow, your application receives an ID Token — a JSON Web Token (JWT) in the industry-standard RFC 7519 format. The token is signed by ID Dataweb using RS256 (asymmetric cryptography), and contains the full results of the user's verification session.

A JWT consists of three parts separated by dots:

eyJhbGciOiJSUzI1NiJ9.eyJwb2xpY3lEZWNpc2lvbiI6ImFwcHJvdmUiLCAuLi59.signature
       header                          payload                       signature
PartDescription
HeaderToken type (JWT) and signing algorithm (RS256). Base64Url encoded.
PayloadVerification results and session data. Base64Url encoded.
SignatureRS256 signature from ID Dataweb. Verify using the JWKS public key.

Verifying the Signature

Before trusting any data in the ID Token, verify the RS256 signature. Public signing keys are available in JWK format at:

https://preprod.iddataweb.com/axn/oauth2/jwks.json

Use a standard JWT library — do not write your own cryptographic code. Resources: jwt.io libraries | JWK libraries


The policyDecision Field

The policyDecision field is the primary output you will act on. It summarizes whether the user met your configured verification policy.

ValueMeaning
approveUser verified to the level specified in your policy
denyUser did not meet the verification policy
obligationAdditional step required — handled within the workflow
no_decisionPolicy not configured or transaction error

Note: When using the Gateway, the final policyDecision returned to your application will always be either approve or deny. Obligations are handled automatically mid-flow — the user is stepped up to additional checks within the Gateway before a final decision is returned.


Decoding the Payload

To read the ID Token payload, split the JWT on . and Base64Url decode the second segment:

app.get("/callback", async (req, res) => {
  const authCode = req.query.code
  const jwt = await getToken(auth, authCode)
  const payload = jwt.id_token.split('.')[1]
  const jsonString = Buffer.from(payload, 'base64').toString()
  const data = JSON.parse(jsonString)
  // act on data.policyDecision
})

Full ID Token Example

{
  "at_hash": "udfkrvnPivU4uE0BYeUcXA",
  "sub": "[email protected]",
  "aud": "18976aa43dca4b4e",
  "endpoint": {
    "status": "success",
    "errorCode": "",
    "errorDescription": "",
    "credential": "[email protected]",
    "credentialCreationDate": "02/08/2022 21:09:35 UTC",
    "mbun": "f3f2a548-6c67-4155-8e30-bb1a28c84647",
    "maxToken": "EnMbLwzgyefV3dndx9d5r1C-iEyZ8PpRhuIeIFlGpIE",
    "endpointInstanceList": [
      {
        "apikey": "55555",
        "userAttributes": [
          {
            "attributeType": "FullName",
            "values": { "fname": "Jane", "lname": "Smith" },
            "dateCreated": "02/08/2022 21:09:55 UTC"
          },
          {
            "attributeType": "InternationalAddress",
            "values": {
              "country": "US",
              "locality": "Arlington",
              "route": "Main Ave",
              "administrative_area_level_1": "VA",
              "street_number": "123",
              "postal_code": "22201"
            },
            "dateCreated": "02/08/2022 21:09:55 UTC"
          }
        ],
        "acquiredAttributes": [
          {
            "attributeType": "AssertionScore",
            "values": { "assertionScore": "88" },
            "dateCreated": "02/08/2022 21:09:57 UTC"
          }
        ],
        "userAssertionList": [
          {
            "provider": "Experian",
            "serviceOffering": "Experian Precise ID",
            "dateAsserted": "02/08/2022 21:09:55 UTC",
            "assertions": {
              "link.fullName_address": "pass",
              "test.address90DaysOld": "pass",
              "test.addressIsResidential": "pass",
              "link.lastName_phone": "pass"
            }
          }
        ],
        "policyDecision": {
          "conclusion": "approve",
          "status": "success",
          "selectedPolicyID": 12391,
          "decisionDetail": "{}"
        }
      }
    ]
  },
  "policyDecision": "approve",
  "idwRiskScore": "100",
  "iss": "https://preprod.iddataweb.com/axn",
  "idwTrustScore": "100",
  "exp": 1644355218,
  "iat": 1644354618,
  "jti": "008ab766-a58d-4489-b4cd-85188d2562d0"
}

Key Fields Reference

FieldDescription
subThe user's credential (e.g. email address). Same value as credential. Used per OIDC standard.
audThe primary client_id (API key) of the workflow.
issIssuer — the ID Dataweb Gateway URL.
policyDecisionTop-level verdict: approve or deny. This is your primary action field.
idwRiskScoreComposite risk score (0–100). Higher is lower risk.
idwTrustScoreComposite trust score (0–100). Higher indicates greater confidence in the identity.
jtiJWT ID — same value as asi and transaction_id used elsewhere. Per OIDC standard.
exp / iatToken expiry and issue time (Unix timestamp).
endpoint.endpointInstanceListArray of per-step results. See below.

The endpointInstanceList

The endpointInstanceList is an array of objects — one per step in your verification workflow. Each object corresponds to one API key (step) and contains:

  • apikey — the step's API key
  • userAttributes — attributes collected from the user during this step
  • acquiredAttributes — attributes acquired from Checkers (e.g. device type, assertion scores)
  • userAssertionList — individual assertion results from each Checker
  • policyDecision — the decision for this step, including conclusion and obligationApiKey (if stepped up)

Example endpointInstanceList entry (obligation mid-flow)

{
  "apikey": "12345",
  "userAttributes": [],
  "acquiredAttributes": [
    {
      "attributeType": "DeviceType",
      "values": { "deviceType": "desktop" },
      "dateCreated": "02/08/2022 21:09:40 UTC"
    }
  ],
  "userAssertionList": [],
  "policyDecision": {
    "conclusion": "obligation",
    "obligationApiKey": "55555",
    "status": "success",
    "selectedPolicyID": 20124,
    "decisionDetail": "{}"
  }
}

In this example, step 12345 obligated the user to proceed to step 55555 — this happened transparently within the Gateway flow before a final decision was returned to your application.