@ver-id/embedded-node-client
v0.2.0
Published
Ver.iD embedded-mode Node.js SDK: PKCE bootstrap + signed webhook verification + token exchange for embedded flows
Downloads
22
Maintainers
Readme
Ver.iD Embedded Node Client
The backend half of Ver.iD embedded mode. This package owns the confidential
side of an embedded flow: it bootstraps PKCE, verifies signed webhooks, and
exchanges the authorization code for tokens — all server-side. The browser half
is @ver-id/embedded-browser-client, which holds
no secrets and never sees the authorization code.
Getting Started
Installation
Using npm in your project directory run the following command:
npm install @ver-id/embedded-node-clientUsing yarn in your project directory run the following command:
yarn add @ver-id/embedded-node-clientUsing pnpm in your project directory run the following command:
pnpm add @ver-id/embedded-node-clientUsage
import { VeridEmbeddedDisclosureClient } from '@ver-id/embedded-node-client';
const client = new VeridEmbeddedDisclosureClient({ issuerUri, clientId });
app.post('/api/verid/start', async (_req, res) => {
const bootstrap = await client.createEmbeddedSession({
scope: 'openid disclosure',
webhookUri: 'https://app.example.com/api/verid/webhook',
});
res.json(bootstrap); // { clientId, scope, state, codeChallenge, webhookUri, gatewayUri }
});
app.post('/api/verid/webhook', express.text({ type: '*/*' }), async (req, res) => {
const result = await client.finalizeEmbedded({
rawBody: req.body,
signature: req.header('x-signature-256'),
secret: process.env.VERID_WEBHOOK_SECRET!,
clientAuth: { client_secret: process.env.VERID_CLIENT_SECRET! },
});
const token = await client.decode(result, assertDisclosureV1JwtPayload);
await store(result.state, token);
res.json({ received: true });
});The same shape applies to VeridEmbeddedAuthenticationClient and
VeridEmbeddedIssuanceClient. For issuance, create an intent first and forward its
intentId via createEmbeddedSession — it is required there and throws
InvalidArgumentError if omitted.
Security
- The
code_verifiernever leaves the backend.createEmbeddedSessionpersists it against thestatein the cache manager and returns only the publiccodeChallengeto the browser. - The authorization code arrives only via the HMAC-verified webhook.
finalizeEmbeddedrejects any webhook whosex-signature-256header does not match an HMAC-SHA256 of the raw body computed with your flow's webhook secret (checked with a timing-safe comparison). - The token exchange sends no
redirect_uri. Embedded flows are registered without one; the authorization code is bound to the client purely through PKCE.
Per-flow guides
For other comprehensive configurations and examples, see the per-flow documents:
- Authentication — server-side embedded authentication with
VeridEmbeddedAuthenticationClient. - Verification — server-side embedded disclosure with
VeridEmbeddedDisclosureClient. - Issuance — server-side embedded issuance with
VeridEmbeddedIssuanceClient(requires an intent).
License
MIT
