"Sign in with eHerkenning" via standard OAuth 2.0 / OIDC. PKCE public-client flow, in-browser only.
import { Issuer, generators } from 'openid-client';
const issuer = await Issuer.discover('https://eherk.nl');
const client = new issuer.Client({
client_id: 'your-client-id', // request via beta@eherk.nl
redirect_uris: ['https://yourapp/callback'],
response_types: ['code'],
token_endpoint_auth_method: 'none', // public client + PKCE
});
const codeVerifier = generators.codeVerifier();
const codeChallenge = generators.codeChallenge(codeVerifier);
const authUrl = client.authorizationUrl({
scope: 'openid profile chamber_of_commerce',
code_challenge: codeChallenge,
code_challenge_method: 'S256',
});
// redirect user to authUrl — they come back to your callback with ?code=...
const tokenSet = await client.callback(redirectUri, params, { code_verifier: codeVerifier });
// tokenSet.id_token contains: chamber_of_commerce, organisation,
// eherkenning_service_uuid, eherkenning_level, transaction_id, acr
{
"iss": "https://eherk.nl",
"sub": "urn:eherk:sub:abc123...",
"aud": "your-client-id",
"exp": 1777230000,
"iat": 1777228200,
"auth_time": 1777228195,
"acr": "loa:substantial", // EH3 → substantial, EH4 → high
"amr": ["eherkenning_broker_mock"], // becomes "eherkenning" with real upstream
"chamber_of_commerce": "12345678", // 8-digit KvK number, plain string
"organisation": "Acme Beheer B.V.",
"eherkenning_service_uuid": "urn:nl:eherkenning:service:bewijskluis:demo",
"eherkenning_level": "EH3", // NL-specific level (Signicat-aligned)
"transaction_id": "tx-..."
}
https://eherk.nl/.well-known/openid-configuration · /jwks
Beta: mock upstream. Real Signicat eHerkenning broker arrives once the contract activates.