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

[Proposal] Authentication Plugin System #1433

Open
KazWolfe opened this issue Jan 30, 2024 · 2 comments
Open

[Proposal] Authentication Plugin System #1433

KazWolfe opened this issue Jan 30, 2024 · 2 comments

Comments

@KazWolfe
Copy link
Member

We've received a number of requests/PRs for various interesting authentication methods (e.g. #1378, #1432, #738, and more), and this is more or less a repost of something posted on one of those Issues.

XIVLauncher may benefit from supporting plugins designed to allow integration with authentication providers. These plugins would provide an API surface for users to add support for their own custom authentication integrations however they see fit.

The primary intent of the authentication plugin system would be to provide a deep connection between XIVLauncher and any given password manager or provider. The API surface should include functionality for:

  • Providing a list of saved accounts from the backend store
  • Providing the credentials (username + password + optionally OTP) from any given backend
  • Retrieving an OTP code from a backend, allowing devs to write their own OTP providers

This would open a number of use cases, such as:

  • Allowing XIVLauncher to grab all Square Enix accounts from 1Password, allowing the user to choose the saved password to use, and logging in with it.
  • Allowing developers to store their (encrypted) credentials backed by a U2F security key rather than the Windows Credential Store.
  • Allowing porting the OTP server feature to its own plugin.

The Authentication Plugin feature should be documented and open for developers to use, although the project can officially support certain "known-good" integrations (e.g. those for 1Password, Bitwarden, and others). A type of "plugin store" should be out of scope for this feature - support is provided only for official integrations, others are supported only provisionally.

This system does have a slight impact to XIVLauncher's security, but I would consider these changes to be a non-issue to a benefit. Password managers feel more secure than the local Windows Credential Store. Developers may choose to implement bad ideas such as plugins with hardcoded OTP secrets, but this is no worse than existing integrations with the currently-existing webserver.

This system would be preferred over the webserver as it's overall simpler and can provide a better experience by removing the need for launch scripts and similar. It would also arguably be more secure, is simpler, and doesn't require firewall management.

@KazWolfe
Copy link
Member Author

KazWolfe commented Jul 3, 2024

Proposed API surface:

Get Accounts

Signature: public async Task<List<SavedAccount>> GetAccounts()

public record SavedAccount {
  public string Username { get; }
  public bool HasMFA { get; }
}

This method would be used to allow the launcher to request a list of all saved accounts registered with that authentication provider. This method would serve to populate a dropdown or some other form of account selector to allow users to easily choose from their saved credentials. This method should not return any sensitive information such as passwords or MFA codes, but may return metadata, e.g. whether a MFA code is present.

Implementation details for this method are provider-specific, and it may not be supported by all providers. When supported, however, plugins should take effort to filter and only return account entries that can reasonably be assumed to belong to FFXIV. As an example, this method should only return password manager entries with a URL matching https://secure.square-enix.com/*.

If the authentication provider does not support accounts (e.g. XLAuth), this method should return an empty list.

Get Credential

Signature: public async Task<SavedCredential?> GetCredential(string username, CancellationToken token = default)

public record SavedCredential {
  public string Username { get; }
  public string? Password { get; }
  public string? MFACode { get; }
}

This method would be used to retrieve information from a provider, and will be called by the launcher after the user has either chosen an account from a dropdown or otherwise initiated a login request.

The authentication plugin will be responsible for implementing username matching to find the specific target credential if necessary.

Both the Password field and MFACode field are optional, and should only be returned if information is present. Providers are not required to return all fields (e.g. XLAuth will never return a password).

As this method is asynchronous, it can be used as the entrypoint for setting up listeners or other servers (e.g. a webserver/mDNS server to request MFA from a phone). Note that if a request is network-based, it is the plugin's responsibility to manage all security (including encryption) for the requests.

Example Flow

XL-Authenticator (MFA App)

  1. User opens XIVLauncher.
  2. XIVLauncher calls GetAccounts() in the XL-Authenticator plugin.
  3. Plugin does not support credentials, so returns [].
  4. User initiates login with SQEX ID DalamudFriend and password, indicating MFA is required.
  5. XIVLauncher calls GetCredential("DalamudFriend").
  6. Plugin launches HTTP server and mDNS server for XLAuth.
  7. User opens XLAuth and sees MFA request for username "DalamudFriend" and approves.
  8. Plugin responds with username and MFA code to XL.
  9. XIVLauncher continues the login flow.

1Password

  1. User opens XIVLauncher.
  2. XIVLauncher calls GetAccounts() in the XL-Authenticator plugin.
  3. Plugin requests all accounts matching domain from 1Password, and returns it.
  4. XIVLauncher displays a dropdown of available accounts.
  5. User chooses the desired account.
  6. XIVLauncher calls GetCredential("DalamudFriend").
  7. Plugin retrieves password and MFA (if necessary) from 1Password.
  8. XIVLauncher continues the login flow.

@goaaats
Copy link
Member

goaaats commented Jul 3, 2024

It would be nice if this was a separate thing to XL and implemented as a C interface. Maybe some other tools also want to take advantage of this if we write a good spec.

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

2 participants