Skip to content

Latest commit

 

History

History

logins

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Logins Component

status-img status-img status-img

The Logins component can be used to store website logins (i.e. usernames, passwords, and related metadata) and to sync them between applications using Firefox Sync.

Features

The Logins component offers:

  1. Local encrypted storage of login records (including usernames, passwords, and website metadata).
  2. Basic Create, Read, Update and Delete (CRUD) operations for login data.
  3. Syncing of logins data between applications, via Firefox Sync.
  4. Import functionality from existing login storage (ex: Fx Desktop or Fennec).
  5. Data migration functionality from Fennec to Firefox Preview storage.

The Logins component does not offer, and we have no concrete plans to offer:

  1. Any form-autofill of other UI-level functionality.
  2. Storage of other secret data, such as credit card numbers.

If you'd like to see new capabilities added to this component, please file an issue for discussion, but on the understanding that it may be a lengthy discussion.

Using the Logins component

Before using this component

Products sending telemetry and using this component must request a data-review following this process. This component provides data collection using the Glean SDK. The list of metrics being collected is available in the metrics documentation.

Prerequisites

To use this component for local storage of logins data, you will need to know how to integrate appservices components into an application on your target platform:

To sync logins data between devices, you will additionally need to integrate the FxAClient component in order to obtain the necessary user credentials and encryption keys, and the SyncManager component in order to orchestrate the syncing process.

Core Concepts

  • A login record contains a single saved password along with other metadata about where it should be used. Each record is uniquely identified by an opaque string id, and contains fields such as username, password and origin. You can read about the fields on a login record in the code here.
  • A logins store is a syncable encrypted database containing login records. In order to use the logins store, the application must first unlock it by providing a secret key (preferably obtained from an OS-level keystore mechanism). It can then create, read, update and delete login records from the database.
    • If the application is connected to Firefox Sync, it can instruct the store to sync itself with the user's server-side logins data. This will upload any local modifications as well as download any new logins data from the server, automatically reconciling records in the case of conflict.

Examples

API Documentation

Working on the Logins component

Prerequisites

To effectively work on the Logins component, you will need to be familiar with:

Implementation Overview

Logins implements encrypted storage for login records on top of NSS. The storage schema is based on the one originally used in Firefox for iOS, but with the following notable differences:

  • the queries; they've been substantially modified for our needs here.
  • how sync is performed; the version here allows syncs to complete with fewer database operations.
  • timestamps; iOS uses microseconds, where the Logins component uses milliseconds.

See the header comment in src/schema.rs for an overview of the schema.

Directory structure

The relevant directories are as follows:

  • src: The meat of the library. This contains cross-platform rust code that implements the actual storage and sync of login records.
  • examples: This contains example rust code that implements a command-line app for syncing, displaying, and editing logins using the code in src. You can run it via cargo like so: cargo run --example sync_pass_sql.
  • ffi: The Rust public FFI bindings. This is a (memory-unsafe, by necessity) API that is exposed to Kotlin and Swift. It leverages the ffi_support crate to avoid many issues and make it more safe than it otherwise would be. At the time of this writing, it uses JSON for marshalling data over the FFI, however in the future we will likely use protocol buffers.
  • android: This contains android bindings to logins, written in Kotlin. These use JNA to call into to the code in ffi.
  • ios: This contains the iOS binding to logins, written in Swift. These use Swift's native support for calling code written in C to call into the code in ffi.

Business Logic

Record storage

At any given time records can exist in 3 places, the local storage, the remote record, and the shared parent. The shared parent refers to a record that has been synced previously and is referred to in the code as the mirror. Login records are encrypted and stored locally. For any record that does not have a shared parent the login component tracks that the record has never been synced.

Reference the Logins chapter of the synconomicon for detailed information on the record storage format.

Sign-out behavior

When the user signs out of their Firefox Account, we reset the storage and clear the shared parent.

Merging records

When records are added, the logins component performs a three-way merge between the local record, the remote record and the shared parent (last update on the server). Details on the merging algorithm are contained in the generic sync rfc.

Record de-duplication

De-duplication compares the records for same the username and same url, but with different passwords. Deduplication logic is based on age, the username and hostname:

  • If the changes are more recent than the local record it performs an update.
  • If the change is older than our local records, and you have changed the same field on both, the record is not updated.

Testing

status-img

Our goal is to seek an acceptable level of test coverage. When making changes in an area, make an effort to improve (or minimally not reduce) coverage. Test coverage assessment includes:

Telemetry