Upgrade Next for PostCSS, drop vulnerable drizzle-kit/esbuild and eslint-config-next braces chains, and switch linting to typescript-eslint. Co-authored-by: Cursor <cursoragent@cursor.com>
Nitrokey 3C NFC Demo
A self-hosted Next.js demo for registering and authenticating with a Nitrokey through WebAuthn. It also includes educational guides and a lab for trying different WebAuthn options.
Run locally
cp .env.example .env
npm install
npm run dev
Open http://localhost:3000.
For a production build:
npm test
npm run build
npm start
Run with Docker
Generate a session secret and start the app:
SESSION_SECRET=$(openssl rand -hex 32) docker compose up --build
The app is available at http://localhost:3000.
SQLite data persists in the nk_data Docker volume. Stop the app with
docker compose down; add --volumes only when you also want to delete its
stored users and credentials.
For a real hostname, configure RP_ID and RP_ORIGIN in
docker-compose.yml (or your deployment platform) to match that hostname.
WebAuthn and HTTPS
WebAuthn requires a secure context. Browsers treat http://localhost as secure
for local development, but a network address or production hostname must use
HTTPS. RP_ORIGIN must exactly match the public origin (including scheme and
port), and RP_ID must match its domain. NFC testing on a phone normally
requires an HTTPS deployment reachable by that device.
Troubleshooting
If you lose your only security key, this demo cannot recover its private key. While signed in, register the same username again to add a second credential; signed-out users cannot add credentials to an existing account.
Manual Nitrokey checklist
Use a real Nitrokey 3C NFC and a supported browser/operating system:
- Register a new credential via USB.
- Log out, then log in via USB.
- Log out, then log in via NFC.
- Cancel the UV/PIN prompt and confirm a friendly retry message appears.
- In Lab, complete a flow with user verification set to required.
- Log out and confirm protected pages no longer expose the session; also confirm an expired session requires a new login.