Skip to content
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

Question About The Credential Storage Side of the API #1

Open
quexten opened this issue Jan 27, 2024 · 4 comments
Open

Question About The Credential Storage Side of the API #1

quexten opened this issue Jan 27, 2024 · 4 comments

Comments

@quexten
Copy link

quexten commented Jan 27, 2024

Hi,

first of all, thanks a lot for the effort to move these platform APIs forward!

I hope this is the correct place to discuss the draft. Let me know if i should move this to the xdg-desktop-portal issue instead.

From my perspective, I would like to eventually implement these APIs in password managers. ( https://github.com/quexten/Goldwarden, and https://github.com/bitwarden/clients ), with the password managers acting as the credential (password/passkey) store. On Android you can select your preferred password / passkey manager in the settings. Is this something that would be in-scope for this platform API as well, or do we just expect this to be handled by the portal / dbus implementation? (I would prefer the former, so that in the password manager, I just have to implement the dbus registering and provider interface once, and it will be "selectable" easily on all desktop environments).

@Fraetor
Copy link

Fraetor commented Jan 27, 2024

There is also the default case to consider, where the user does not have any password manager. In this case it could be good to use the login keyring (libsecret), as that more reliably exists.

@iinuwa
Copy link
Owner

iinuwa commented Jan 27, 2024

Yes, this is a fine place to ask questions!

I'm focusing on working on the D-Bus spec, so anything to do with implementation will probably be thrown away; I'm doing the bare minimum so I can sketch out the spec. I will probably work with https://github.com/AlfioEmanueleFresta/xdg-credentials-portal or others for more of the implementation.

That being said, I would like to support third-party credential providers, like Bitwarden, etc. (see Scenarios 7 & 8). I haven't worked it out quite yet, but I see two basic scenarios: one where the providers credentials are unlocked and ready for selection, and another where the credentials require user interaction.

Provider unlocked

  1. Provider runs a D-Bus service and registers (somehow) with the platform API.
  2. When the user/client requests a credential, the platform API frontend broadcasts the credential request info to the rest of the providers it knows about.
  3. The provider receives the credential request and responds, within a certain timeframe, with matching credentials.
  4. The platform API frontend gathers all the available credentials (from both the internal storage, and the providers that responded) and sends that to the frontend to display to the user.
  5. The user selects a provider credential.
  6. The backend tells the frontend that the user selected a credential. The backend knows this is a provider credential and forwards the request to sign the assertion or retrieve the password from the credential provider
  7. The backend responds to the client with the credential.

Provider vault locked

This scenario is a little different, when the provider doesn't know whether any credentials match (or doesn't want to reveal that it does), because the user has not authenticated to the provider's vault.

  1. Provider runs a D-Bus service and registers (somehow) with the platform API.
  2. When the user/client requests a credential, the platform API frontend broadcasts the credential request info to the rest of the providers it knows about.
  3. The [locked] provider receives the credential request does not respond.
  4. The platform API frontend gathers all the available credentials (from both the internal storage, and the providers that responded) and sends that to the frontend to display to the user.
  5. The user selects "Other credentials" to show a list of other sources of credentials. The frontend offers the registered providers as potential sources.
  6. The user selects the [locked] provider.
  7. The frontend tells the backend, who tells the provider, that the user wants to open the provider's UI for a credential request.
  8. The provider provides its own UI for unlocking and selecting a credential.
  9. The user unlocks and selects a credential from the provider's UI.
  10. The provider tells the backend which credential was selected.
  11. The backend retrieves the full credential from the provider
  12. The backend responds to the client with the credential.

In these scenarios, the provider would need to:

  • register with the credential manager,
  • implement the "credential matching" request API,
  • implement the "initiate unlocking UI" API
  • (the former implies that actual UI for unlocking/selecting credentials is implemented, but I assume that this already exists for most password managers anyway),
  • be able to call the frontend's "SelectCredential(id)" API, and
  • implement the "GetCredential(id)" API

I think that's a fairly minimal set of requirements. From here, as long as the desktop environment's backend properly shows the third-party provider credentials sent from the backend, that should work across desktop environments.

This still needs refinement, happy for any feedback.

Does that answer your question?

Is this something that would be in-scope for this platform API as well, or do we just expect this to be handled by the portal / dbus implementation?

@quexten, I'm not picking up this distinction; could you clarify? (I think you may be confused by the name of this repo, which is a bit of misnomer, but I've already linked to it in a few places, so the name will stick for now.) "Platform API" here is referring to the portal/D-Bus implementation.

There is also a notion of a platform authenticator, which is a WebAuthn/FIDO2 authenticator built into a platform/device. (I think I made up this term/distinction, so it's probably confusing.) I also want to be able to specify that as well. But if you squint, the platform authenticator is basically just another provider, with some special features (being able to call out to the biometric sensor or TPM, etc.)

In this case it could be good to use the login keyring (libsecret), as that more reliably exists.

@Fraetor, I still haven't decided, but I don't think I'll use the default login keyring for these platform authenticator credentials so I can more precisely control when the keyring is locked or not.

@quexten
Copy link
Author

quexten commented Jan 27, 2024

Thanks for the extensive response! The described flows seem reasonable.

@quexten, I'm not picking up this distinction; could you clarify? (I think you may be confused by the name of this repo, which is a bit of misnomer, but I've already linked to it in a few places, so the name will stick for now.) "Platform API" here is referring to the portal/D-Bus implementation.

I'm not sure if I used the correct terms in this context but I'll try to describe what I mean. From what I read initially in the repo, it seemed to be mostly about the credential consumers (users of passkeys, passwords) not credential stores. If the credential store part is not specified, then for example gnome could decide to implement this as a portal that uses only the gnome keyring, while kde could decide that it has it's own "kde custom credential store dbus interface" that handles the credential gathering across providers as you sketched out above.

Though, looking at it again I think 7/8 cover the password manager use-case. I guess my initial assumption was that each Scenario would have a different API (as in 1 interface "GetPassword", 1 interface "GetPasswordFromProvider"), but that's not actually the case. I might have been confused there.

Anyways, as long as the spec will include some way to support external credential stores (password managers), be it selectable in a settings menu like on iOS or Android, or just gathered across all active credentialstores on the system, I'm happy.

@iinuwa
Copy link
Owner

iinuwa commented Jan 27, 2024

Yeah, I think we're on the same page.

I guess my initial assumption was that each Scenario would have a different API (as in 1 interface "GetPassword", 1 interface "GetPasswordFromProvider"), but that's not actually the case. I might have been confused there.

Yeah, I was using the scenarios to draft what kinds of interactions would be necessary. I think I've gone through all the scenarios that I want to cover (though others may have others/different ones). Now, I'm working on taking the required interactions and turning that into an API.

I'm separating the API into "profiles," which are groups of APIs required to make a certain scenario work. This is to organize it so that a base set of features will work, but as an implementation becomes more mature, it can implement the other profiles in an order that leads to getting an actual feature shipped. (You can watch api.md for updates on that if you're interested.)

Thanks again for taking the time to look at it. It's really not organized since I can only work on this at night while stirring a pot of chili. :) I hope I can get something coherent together soon though.

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

No branches or pull requests

3 participants