Skip to content

feat: support multiple passkeys per user - #11

Merged
treeder merged 5 commits into
mainfrom
support-multiple-passkeys
Sep 2, 2026
Merged

feat: support multiple passkeys per user#11
treeder merged 5 commits into
mainfrom
support-multiple-passkeys

Conversation

@treeder

@treeder treeder commented Sep 2, 2026

Copy link
Copy Markdown
Owner

Summary

Adds multi-passkey support per user:

  • Passkeys.new: Populates excludeCredentials from the user's existing passkeys in KV to prevent registering duplicates of the same authenticator.
  • Passkeys.create: Appends the new passkey to user.passkeys (or updates an existing credential by ID) instead of overwriting the array.
  • Passkeys.verify: Updates passkey counters in both passkeys-${id} and users-${userId}.
  • Tests: Adds unit test suite in test/test_passkeys_multi.js testing single, multi-passkey, and legacy user states.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Sep 2, 2026

Copy link
Copy Markdown

Deploying passkeys with  Cloudflare Pages  Cloudflare Pages

Latest commit: 225dd56
Status:⚡️  Build in progress...

View logs

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review Summary

This pull request adds support for multiple passkeys per user across registration, authentication, and session handling. It correctly prevents duplicate authenticator registrations via excludeCredentials, maintains a collection of passkeys under the user record in KV storage, updates counters on verification, and introduces comprehensive unit tests for multi-passkey scenarios.

🔍 General Feedback

  • The multi-passkey implementation is clean and handles backwards compatibility well for legacy user records missing the passkeys array.
  • Consider adding test/test_passkeys_multi.js to package.json scripts (e.g. as a pre-test or unit test step in CI) so that these unit tests are executed automatically alongside integration tests during workflow runs.
📊 Token Usage & Cost Efficiency
Metric Value
Input Tokens (uncached) 6,739
Input Tokens (cached) 23,618 (⚡ 77.0% cached)
PR Comments History Tokens 313
Output Tokens 182
Total Session Tokens 33,225
Cost (uncached input) $0.0053
Cost (cached input) $0.0018
Cost (output) $0.0007
Estimated Total Cost $0.0077

Gemini 3.7 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.7 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review Summary

This pull request introduces support for multiple passkeys per user, correctly populating excludeCredentials during registration to prevent duplicate authenticator enrollment. It also ensures user records maintain an array of passkeys and updates counters appropriately upon successful authentication, backed by dedicated multi-passkey unit tests.

🔍 General Feedback

  • The implementation of excludeCredentials in Passkeys.new() conforms well with WebAuthn best practices to prevent users from accidentally re-registering an already bound authenticator.
  • Handling of legacy user records lacking the passkeys array is robust across new(), create(), and check() methods.
  • The addition of test/test_passkeys_multi.js provides good unit coverage for both new and existing credential scenarios.
📊 Token Usage & Cost Efficiency
Metric Value
Input Tokens (uncached) 3,668
Input Tokens (cached) 27,584 (⚡ 87.4% cached)
PR Comments History Tokens 313
Output Tokens 194
Total Session Tokens 35,187
Cost (uncached input) $0.0030
Cost (cached input) $0.0021
Cost (output) $0.0007
Estimated Total Cost $0.0058

Gemini 3.7 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.7 Flash: standard tier; batch and flex are half again, priority is higher.
Cache reads are priced here, but context-cache STORAGE, where the model charges for it separately per token-hour, is not included, so the figure can run slightly low.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review Summary

This pull request introduces support for multiple passkeys per user account and updates the registration flow to populate excludeCredentials. Existing user credentials are now stored in an array under the user profile in KV, preventing duplicate registrations for already registered authenticators while updating credential counters across authentication events. The changes are accompanied by dedicated unit tests and a major version bump to 5.0.0.

🔍 General Feedback

  • Great implementation of multiple passkey support and authenticator exclusion. The data structures handle backwards compatibility gracefully for legacy user records missing the passkeys property.
  • Comprehensive unit tests in test/test_passkeys_multi.js effectively cover legacy record migration, exclusion list population, and count checks.
📊 Token Usage & Cost Efficiency
Metric Value
Input Tokens (uncached) 27,228
PR Comments History Tokens 313
Output Tokens 177
Total Session Tokens 29,793
Cost (uncached input) $0.0207
Cost (output) $0.0007
Estimated Total Cost $0.0213

Gemini 3.7 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.7 Flash: standard tier; batch and flex are half again, priority is higher.

@treeder
treeder merged commit dbce6b5 into main Sep 2, 2026
3 of 4 checks passed
@treeder
treeder deleted the support-multiple-passkeys branch September 2, 2026 02:54

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📋 Review Summary

This pull request adds support for multiple passkeys per user account and prevents re-registering existing authenticators by populating excludeCredentials during registration. It also introduces comprehensive unit tests for multi-passkey workflows and applies Prettier code formatting across the repository.

🔍 General Feedback

  • The implementation for multiple passkey registration cleanly handles legacy user records missing the passkeys array.
  • The addition of test/test_passkeys_multi.js with isolated KV mocking provides good test coverage for the new multi-passkey logic.
  • Updating credential counter values in both passkeys-{id} and users-{id} records keeps authentication metadata consistent.
📊 Token Usage & Cost Efficiency
Metric Value
Input Tokens (uncached) 30,537
PR Comments History Tokens 313
Output Tokens 173
Total Session Tokens 33,698
Cost (uncached input) $0.0231
Cost (output) $0.0006
Estimated Total Cost $0.0238

Gemini 3.7 Flash: introductory rate $0.75/$3.75 per 1M applied; reverts to $1.5/$7.5 after 2026-12-31.
Gemini 3.7 Flash: standard tier; batch and flex are half again, priority is higher.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant