Skip to content

Add support for passkeys to Hypha#4772

Open
frjo wants to merge 34 commits intomainfrom
feature/passkeys
Open

Add support for passkeys to Hypha#4772
frjo wants to merge 34 commits intomainfrom
feature/passkeys

Conversation

@frjo
Copy link
Copy Markdown
Member

@frjo frjo commented Mar 24, 2026

Fixes #4563

This implementation uses duo-labs/py_webauthn: Pythonic WebAuthn directly implementing its own Django wrapper. This is so passkeys are used as a stand alone login method and not as a 2FA option.

The interesting parts are in passkey_views.py and passkeys.js.

Test Steps

  • Test that setting up and logging in with passkeys works on Mac, Windows, iPhone, Android and Linux.
  • Using built in OS support, using usb keys etc.
  • Test that ENFORCE_TWO_FACTOR are bypassed for passkey users. Passkeys are more secure than 2FA.
  • Audit the implementation for any issues.

@frjo frjo added Type: Feature This is something new (not an enhancement of an existing thing). Type: Minor Minor change, used in release drafter labels Mar 24, 2026
@frjo frjo requested a review from wes-otf March 24, 2026 10:17
@wes-otf
Copy link
Copy Markdown
Contributor

wes-otf commented Mar 24, 2026

This is exciting! looking forward to reviewing it in the next day or two!

@frjo frjo force-pushed the feature/passkeys branch from 1fc67c6 to 6a0c0e6 Compare March 27, 2026 14:45
@wes-otf
Copy link
Copy Markdown
Contributor

wes-otf commented Apr 1, 2026

pushing this to test now - is it possible to test locally? getting domain errors trying it on my setup

@frjo frjo temporarily deployed to test-hypha-app April 1, 2026 16:26 Inactive
@wes-otf wes-otf temporarily deployed to test-hypha-app April 1, 2026 16:26 Inactive
@frjo frjo force-pushed the feature/passkeys branch from 6a0c0e6 to 2ef281d Compare April 1, 2026 16:39
@frjo
Copy link
Copy Markdown
Member Author

frjo commented Apr 1, 2026

Test build will likely fail due to migration conflict. Fixed it just now in this branch. More migration conflicts will come, the translation PR have a lot migrations e.g.

If we push this to test and then do not merge this in before translate PR we will have to reset the test db a bit.

@frjo
Copy link
Copy Markdown
Member Author

frjo commented Apr 1, 2026

is it possible to test locally?

Yes, if you set base_url to "localhost". Then it will not require TLS either.

IP 127.0.0.1, hypha.test etc. will not work due to how browsers handle this for security.

This should work:

python manage.py runserver_plus localhost:9001

@frjo frjo added Status: Needs testing Tickets that need testing/qa Status: Needs dev testing 🧑‍💻 Tasks that should be tested by the dev team labels Apr 3, 2026
@frjo frjo force-pushed the feature/passkeys branch from 9fb95fe to 73f6869 Compare April 5, 2026 15:18
@frjo frjo removed Status: Needs testing Tickets that need testing/qa Status: Needs dev testing 🧑‍💻 Tasks that should be tested by the dev team labels Apr 6, 2026
@frjo frjo force-pushed the feature/passkeys branch from 56a48c0 to 0a8e510 Compare April 13, 2026 07:55
@wes-otf
Copy link
Copy Markdown
Contributor

wes-otf commented Apr 15, 2026

left a super minor comment but otherwise this is totally ready to go!

Comment thread hypha/apply/users/templates/users/partials/list.html Outdated
@frjo frjo force-pushed the feature/passkeys branch from 610b26d to 7f85491 Compare April 15, 2026 17:38
@frjo
Copy link
Copy Markdown
Member Author

frjo commented Apr 15, 2026

@wes-otf Good change. Looking at it I came up with some more ways to polish it. The green check is there but when you start typing in the name field the check turns blu with a border so it looks like a button. Clicking it saves and makes it green without a border again.

@frjo
Copy link
Copy Markdown
Member Author

frjo commented Apr 16, 2026

Added some new stuff:

  • The db field is varchar 255 but the length of the name was never checked before saving. Cap it at 128 now.
  • When trying to add another key for the same device, catch the error so it looks nicer for the user.
  • Make all user facing strings translatable. Keep missing this for new code.
  • Get CSRFToken from hxHeaders instead of cookie parsing.
  • Use transaction.atomic for passkeys loggin in the small chance someone tries to use the same key from two devices.
  • Logging errors so admins can track issues.

@frjo frjo force-pushed the feature/passkeys branch from bc10a9e to 32368fd Compare April 16, 2026 10:47
@frjo frjo force-pushed the feature/passkeys branch 2 times, most recently from 4cff425 to fda3ef7 Compare April 21, 2026 19:23
@wes-otf
Copy link
Copy Markdown
Contributor

wes-otf commented Apr 21, 2026

@frjo I think I accidentally force pushed earlier when I intended to force push to the test branch - sorry about that!

The green check is there but when you start typing in the name field the check turns blu with a border so it looks like a button

it looks like the original issue is still there where you can still make the request (by clicking the button) even if the name hasn't been changed. I think it makes things a little less intuitive and could result in an unnecessary request but probably isn't big in the scheme of things.

Everything else looks good to me! Happy to get this merged whenever you feel it's good.

@frjo
Copy link
Copy Markdown
Member Author

frjo commented Apr 22, 2026

@wes-otf Easy to restore the branch so no worry. I think I managed to make the green check not behave like a button now. When you change the name the check turns blue and behave like a button.

Comment on lines +13 to +14
{% heroicon_micro "key" class="inline size-4" aria_hidden=true %}
{% trans "Sign in with passkey" %}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Wondering if we should make this a little more similar to the "Login with password" button in both verbiage and icon.

Like choosing to user either "Sign in" vs "Log in" and the password button uses the heroicon_mini: {% heroicon_mini "key" size=18 class="opacity-80" aria_hidden=true %}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

What do you think about these points @frjo?

frjo and others added 25 commits April 22, 2026 17:21
Co-authored-by: Wes Appler <145372368+wes-otf@users.noreply.github.com>
…idden inputs to data attributes. Handle os errors nicer, like when trying to add a second icloud key.
@frjo frjo force-pushed the feature/passkeys branch from 6f803bb to 88dacdc Compare April 22, 2026 15:21
@wes-otf
Copy link
Copy Markdown
Contributor

wes-otf commented Apr 22, 2026

button layout is nice!

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

Labels

Type: Feature This is something new (not an enhancement of an existing thing). Type: Minor Minor change, used in release drafter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reimplement 2FA to create a smother user flow and add support for passkeys

2 participants