Boku no Potato
Boku no Potato3mo ago

Using Passkey - Webauthn begin login failed WEBAU-4G8sw

Hey! I've been trying to get PassKeys to work with Custom UI for a good while now, but I'm just getting 500 errors when following the documentation. Since we're on Discord and the question, assumption and explanation is too long, you'll find the whole message/explanation as attached as a .txt file 🫠 Thanks!
13 Replies
Rajat
Rajat3mo ago
hi @Boku no Potato thanks for your question, What's the exact domain you're using for the WebAuthN challenge, and does it match your login UI's domain?
Boku no Potato
Boku no PotatoOP3mo ago
I'm testing towards a production instance that we're self-hosting, using https://auth.example.com (just as an example, real domain is different) - this is the domain I used to register the PassKey. The backend service I'm running at http://localhost:1437, meanwhile the frontend is http://localhost:3000. I've tried passing both auth.example.com, localhost and localhost:1437 I haven't tried localhost:3000 as Zitadel never sees that domain.
Rajat
Rajat3mo ago
hey @Boku no Potato You registered the passkey for auth.example.com, but you're loading your login UI from localhost. WebAuthn only works when domain matches exactly. I think you're mixing domains and that’s the root issue and mismatched domains break WebAuthN's origin security.
Boku no Potato
Boku no PotatoOP3mo ago
Thanks for the quick response! So Zitadel won't even return the public key for the WebAuthN challenge if the headers are wrong from the backend service doing the request? Just to clarify, the 500 error occurs when the backend tries to issue a challenge on behalf of the user, it is before the public key gets to the browser and the browser actually validates the public key.
Rajat Singh
Rajat Singh3mo ago
Zitadel won’t generate the WebAuthN challenge at all if the domain field in your session challenge doesn’t exactly matches during the challange. That 500 happens BEFORE the challenge reaches the browser.
Boku no Potato
Boku no PotatoOP3mo ago
Hmm, is it correct that the Origin should be set to "" at this line? https://github.com/zitadel/zitadel/blob/83839fc2eff533611abb2b0a81c09ae65eff94b0/internal/webauthn/webauthn.go#L133 It seems like the serverFromContext method https://github.com/zitadel/zitadel/blob/83839fc2eff533611abb2b0a81c09ae65eff94b0/internal/webauthn/webauthn.go#L184 Checks if the ID == "" and then sets the config for webauthn to use configFromContext which actually fetches the origin from the request context. But if the domain in challenges.webAuthN.domain is set as described in the doc: https://zitadel.com/docs/guides/integrate/login-ui/passkey#create-session Then the serverFromContext is never called and the origin is never set to the origin defined in the request context. Which ultimately means that the rpID will equal example.domain.com and the origin will be "" which would most likely create an error in the webauthn Go library: https://github.com/go-webauthn/webauthn?tab=readme-ov-file#initialize-the-request-handler I believe not setting the challenges.webAuthN.domain or setting it to "" is a workaround as it would then be derived from the x-zitadel-instance-host header?
Rajat
Rajat3mo ago
hi @Boku no Potato good find!. Not setting challenges.webAuthN.domain entirely lets it fetch from headers (assuming x-zitadel-instance-host is correctly set). Can you pls try and test it and let me know?. I think we are looking at a potential bug here. 🐛
Boku no Potato
Boku no PotatoOP3mo ago
Hello again, the workaround doesn't seem to work due to parameter validation invalid RequestChallenges_WebAuthN.Domain: value length must be between 1 and 200 runes, inclusive The error I got seems to be from: https://github.com/zitadel/zitadel/blob/83839fc2eff533611abb2b0a81c09ae65eff94b0/proto/zitadel/session/v2/challenge.proto#L22 However in the Typescript new UI project, setting the headers and setting the domain to "" is done on this line: https://github.com/zitadel/typescript/blob/903bc0545e3d5131ff1cf55f6bdd5fae7a4ab9b9/apps/login/src/components/login-passkey.tsx#L95 I did however find an issue on the Typescript project on: https://github.com/zitadel/typescript/issues/414 that seems to be related. It doesn't seem like I can do much more troubleshooting without actually creating a custom build of Zitadel. Edit: Most likely also related: https://github.com/zitadel/zitadel/issues/8282
Rajat
Rajat3mo ago
hey @Boku no Potato good afternoon and this is nice discovery and seems like a bug like we discussed. Can you please update the https://github.com/zitadel/zitadel/issues/8282 with our findings/discussions and I will let the engineers know about it. Thanks
GitHub
[Bug]: Errors.User.WebAuthN.BeginLoginFailed · Issue #8282 · zita...
Preflight Checklist I could not find a solution in the documentation, the existing issues or discussions I have joined the ZITADEL chat Environment Self-hosted Version 2.55.2 Database PostgreSQL Da...
Boku no Potato
Boku no PotatoOP3mo ago
Can do! I'm a bit swamped until the evening, but I'll post an update then 🙂
Boku no Potato
Boku no PotatoOP3mo ago
GitHub
[Bug]: Errors.User.WebAuthN.BeginLoginFailed · Issue #8282 · zita...
Preflight Checklist I could not find a solution in the documentation, the existing issues or discussions I have joined the ZITADEL chat Environment Self-hosted Version 2.55.2 Database PostgreSQL Da...
Boku no Potato
Boku no PotatoOP3mo ago
@Rajat did you hear anything back from your team? I’m wondering if I should spend more time on my end and make a PR or if it’s something the team will prioritize to fix themselves.
Rajat Singh
Rajat Singh3mo ago
Hey @Boku no Potato we're open source so if you have an idea on how to implement it, please go for it

Did you find this page helpful?