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.
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.
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.
- 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
externaland say what they would need - a validator that claims to decide them from bytes is lying. - Subject identifiers are the trap. A
sub_idthat resolves on thenameidalone 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-jaggrant profile withoutjwt-beareringrant_types_supportedis 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 whichMUSTended it.
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.
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.
npm install id-jag-validate
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
});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
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/