Skip to content

Implement credential selection #43

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Jun 13, 2025

Conversation

msirringhaus
Copy link
Contributor

Couple of notes:

  • Hybrid isn't supported yet. If the rest of the PR is acceptable, it should be relatively easy to copy the USB-handling over to Hybrid.
  • There are lot places that reference selected_credential, which I'm not sure is needed at all (see various todo-comments in this PR). I haven't removed all of that yet, as I wanted to have confirmation first, but I don't think it's used anywhere.

}
AuthenticatorResponse::CredentialsAsserted(get_assertion_response) => {
CredentialResponse::from_get_assertion(
// TODO: Implement credential selection for hybrid
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm thinking about this now: I don't think we need credential selection for hybrid, since the authenticator is capable of displaying it's own UI. For hybrid, I think we can assume it's just returning one for now and just leave a comment in case some hybrid authenticator without a display ever appears in the wild.

.assertions
.iter()
.map(|x| Credential {
id: x
Copy link
Collaborator

@iinuwa iinuwa Jun 12, 2025

Choose a reason for hiding this comment

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

This will need to be used as a handle for the UI to return which credential the user selected. So this should return an error (unwrap is fine for now) rather than mapping to a non-unique string.

Separately, I think we should use an opaque ID here so that the credential ID is not leaked to the (untrusted) UI code.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good catch regarding the <unknown>-fallback!
I also hashed the ID now, before sending it.

@iinuwa
Copy link
Collaborator

iinuwa commented Jun 12, 2025

There are lot places that reference selected_credential, which I'm not sure is needed at all (see various todo-comments in this PR).

Yeah, I put on a bunch of variables hoping to be able to derive the UI components declaratively from the current state, but raw GTK doesn't quite work that way, and I haven't put much effort into getting there. We could probably get rid of quite a few state variables since it's ultimately imperative. Also, up until recently, the UI code "owned" the data that would be sent back via D-Bus, but it doesn't anymore, and it properly belongs to the credential service now. So I think the selected credential field in the UI is doubly-irrelevant.

You've also hit my trap: I named these things poorly and so it's all mixed up. Currently, the first screen in the flow is to choose a transport or device. This is mainly because we don't know what credentials are available ahead of time. (With a platform authenticator and third-party passkey providers, we could know the stored credentials that match the request ahead of time, so this first screen may also eventually allow selecting a specific credential.) I've poorly named the GTK stack page for this choose_credential. That should probably be renamed to something like choose_authenticator or something.

This feature is actually selecting between different attested credentials, not available transports/devices. So for this feature, we should create a separate page, probably taking the existing name choose_credential or maybe confirm_credential?, that receives a list of attested credentials that the user should be promoted to choose from. (The page screen should say something like "We found multiple matching credentials on this device, which would you like to use?" with the list of credential metadata.) When the user selects one, that will need to send a message back to the credential service with the ID of the specific credential to send back to the client. That means the credential service will have to store the attested credentials and wait for the UI code to confirm before releasing.

One thing to note is that the UI code is considered untrusted, so we should only send minimal data to the UI. I haven't considered the privacy implications of the credential IDs: whether the IDs would be any more useful to an attacker that has compromised the UI code than the username and other metadata already included. If none, sending the credential ID would probably be fine, though an opaque identifier could prevent mistakes like the UI returning a completely separate credential ID and somehow tricking the credential service into returning it. (E.g., if we used the same mechanism for selecting a credential out of the platform authenticator.)

Sorry for all the confusion. All on me.

Edit: Remove nonsense about misnamed stack page.

@iinuwa
Copy link
Collaborator

iinuwa commented Jun 12, 2025

Ah, scratch some of that. Now that I'm reading this on a laptop and not on mobile, I see more clearly what's going on. choose_credential is the correct view to use here. We don't need to store selected_credential, we just need the UI to send the ID of the selected credential and wait for the Completed state.

@msirringhaus
Copy link
Contributor Author

I hashed the credential ID now, before sending it to the UI.
And I removed the whole selected_credential stuff.

Copy link
Collaborator

@iinuwa iinuwa left a comment

Choose a reason for hiding this comment

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

This looks good, thank you!

@iinuwa
Copy link
Collaborator

iinuwa commented Jun 13, 2025

Closes #30.

@iinuwa iinuwa merged commit dbce932 into linux-credentials:main Jun 13, 2025
1 check passed
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.

3 participants