Before you start
You need:- An AIR Developer Dashboard account and Partner ID, with verifier functionality enabled
- A web app with its origin registered in the Dashboard
- A public HTTPS JWKS endpoint registered for your Partner ID
- A server endpoint that signs short-lived Partner JWTs with
scope: "verify" - A test holder with a matching credential from an issuer accepted by your program, or access to that issuer’s claim flow
- A supported Node.js version for your web framework and AIR Kit
Step 1: Configure a verification program
- Open the Sandbox Developer Dashboard and copy your Partner ID from Account → General Settings.
- Under Verifier → Programs, create a program and select the accepted schema and issuer configuration.
- Select
SD_JWT_VCas the accepted proof type and choose the claims to request. - Publish or apply the program so it is active, and copy its verification program ID.
Step 2: Configure Partner authentication
The code below uses a Next.js app. Keep the private key on the server, including during local development.app/api/verification-token/route.ts
kid. If your registered
key uses a different kid, use that value in the token header.
Step 3: Initialize AIR Kit and start verification
Call this helper from a browser event handler, such as your Verify button:lib/verify-credential.ts
redirectUrl pointing to that issuer’s claim page.
Step 4: Obtain consent and handle the result
During verification, AIR Kit:- Finds matching credentials. If none exist, the user needs to complete an accepted issuer’s issuance flow before verification can succeed.
- Fetches and decrypts the credential on the holder’s device.
- Shows the requested data and asks the user to consent.
- Records consent and generates the presentation. For a holder-bound credential, the holder signs a key-binding JWT over your nonce.
- Returns the outcome to your app.
Compliant check runs in the browser, and the presentation wrapper is not
signed. Your /api/verify-presentation route must verify the SD-JWT inside it:
issuer signature, disclosures, expiry, credential type, and the key-binding JWT
against your nonce and programId. Then it deletes the nonce. Follow
Verify SD-JWT on your backend, which
includes a reference implementation.
Step 5: Test the integration
Test with a matching credential, a credential that fails the requested condition, and a user who declines consent. Confirm your app handles missing credentials, expired tokens, and failed requests without granting access. Also confirm your backend rejects a replayed presentation (same nonce twice), a presentation made for anotherprogramId, and a presentation with a disclosure
removed.
Troubleshooting
Next steps
- Verification reference
- Verify SD-JWT on your backend
- Architecture and data flow
- Credential issuance quickstart, if you also operate an issuer