Skip to content

[Browser MFA] Split validation out of Finish function#63978

Closed
danielashare wants to merge 5 commits into
masterfrom
danielashare/browser-mfa-webauthn-validation
Closed

[Browser MFA] Split validation out of Finish function#63978
danielashare wants to merge 5 commits into
masterfrom
danielashare/browser-mfa-webauthn-validation

Conversation

@danielashare
Copy link
Copy Markdown
Contributor

@danielashare danielashare commented Feb 19, 2026

This PR extracts the validation logic out of the WebAuthn finish function. This allows the Browser MFA flow to validate a WebAuthn response it gets from the browser before sending it to tsh to be consumed. The RFD for this addition can be found here.

Manual tests:

  • Login with Passkey
  • Login with TouchID
  • Login with YubiKey
  • Passwordless with Passkey
  • Passwordless with TouchID
  • Passwordless with YubiKey

@danielashare danielashare self-assigned this Feb 19, 2026
@danielashare danielashare added the no-changelog Indicates that a PR does not require a changelog entry label Feb 19, 2026
Copy link
Copy Markdown
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

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

I appreciate the small, focused PR. Thanks!

This doesn't need to depend on danielashare/browser-mfa-proto - if you drop those commits it can land on its own.

Comment thread lib/auth/webauthn/login.go Outdated
Comment thread lib/auth/webauthn/login.go Outdated
Comment thread lib/auth/webauthn/login_test.go Outdated
Comment thread lib/auth/webauthn/login_test.go Outdated

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := webLogin.Validate(ctx, test.user, test.createResp(), test.exts)
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.

Similarly, should we piggy back this onto TestLoginFlow_Finish_errors? That's even simpler with "createResp" being a func.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

As above, combined the two

Comment thread lib/auth/webauthn/login_test.go Outdated
Comment thread lib/auth/webauthn/login_test.go Outdated
Comment on lines +1564 to +1565
// Validate should succeed and not consume the session.
err = webLogin.Validate(ctx, user, assertionResp, &mfav1.ChallengeExtensions{
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.

Is this test covering a meaningful scenario?

Is a reusable session any different from a "normal" one? Do we expect multiple Validate calls for a reusable session?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it wouldn't be validated twice, I removed this test

@danielashare danielashare changed the base branch from danielashare/browser-mfa-proto to master February 20, 2026 07:32
@danielashare danielashare force-pushed the danielashare/browser-mfa-webauthn-validation branch from 9f7bc17 to dd9ef28 Compare February 20, 2026 07:32
Copy link
Copy Markdown
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

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

Please take a look at the test failures.

Comment thread lib/auth/webauthn/login_mfa.go Outdated
user string,
resp *wantypes.CredentialAssertionResponse,
requiredExtensions *mfav1.ChallengeExtensions,
validateOnly bool,
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.

Just to clarify, I was OK keeping the public variants of Finish and Validate. The refactor was more about having them both delegate to the private finish func.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

That's cleaner, added

Comment thread lib/auth/webauthn/login_test.go Outdated
Comment on lines +317 to +319
exts: &mfav1.ChallengeExtensions{
Scope: mfav1.ChallengeScope_CHALLENGE_SCOPE_LOGIN,
},
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.

Pull into okExts (or some other name) and reuse throughout?

Suggested change
exts: &mfav1.ChallengeExtensions{
Scope: mfav1.ChallengeScope_CHALLENGE_SCOPE_LOGIN,
},
exts: okExts,

@danielashare danielashare changed the base branch from master to danielashare/browser-mfa-proto February 23, 2026 11:38
@danielashare danielashare force-pushed the danielashare/browser-mfa-webauthn-validation branch from 1b45bb0 to 9290713 Compare February 23, 2026 11:40
@public-teleport-github-review-bot
Copy link
Copy Markdown

@danielashare - this PR will require admin approval to merge due to its size. Consider breaking it up into a series smaller changes.

@danielashare danielashare force-pushed the danielashare/browser-mfa-webauthn-validation branch 4 times, most recently from 6a05b78 to a1f454e Compare February 23, 2026 13:16
@danielashare
Copy link
Copy Markdown
Contributor Author

Apologies for the mass review ping, attempted git surgery did not go well

Copy link
Copy Markdown
Contributor

@codingllama codingllama left a comment

Choose a reason for hiding this comment

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

Looks great, thanks Dan!

Comment thread lib/auth/webauthn/login_test.go Outdated
}
}

func (f *fakeIdentity) clone() *fakeIdentity {
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.

If this were a clone function in prod code, I'd probably ask for some kind of fuzz test to ensure new fields that are added are covered. As this is test code, that seems unnecessary - but we could add a short note where the struct is defined to remind other engineers in future that they may need to update the clone.

Copy link
Copy Markdown
Contributor

@strideynet strideynet left a comment

Choose a reason for hiding this comment

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

Looks good - thanks for running manual tests 👍

@public-teleport-github-review-bot public-teleport-github-review-bot Bot removed the request for review from tele-lion February 25, 2026 17:35
@danielashare danielashare force-pushed the danielashare/browser-mfa-webauthn-validation branch from a25407d to b344b73 Compare February 28, 2026 01:49
@danielashare
Copy link
Copy Markdown
Contributor Author

Closing due to double validation requirement being dropped in #63873

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

Labels

backport/branch/v18 no-changelog Indicates that a PR does not require a changelog entry size/md

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants