Passkeys in Django: the best of all possible worlds

This video features Tom Carrick at DjangoCon Europe 2025 in Dublin, Ireland.

Passkeys in Django: the best of all possible worlds
0:24:48
Published June 4, 2025
534 views

Talk: Passkeys in Django: the best of all possible worlds by Tom Carrick

https://pretalx.evolutio.pt/djangocon-europe-2025/talk/Q9V9ZR/

Summary

Passkeys use public-key cryptography: the server stores a public key while the private key remains protected by a device, operating system, hardware key, or password manager. Tom Carrick argues they are easier and generally safer than passwords because they resist phishing, guessing, credential stuffing, and password database leaks, and can often replace a separate second-factor step. He shows a Django implementation using `django-otp-webauthn`, including registration, login, passkey management, and bypassing OTP after passkey authentication, while noting usability, recovery, provider-trust, JavaScript, REST, and Django core integration challenges.

Key takeaways

  • Passkeys authenticate with a device-protected private key rather than a password, while the server stores only a public key.
  • They resist phishing, password guessing, credential stuffing, and damage from leaked password databases.
  • A passkey can combine possession of a device with a PIN or biometric and replace a separate OTP-based second-factor step.
  • Users need clear handling for multiple providers, lost devices, passkey deletion, unsupported browsers, and recovery.
  • A Django integration is practical with existing packages, but adding passkeys to Django core would require decisions about JavaScript, REST-style errors and validation, and secure defaults.

Summarised automatically from the transcript.

Chapters

  1. 0:00 Introduction and Audience Survey Tom Carrick introduces the talk and gauges the audience’s experience with Django and passkeys.
  2. 1:30 Passkey Motivation The talk outlines why passkeys can make login easier, improve security, and potentially replace separate two-factor authentication.
  3. 3:01 Passkey Fundamentals A brief explanation covers public-key encryption, supported devices, and hardware security keys.
  4. 3:47 Security Benefits and Trade-offs Passkeys’ resistance to guessing, phishing, credential stuffing, and database leaks is weighed against trust in platform providers and continued password support.
  5. 5:25 Usability and Accessibility The speaker discusses biometrics, PINs, HTTPS and JavaScript requirements, and the challenge of managing passkeys across providers.
  6. 7:52 Passkeys as Two-Factor Authentication Passkeys are examined through the “something you have, know, or are” model, along with their practical limitations.
  7. 9:23 Django Integration The talk demonstrates adding passkey registration and login to Django using templates, JavaScript, and a login button.
  8. 11:42 Passkey Management The speaker covers identifying passkey providers, deleting credentials safely, and skipping traditional two-factor authentication for passkey users.
  9. 14:10 Django Core Integration The discussion turns to whether passkey support belongs in Django core and the JavaScript, error handling, and REST concerns involved.
  10. 17:16 Recommendations and Conclusion Tom encourages developers to offer passkeys, recaps the project, and points attendees to the slides and example code.
  11. 18:59 Questions The audience asks about provider trust, PIN security, device relationships, and single sign-on.

Transcript

3,821 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:00

Speaker 1: Hello? Okay. Alright, thanks for coming. My name is Tom, but I'm not here to tell you my name. I want to talk about pass keys, but first everyone really likes audience participation, so please, if you could raise your hand if you have a Django app deployed somewhere Uh it's a good chunk of the room, I would say. Can you uh give it a lot, please, please. So um keep your hand up if you have pass keys implemented on your site in any way It's that I have I think I see me and maybe three others now -ish

0:45

Speaker 1: Okay, and now keep your hand up if you support passcase as a primary login method, not only for 2FA. And I think I might now be the only hand in the room. So I have a great Oh, sorry. I have one. Almost. Almost? Pretty close. But I feel like I have a good audience then Um so yeah, I'm not gonna talk about anything technical because to be honest I don't really understand the technical details of Web Oth N or Any of it it's a bit scary for me. I'll go into like the tiniest bit that I need to to make the points that I want to make, but I don't really know if um I'm gonna be correct about everything because it's a bit complex.

1:30

Speaker 1: Uh so before I even tell you what they are, for those that don't know, um why you should care is because it makes login easier for In my opinion, basically everyone. Um you also get better security in my opinion. And you can kind of maybe if you want to take that step. replace your existing 2FA step with just a single login with a pass key. And we'll get into each of those three things a little bit. So Um Wodapaskis they if you recognize these images You probably have access to PASKIS, but these are not really PASKIS, but they kind of are.

2:16

Speaker 1: But don't worry about it too much. Basically, if you log into your phone with your face or your laptop with your fingerprint, you can already use these. Yeah, actually one sec I do need to change something. Sorry, I know I have too much stuff open. Don't worry about it. I think I just Have the wrong thing in the wrong wait no I don't you can't see this. Okay, it's perfect. Never mind. Sorry, I'm I'm not the most Technically competent. I will get this okay, I'm I think I'm good.

3:01

Speaker 1: Yeah, okay. So Ah it's no good. Hang on. I'm in the wrong why am I extending the whole thing? This is it, right? Yeah. I'm good. Okay, thank you. Sorry, I'm always So yeah. So the only technical detail I'm really going to get into here is that it's basically your standard public-private key encryption. Your private key lives on your device in theory, but also in other places. And there's a public key and that's what the server gets, more or less. So you don't have to have Apple device, uh this works on Android. There's also Windows Hello. You can apparently do this on Linux, but don't ask me how. And the OG of pass keys are these hardware security keys like UB keys

3:47

Speaker 1: that kind of had the precursors of the standards, I think. So why you want to use them in terms of security? They're very resistant to guessing because there's not really anything to guess unless you want to guess a private key. You can't really fish it because it's only a public key on the server, so they're not getting anything Because there if if you go to some fake website and you put your your fingerprint on your it's not gonna do anything. Uh credential stuffing, which is like an advanced form of guessing, I guess. So You basically take a big password list and try a bunch of stuff. Also not gonna work because there's no password. Um and database leaks, I would say

4:33

Speaker 1: I don't think you should go ahead and just leak your database with fun. But if it happens to get out there, at least there's no passwords in there. It's just a bunch of public keys that don't really matter The problems come when you think about, well, your pass key is now on your iCloud uh account, your your private key. Um do you want Apple to have that? I don't mind personally, but maybe you do. If you don't trust Apple, Google, or your password manager, do you trust yourself to set this up properly yourself and maintain your OS updates and so on And if you still allow passwords on your websites in tandem, that's kind of nice because you get all the benefits of passkeys and all the benefits of passwords, but you also get the the trade-offs uh with both of those.

5:25

Speaker 1: And you can work around this a bit by saying if your user has a passkey setup, then always make them use the pass key, don't let them even use their password. Um but then you get into like there are a few like UX and security trade-offs there. Yeah, so the UX and accessibility is nice. You don't have to remember big passwords anymore You don't really have to deal with the password manager, though you can use a password manager to stick your passkey, private key in. That's fine. And you can also use a authentication method that works well for you. So you can use a pin code, for example, like just a few digits, a bit easier to remember. But your fingerprint

6:12

Speaker 1: Most people have. Most people have a face. So they work for most people and if you don't happen to have a face, then you might have a fingerprint. You'll you probably be okay. A few caveats on usability. Yeah, you need HTTPS for this unless you're using it locally. If your user has JS turned off, it's not gonna work. It's all JS APIs. Um and one usability concern I have seen around the web is um if you like you know you can have your pass keys in Apple, you can have them in Google, you can have them in OnePassword, you can stick them anywhere you want. That's that's really great, but it also means like where is it? Like which one do I use now? Is this one in my Apple keychain? So yeah, I would say pick one you like, stick with it.

7:01

Speaker 1: Yeah, few issues. Like they're difficult to export from some providers. I don't think Apple have a way, Google have a way, but it's not super production-y. Yeah. Um and 2FA, so if you're using email or SMS 2FA, people don't like this, it's not that great. OTP uh works great, it's amazing, but everyone kind of doesn't like using it because it's a bit I think it's clunky anyway. Where I work, all of our customers are really rich, also really old. So getting them to use a authenticator app even to protect like their identity is is a bit tricky So if we think about second factors, uh the the way it's usually described is uh something you have, something you know, something you are, you want two of these, and Paskies

7:52

Speaker 1: usually hit two. So the have is the the device that you're using that has the private key on it or has that private key through your keychain. Something you know could be a pin code, which is usually showed in password. And something you are, some biometric thing like your face or your finger. Um it's quite nice. But these also quickly turn into things that you lost for gotta were. You can easily lose your phone, kinda sucks. You can if it's on a keychain, then you can get it back. Not a huge deal apart from the money You can forget the pin code even though it's shorter. If anyone here goes climbing often, you'll know your fingerprints don't work for a good few hours after, even longer

8:38

Speaker 1: often. Um your face can kind of change a bit. Doesn't happen super often, but it can. And if you're wearing a mask, there's also issues with that. And if you think about it a bit, hardware like YubiKeys are not really a second factor, because it's just a really strong something you have. I think you can maybe add extra authentication steps, but I don't know because I don't have one. So The how is pretty easy. You install the package. You can do this through Olauth, but when I looked, Olauth only had support for MFA. And I wanted it for login. Uh but if we're being realistic, we're probably using of and we also need to add some stuff to settings.

9:23

Speaker 1: After this There's a bit of code, I will admit. So I decided to add this directly into the Django admin just because it was the quickest way to kind of show it. So this is the code you end up with. This is the entire base admin template. Just with some template elements that are kind of like messages that get rendered at various times And uh the template tag just loads a piece of JavaScript. And this is for login. No, this is for registering, sorry. And then for login you also need like a button so people can click it. You don't really need a button, but it's nice to have.

10:10

Speaker 1: And the only difference here really is this you put in your username field into the tag so it knows where it is. And now I'm gonna struggle with technology again. I try to show this. So I think if I go over here I have another tab which is the Django admin with the extra button here. I'll zoom in a bit. Yeah. Now I have to stretch my head around. But we're okay. So I don't have a pass key yet. I haven't set one up, so I'm going to use my very secure password. um ignore Chrome complaining about my uh

10:56

Speaker 1: password being password. And now we have this new amazing beautiful button Uh and I click this, I stick my finger, and now I have a pass key. And now I can log out, I can log in again, and I can log in with a pass key and click the one that I'm actually set up. I think I mean. Um so yeah

11:42

Speaker 1: I wasn't implementing this into a virgin project. I wasn't implementing this at all to be perfectly honest. I gave that test to one of my engineers who did it way better than I ever could have. Who I won't be naming so he has zero social media presence. Um so there are a few little things. So if you want to list your passkeys nicely so people can like you know look at them and see what they've got set up on your site You have to go to this um MDS thing, it's like the FIDO Alliance Metadata Service. It stores a bunch of UUIDs against providers. So does you well There's UUIDs for like Apple, for example, and uh Google, OnePassword, a bunch of others. And this just lets you say, hey, this this passkey that you have registered with us

12:28

Speaker 1: It's your it's the one from your Apple keychain. It's quite it's quite, you know, it's just something we had to like add. The recommendation is you check this once a month, but we just um download the JSON file from somewhere and we're using that and we'll update it at some point. Um you also have to think about deleting pass keys because if you log in with a pass key and then you delete your pass key, you're not logged in anymore. So that's a little bit of a UX issue in my opinion. So we just kind of didn't let people delete the one that they are currently logged in with. And then if they want to delete it, they have to log in with their password, which we do still allow, and then delete it. But why you would delete it before adding a new passkey, I don't know, because PASKEs are really great.

13:20

Speaker 1: One other small problem we had. Um Yeah, so we kind of wanted we still had two FA with like OTP and email and all the others. But we didn't want people to have to do two FA if they have a passkey. So this is basically a decorator that Calls the OTP required from uh Django two-factor authentication package. And it if if you're already verified, which means you've gone through 2FA and we set this when the pass key gets when you log in with the pass key. Then we say, well, if you already have a passkey, then please just, you know, use your passkey. Otherwise, you can use the other methods that you've set up before. So it works fine. It's just yeah, we have to write some code, which is a bit sad.

14:10

Speaker 1: Um so I wanted to talk a bit About if we can get these into Django Core, because that's usually what I like to talk about. Unfortunately, we've had two very compelling arguments that we should be taking things out of core and not putting things into core. This makes me a bit sad. I think, however, I can make a bit of a case for all of the reasons I've mentioned before But also Django builds itself as being secure by default. Ten years ago, we were probably secure by default. Now I think we're

14:55

Speaker 1: Pretty secure by default. In a few years, I think we'll be mm-mm could do better territory. So how do we make this happen? Is the trickier part because, well, there's JavaScript involved. Django doesn't historically have a great story to tell about how you should use JavaScript. And as soon as we add passkeys into the mix, then we we now have A need for a compiling JavaScript story, which is going to be very difficult Um there are a million ways to do it. I think we have some kind of ways already if we just say

15:41

Speaker 1: stick it in your static JS and it's okay. Maybe that's fine. It's what we do in the admin. It's it's okay. Um we also have to do things not everything goes as perfectly as my demo. Sometimes things don't go great. Sometimes the browser doesn't support the pesky. Sometimes There's some weird cause you like logged in a different tab and all these random things can happen. Yeah. So unfortunately What I didn't mention was the package that I mentioned before Django OTP WebAuth N. Has a dependency. That dependency is Django

16:27

Speaker 1: Rest framework. It uses this just to give error messages to the front end through JSON So unfortunately, to get this into Django Core, I also think we need at least a slightly more compelling rest story in core than we have right now. I don't think we need much. I think we need a good way to do validation, good way to do errors. I'm not sure the content negotiation stuff ever has landed yet. I think it hasn't. It hasn't. But yeah, I think I think we can get there. But there's a lot of discussions to be had. Often this would be a time when I or someone else says, hey, let's do this in the sprints.

17:16

Speaker 1: This time I think it's a little tricky. I think the best I can do is let's have some conversations in the sprints and in the corridors tomorrow. Yeah. Sorry. So yeah, I think you should use cla I think you should use passcase just as a user. Like you like , Yeah, okay, maybe you hate Apple, maybe you hate every possible company that could do this. Um Yeah, but I think you either should put a bit more trust in Apple Or set it up yourself or whatever. Whatever you prefer. But in my opinion, they are in most cases better than just the password.

18:02

Speaker 1: And I think you should be offering them to your users and this message especially goes to the people that put their hands down after the second or third question, which I believe is almost everyone And I would like to see these in Django someday. And I have plenty of time for questions, because that's it. I will quickly give a recap of me. I'm this person. I don't use social media. I am on there. I can be found there. Please don't add me there, but I am there. This QR code just goes to uh GitHub repo, which has the slides, and the example project with the uh setup and uh yeah, those two admin templates basically. Um yeah, that's me.

18:59

Speaker 2: Thank you for the talk. You know how to do that. Last pass, I mean one password took loads and loads of VC money and loads of us used them. We know there's this kind of apocalyptic moment coming up as they have to figure out how to get that money back. And you know how like Apple, Google and Microsoft are kind of incentivized to favor their shareholders' needs more than my needs. Every single time we talk about passkeys. I never find a useful answer to this problem here and that seems to be the issue, the fact that all the people I master trust, not sure I should really trust them to do the right thing. Have you found any place organizations who are Who who it's easier for me to trust and feel more comfortable about using them because I don't really trust myself to do this stuff either.

19:46

Speaker 1: Yeah. Um so to be honest, my answer is no My my slight follow-up answer is that people are probably not gonna like this, but I've learned to trust Apple somewhat. So in the UK they recently pulled one of their services because the UK government asked for like a bunch of data and they were like nope. And I think at this point if they backtracked on that that would be such a reputational loss there would be like Yeah, I don't think they would risk it. Um that said things will come along like they always do, right? Um there probably already are things that I just haven't looked into because I'm such an Apple fanboy, I guess Um but yeah, I I think we'll have some solutions.

20:33

Speaker 3: Thanks for the talk. Um I'm wondering Why is a pass key with a PIN number better than a password?

20:42

Speaker 1: Yeah. Because it's tied to your device. You also need the device. You don't put the pin into the website, you put it into your device. And it only works on your device. So this is what uh Windows Hello. I don't know if you use Windows, but if you use Windows and you log in using Windows Hello, it's like a I think it's like a four or six digit passcode. But it only works on that device. You can't log in anywhere else with it. That's basically it.

21:05

Speaker 3: That makes sense. Thanks.

21:08

Speaker 4: When when you uh when you register or create your pass key. Does it have to like validate it or make sure it's valid or does it send to the server run like does it accept a every every key there?

21:29

Speaker 1: So I I don't know enough about technical implementation. Um I don't know if there's validation for the format, probably, but yeah, I don't know. But I haven't run into issues because everything I use behaves itself.

21:48

Speaker 3: Thank you very much. I have heard and I don't know if it's true that when I log into my um MacBook, then how difficult it is for me to log in also depends on whether I've recently logged into my phone or m my watch and and these things talk to each other and they say well He's nearby, he's opened his phone, so you just need to scan his fingerprint this time.

22:12

Speaker 5: You don't need to type in the whole password. I'm not sure if that's even true, to be honest, but if it let's say it is, is that something that we can incorporate into the loop that you showed? These additional layers of trust.

22:29

Speaker 1: I'm not sure is the answer because again I don't know the technical details. What I can tell you is that the the the things I think you might be talking about. So I also have an Apple Watch, Apple Fanboy, of course There is a thing you can turn on where if you have your watch on, then your computer or your iPhone will just unlock itself if it's like right next to it. That might be what you're talking about, but that's purely an Apple thing. I don't think it relates to Web Authenti in any way Other than like yeah, you can maybe log in a bit faster on Apple. But yeah.

22:59

Speaker 4: Hi. Nice talk. Thank you. Can you speak to how that relates to single sign -on? Because By using a sign-on I have pass keys. I can it's just like a different way of the the the chain of authentication is a bit different.

23:16

Speaker 1: Yeah This one I think is a bit tough because I haven't had to implement it at all. So I don't really have much expertise here. Um so are you talking about like SAML or are you talking more about like just signing through Google or or whatever?

23:35

Speaker 4: Yeah. Um I don't know. So I mean you get redirected to another site, you have to trust that site and get redirected back. So that's yeah like UX is Less ideal, but safety-wise it should be similar, right?

23:56

Speaker 1: Yeah, so it's quite good if you want to protect things through your organization that's all under one domain or um Whatever. Um how it interacts with PASCIS, I'm not sure, or even how it should interact with PASKIs, I'm not sure. Um I think that Yeah, it really depends on how that provider signs you in, right? So if you use a passkey with that provider, that's really great. But do you know that they used a passkey when they come to you and do you then need to do two FA through a passkey or T OTP or or one of those things? Yeah, I'm just not sure. I It would be nice if they told you, but I don't know if if they do.

Questions this talk answers

What are passkeys and what devices support them?

Passkeys use public-key cryptography: the private key stays on a device or in a credential manager, while the server stores the public key. They work with device biometrics or PINs on Apple, Android, Windows, Linux, and hardware security keys such as YubiKeys.

Discussed at 3:01

Why are passkeys more secure than passwords?

Passkeys resist guessing, credential stuffing, and phishing because there is no password to guess or submit to a fake site. A database leak exposes public keys rather than passwords or private keys.

Discussed at 3:47

Are passkeys easier to use than passwords?

They eliminate the need to remember long passwords and can use a PIN, fingerprint, or face authentication instead. They require HTTPS and JavaScript, and users may need to decide where to keep their passkeys if they use multiple providers.

Discussed at 5:25

How do I add passkey login to a Django application?

Install a passkey package, configure the necessary settings, add the registration template tag, and add a login button that points to the username field. The talk demonstrates adding these pieces to the Django admin.

Discussed at 8:38

Can passkeys replace two-factor authentication in Django?

Yes. The example marks a user as verified after passkey login, allowing the application to skip OTP or email-based 2FA for that session while retaining those methods as alternatives.

Discussed at 13:20

Will passkey support be added to Django core?

The speaker would like to see passkeys in Django, but says several issues need discussion first, including Django's JavaScript and build story, browser and error handling, and a stronger REST/JSON approach in core.

Discussed at 14:10

Which passkey provider should I trust?

The speaker does not have a definitive provider recommendation and says users must decide whether to trust Apple, Google, a password manager, or themselves. He personally has learned to trust Apple to some extent, while acknowledging that future problems are possible.

Discussed at 19:46

Are passkeys better than passwords when they use a PIN?

Yes, because the PIN is entered on and tied to the user's device rather than on the website. The PIN alone cannot be used to log in from another device.

Discussed at 20:42

Presenters

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos by Tom Carrick

More videos from DjangoCon Europe