Skip to main content
A JWKS (JSON Web Key Set) endpoint publishes the public key that matches the private key you sign Partner JWTs with. AIR fetches it to check every Partner JWT, so credential calls fail until it is live and registered.

How AIR uses your JWKS

If AIR cannot fetch your JWKS, or no key in it matches the JWT’s kid, the request fails with 401.

Step 1: Implement the route

This Next.js route is the one used by every issuer and verifier app in air-examples. It converts your public key from PEM to JWK with jose and sets kid to your Partner ID.
app/api/.well-known/jwks/route.ts
Required environment variables (server-side only — never expose PARTNER_PRIVATE_KEY): Generate the key pair as described in SDK authentication.

Step 2: Register the URL in the Dashboard

  1. Open the Developer Dashboard.
  2. Go to Account → General Settings.
  3. Paste the full HTTPS URL into JWKS URL, for example https://app.example.com/api/.well-known/jwks, and save.
AIR fetches exactly this URL, with no path discovery or fallback. Register the path your app actually serves: /api/.well-known/jwks for the route above, or whatever route you defined yourself. Each Partner ID has one JWKS URL. If your issuer and verifier apps share a Partner ID, register one JWKS and sign all Partner JWTs with a kid it contains. If you need separate JWKS per service, request a second Partner ID.

Step 3: Match the kid

The kid in each Partner JWT header must appear as a keys[].kid in your JWKS. The examples use your Partner ID for both. If you use another convention, such as key-rotation IDs, the rule is the same. Check the endpoint before you call the SDK:

Local development (HTTPS tunnel)

To test any AIR Kit flow locally, always run your app behind an HTTPS tunnel. AIR Kit only runs on HTTPS origins whitelisted under Account → Domains.
  1. Start your dev server, then expose it over public HTTPS with a tunnel (examples below).
  2. Whitelist the tunnel domain, such as https://abc123.ngrok.app, under Account → Domains. AIR Kit refuses to load on any origin that is not whitelisted there.
  3. Register the tunnel’s JWKS URL as your JWKS URL.
  4. Open your app at the tunnel URL and test from there.
Most free tunnels assign a new URL each time they restart. When the URL changes, whitelist the new domain, remove the old one (the list holds up to 3 domains), and update the JWKS URL. A reserved or static tunnel domain avoids this. If you also tunnel an issuer backend, its host is part of your issuer DID; see Issuer backend hosting.
Whitelist https://abc123.ngrok.app under Account → Domains, register https://abc123.ngrok.app/api/.well-known/jwks as the JWKS URL, and open https://abc123.ngrok.app.

Troubleshooting

If AIR still rejects your Partner JWT, see Common issues: