Case Studies

This page (under construction) contains some pointers to existing use cases and implementations.

Search configuration

The list of search engines is managed via the search-config collection.

Configuration

  • A complex JSON schema validates entries (source)

  • On the server, the group of editors is different from the group of users allowed to approve changes (permissions)

Implementation

  • Client is initialized from the Search service (source)

  • Initial data is packaged in release, and is loaded on first startup from a call to .get() (source)

  • A hijack blocklist is managed separately, and the integrity/signature of the local records is verified on each read (source). A certificate might have to be downloaded if missing/outdated.

Misc

Normandy Recipes

The list of ongoing experimentations is managed via the normandy-recipes-capabilities collection.

Implementation

  • Synchronization happens on first startup because no initial data is packaged:

    • Normandy.init() in BrowserGlue (source)

    • Calling .get() with implicit syncIfEmpty: true option will initialize the local DB by synchronizing the collection for Normandy (source)

  • In order to guarantee that the records are published from Normandy, each record is signed individually on the server side (source). Records are published from Django using kinto-http.py.

  • Signature verification for the whole collection is done as usual, and the per-record one is verified on read when recipe eligibility is checked (source)

Configuration

  • Multi signoff is disabled (config)

  • A scheduled task backports certain recipes into a legacy collection for old clients (source, config)

Misc

HIBP Monitor Breaches

The list of websites whose credentials database was leaked is managed via the fxmonitor-breaches collection.

Automation

  • A script pulls from Have I Been Powned API, and creates the missing records using a Kinto Account, and then requests review (source)

  • This script is ran by OPs as a cron job (source, request ticket)

  • A human approves the changes manually

Blocklist

The list of blocked addons is managed via the blocklists/addons-bloomfilters.

Implementation

Addons blocklist implemented using a bloomfilter (docs)

  • Bloomfilters are published from a Cron job on the addons-server, implementated using raw Python requests (source)

  • Incremental updates of bloomfilters are downloaded as binary attachments, full or base + stashes (source)

  • Attachments are stored in IndexedDB thanks to the useCache: true option (source)

  • When using the attachment IndexedDB cache, attachments can be packaged in release in order to avoid downloading on new profiles initialization. The bloomfilter base attachment is shipped in release along with its record metadata (source)

  • Attachments are updated in tree regularly using custom code in periodic_file_updates.sh (source)

Misc

User Journey

Contextual features recommandations is managed via the cfr collection.

Localization

  • Contextual recommandations are published using translatable placeholders or string IDs

"content": {
  "icon": "chrome://browser/skin/notification-icons/block-fingerprinter.svg",
  "text": {
    "string_id": "cfr-doorhanger-fingerprinters-description"
  },
  "layout": "icon_and_message",
  "buttons": {
    "primary": {
      "event": "PROTECTION",
      "label": {
        "string_id": "cfr-doorhanger-socialtracking-ok-button"
      },
      "action": {
        "type": "OPEN_PROTECTION_PANEL"
      }
    },
    ...
  • In parallel, localizations are published in a separate collection

  • Each locale has its own record, with its ID in the following format `` cfr-v1-${locale} `` and a Fluent file attached.

  • A specificly instantiated downloader fetches the relevant one and reloads l10n (source)

  • This specific record is checked on each load, attachment is downloaded only if updated/missing/corrupted (built-in feature of attachment downloader)

Security State

Several security related collections are managed in the dedicated security-state bucket.

Configuration

  • Dedicated bucket in order to have specific content signature certificates

const OneCRLBlocklistClient = RemoteSettings(
  Services.prefs.getCharPref(ONECRL_COLLECTION_PREF),
  {
    bucketNamePref: ONECRL_BUCKET_PREF,
    lastCheckTimePref: ONECRL_CHECKED_PREF,
    signerName: Services.prefs.getCharPref(ONECRL_SIGNER_PREF),
  }
);

source

Cert Revocations (CRLite)

Certificates revocation list using a bloomfilter.

  • Sysops run a scheduled job that pulls data from a Git repo, authenticates using a Kinto account to publish (account:crlite_publisher), and approves changes with another one (account:crlite_reviewer) (source)

  • Download of attachments happens sequentially at the end of first sync (caution)

  • Incremental updates of bloomfilters are downloaded as binary attachments in profile folder (source)

  • Poucave check for age of revocations (source).

Intermediates

  • Download of attachments sequentially at the end of first sync (caution)