ndovuagent-auth

This page was not opened over a private connection (HTTPS). The validator still runs locally, but only a secure context guarantees nothing can tamper with it in transit.

ID-JAG validatorno token yetRuns in your browser - nothing leaves this page

validator ready - nothing leaves this page

Validation context - who issued this, which API, which draft

Paste a token and run Validate: the engine walks the draft's five check families and renders one verdict row per rule, with the section citation. Undecidable rules (replay, tenant trust) honestly render external.

DRAFT-IETF-OAUTH-IDENTITY-ASSERTION-AUTHZ-GRANT · THE RULE-BY-RULE CONSOLE

The ID-JAG validator

Rule-by-rule ID-JAG validator for draft-ietf-oauth-id-jag (Cross-App Access): paste a token, mint broken grants, check metadata - all in your browser.

updated October 31, 2026draft -05 and -04 · engine: id-jag-validate

An Identity Assertion JWT Authorization Grant (ID-JAG) is how an enterprise identity provider vouches for a user to a resource server without handing anyone an access token for the wrong audience. The draft is short; its rules are not optional color - they are the exact MUSTs a resource server checks before it answers. This console runs those checks for real: the Validate tab walks the five check families (structure, claims, semantics, subject identifiers, rejection) with one verdict row per rule and the section citation attached; the Mint tab is a stub enterprise IdP whose toggles break the grant on purpose, one rule family at a time; the Metadata tab checks an authorization server's advertisement and its grant-type coupling. Runs in your browser - nothing leaves this page.

What to take away
  • Decoding is not validating. The signature check needs the issuer's pinned key; the audience and client checks need your deployment's context - that is why the console asks for it.
  • Some rules cannot be decided from the token alone. Replay, tenant trust, and policy checks render external and say what they would need - a validator that claims to decide them from bytes is lying.
  • Subject identifiers are the trap. A sub_id that resolves on the nameid alone imports whatever that name format leaks; the draft's formats exist to scope and stabilize identity across tenants.
  • Metadata is a contract, not a document: advertising the id-jag grant profile without jwt-bearer in grant_types_supported is the coupling failure the Metadata tab catches.
  • Every rejection-grade failure lands the same way: the grant is refused with invalid_grant, and the rule rows tell you which MUST ended it.
The fixtures

The keys are checked-in demo fixtures (one RSA-2048 and one P-256 issuer keypair, published on purpose; they protect nothing - the lab is the one place where seeing the private key is the point). Tokens are minted in your browser with live iat/exp, so "expired" only happens when a toggle rolls the clock. Validation runs against the draft text via theid-jag-validate engine, compiled into this page.

How to validate ID-JAG tokens

The engine behind this console ships as the npm package id-jag-validate (source). It is zero-dependency and isomorphic, and every rule row above is one library call carrying the same keyword and draft citation.

install
npm install id-jag-validate
library

Embed the checks in your own service. The context inputs unlock the rules that need your deployment's shape; rules that cannot be decided from the token alone return external and say what they would need.

import { validateToken } from "id-jag-validate";

const result = await validateToken(token, {
  revision: "-05",                             // or "-04"
  expectedIssuer: "https://idp.example.com/",  // trusted IdP for iss
  expectedAudience: "https://ras.example.com/",// expected RAS audience
  expectedClientId: "my-client",               // authenticated client
  now: 1760000000,                             // optional Unix seconds; defaults to the host clock
  key: issuerPublicJwk,                        // optional; enables signature verification
});
cli

One command, one verdict line per rule - keyword, section citation, outcome. Exit codes: 0 every check passes, 1 an invalid_grant-grade failure, 2 usage error.

npx id-jag-validate validate <token> --issuer https://idp.example.com/ \
  --audience https://ras.example.com/ --client-id my-client \
  --now 2026-10-31T00:00:00Z
ci

Pin a known-good grant in the repo and let the exit code gate the build.

steps:
  - uses: actions/checkout@v4
  - uses: actions/setup-node@v4
    with:
      node-version: 24
  - run: npm install id-jag-validate
  - name: Validate the pinned ID-JAG
    run: |
      npx id-jag-validate validate "$(cat id-jag.txt)" \
        --issuer https://idp.example.com/ --audience https://ras.example.com/

The full flag reference lives in the README. The Mint tab mints the same deliberately broken grants that ship as fixtures inside the package - point your own test suite at them to prove it rejects exactly what the draft rejects.