Personal tools

Services/Sync/Features/Addon Sync

From MozillaWiki

< Services | Sync(Difference between revisions)
Jump to: navigation, search
m (moved Services/Sync/Addon Sync to Services/Sync/Features/Addon Sync: Feature pages go under /Features)
 
(32 intermediate revisions by 6 users not shown)
Line 1: Line 1:
 
{{FeatureStatus
 
{{FeatureStatus
 
|Feature name=Addon Sync
 
|Feature name=Addon Sync
|Feature stage=Definition
+
|Feature stage=Landed
|Feature status=In progress
+
|Feature status=Complete
|Feature version=TBD
+
|Feature version=Firefox 11
|Feature health=Blocked
+
|Feature health=OK
|Feature status note=Product Management needs to flesh out the feature page so that development can be unblocked.
+
|Feature status note=Feature landed in Firefox 11.
 
}}
 
}}
 
{{FeatureTeam
 
{{FeatureTeam
Line 12: Line 12:
 
|Feature lead engineer=Gregory Szorc
 
|Feature lead engineer=Gregory Szorc
 
|Feature security lead=Yvan Boily
 
|Feature security lead=Yvan Boily
|Feature localization lead=Axel Hecht
 
 
|Feature qa lead=Tracy Walker
 
|Feature qa lead=Tracy Walker
|Feature ux lead=Alex Faaborg
 
 
|Feature product marketing lead=Jaclyn Fu
 
|Feature product marketing lead=Jaclyn Fu
 
|Feature additional members=Ibai Garcia (SUMO)
 
|Feature additional members=Ibai Garcia (SUMO)
 
}}
 
}}
 
{{FeaturePageBody
 
{{FeaturePageBody
|Feature overview=Add-ons are synchronized between sync clients.
+
|Feature open issues and risks=<table border=1>
|Feature users and use cases=User installs an add-on on one browser. When a sync occurs, the add-on is automagically installed on other sync clients.
+
<tr valign="top" bgcolor="#AAAAAA">
|Feature functional spec=The Addon Manager maintainers would like to see Sync support all add-on providers so as to not introduce 1st and 2nd class providers. This will require some APIs.
+
  <td>Issue/Risk</td>
 +
  <td>Status</td>
 +
</tr>
 +
<tr valign="top">
 +
  <td>
 +
Do we need some prompts or feedback when add-ons are synced, at all?
 +
  </td>
 +
  <td>
 +
Probably. Many add-ons still aren't restartless, so installing, uninstalling, enabling, or disabling will require restart. When Sync is driving the add-on install, the Add-on Manager won't display any visual prompts. So, it will be Sync's responsibility to trigger a UI element to prompt restart, if desired. Sync has full control over that element. We could display the one used by the Add-on Manager or make our own.
 +
<br/>Answer from Faaborg: Is we do not need any extra UI. If the user happens to go to the Add-ons tab, the updated add-ons should show a restart is necessary.
 +
  </td>
 +
</tr>
 +
<tr valign="top">
 +
  <td>
 +
Are there any problems with large sets of add-on state being updated at once? Say the user has not used a device for a while and they use it again and a whole bunch of add-ons need to be updated.
 +
  </td>
 +
  <td>
 +
  </td>
 +
</tr>
 +
</table>
 +
|Feature overview=Sync is a service to keep the Firefox experience consistent across multiple devices by ensuring user data is synced across various devices. This feature will enable add-ons to be synced across devices. Add-ons are small pieces of software that add new features or functionality to an installation of Firefox. Add-ons can augment Firefox with new features, foreign language dictionaries, or change its visual appearance. Through add-ons, you can customize Firefox to meet your needs and tastes.
  
The solution to this problem will consist of the following:
+
Sync will ensure that add-ons are installed, uninstalled, disabled,and enabled as they are changed on each client for the same application. This means that desktop to desktop add-ons will sync, and mobile to mobile add-ons will sync.
  
# Optional properties on add-on objects that describe the add-on for purposes of use in Sync
+
For the initial release, only XPI extensions and themes from addons.mozilla.org will be supported. In a future release, we can expand scope to add-ons not from addons.mozilla.org.
# Functions on AddonManager that take above properties and perform actions
+
|Feature users and use cases=; Desktop browser to browser add-on install
 +
* A user has sync set up his work and home desktops
 +
* He goes to AMO and installs an add-on on his work computer
 +
* When he goes home and starts his Firefox browser the new add-on will be usable and shows up in the add-on tab
  
For add-on objects, providers wishing to opt in to Sync will expose the following read-only, optional properties:
+
; Desktop browser to browser add-on uninstall
 +
* A user has sync set up his work and home desktops
 +
* At work, he goes to the add-on tab in the browser and removes the add-on
 +
* When he goes home and starts his Firefox browser this add-on will remove itself and not show up in the add-on tab
  
; syncData : a string that describes data necessary to synchronize the add-on between clients. The format of the string is not defined, and is opaque to Sync code. A JSON representation of an object might be a good choice, to hold the data needed by the add-ons manager to install/uninstall an addon.
+
; Desktop browser to browser add-on disable
 +
* A user has sync set up his work and home desktops
 +
* At work, he goes to the add-on tab in the browser and disables an add-on
 +
* When he goes home and starts his Firefox browser this add-on will disable itself and not show up in the add-on tab
  
; syncGUID : a GUID used to identify this add-on across Sync client instances. The GUID should be generated using Utils.makeGUID() from the Sync code. It is basically a Base64-encoded representation of 9 random bytes.
+
; Desktop browser to browser add-on enable
 +
* A user has sync set up his work and home desktops
 +
* At work, he goes to the add-on tab in the browser and enables a disabled add-on
 +
* When he goes home and starts his Firefox browser this add-on will enable itself and not show up in the add-on tab
 +
|Feature dependencies=; Sync GUID added to XPI Provider : Sync requires non-deterministic IDs to be affiliated with synchronized records. XPI add-ons currently don't have a suitable ID so once will need to be created.
 +
|Feature requirements=*When a user installs an add-on, the add-on will be installed on all the user's devices connected with Sync.
 +
*When a user uninstalls an add-on, the add-on will be uninstalled on all the user's devices connected with Sync
 +
*When a user disables an add-on, the add-on will be disabled on all the user's devices connected with Sync
 +
*When a user enables an add-on, the add-on will be enabled on all the user's devices connected with Sync
 +
*Not sure about the update version requirement.  
  
(These properties will need to be documented at https://developer.mozilla.org/en/Addons/Add-on_Manager/Addon)
 
  
The AddonManager will support the following APIs:
+
; Non-impact on add-on manager metrics : The presence of Sync should not skew the metrics in the add-on manager and addons.mozilla.org. Currently, some APIs on the AddonManager upload metrics.
 +
|Feature non-goals=;Syncing add-on information across different Application IDs
  
; getAddonBySyncGUID(syncGUID, callback) : Obtain an add-on from its Sync GUID. Calls the supplied function when that add-on is retrieved. The callback receives null on unknown add-on or the add-on object (generated from the underlying provider) on success.
+
;Sync will not synchronize non-XPI add-ons such as plugins, lightweight themes, and search engines. Sync will also not synchronize add-ons installed outside of the currently running profile.
 +
|Feature functional spec=A syncGUID field has been added to the extensions SQLite database ({{bug|682027}}). All extensions now have a randomly-generated ID suitable for syncing.
  
; installOrUpdateAddonFromSyncData(syncData, syncGUID, callbackObj) : Installs an add-on from sync data or updates the add-on so it has the information specified. Receives the data from the original add-on, the GUID it should be installed with, and an object describing callbacks to be invoked when specific events occurs. The manager will try to obtain an install record and then execute the install. The callbackObj contains the optional keys *onFailure*, *onInstall*, and *onNewSyncGUID* which can be functions that are called when those events occur. Each function receives *syncData* and *syncGUID* as their first arguments. *onInstall* will additionally receive the newly-created (or existing) add-on record and a boolean indicating whether a restart is required. *onNewSyncGUID* will receive as a 3rd parameter the new syncGUID for the already-installed add-on. As inferred from the callback definition, the function must be able to detect existing add-ons from the *syncData* and update the *syncGUID* of that add-on to the value specified.  
+
To track changes, Sync has written a component outside of the add-ons engine called the "Add-ons Reconciler." This provides what the Add-on Manager does not: a persisted state of add-on changes. It installs itself as a listener for Add-on Manager events. When things changed, it records that change and updates its own minimal copy of the global state. These changes are persisted to disk in a JSON file in the profile directory, alongside other persistent Sync metadata. Periodically (at the top of a sync) the reconciler examines the state of the world and ensures that it agrees with the Add-on Manager.
  
; uninstallAddonBySyncGUID(syncGUID, callbackObj) : Uninstalls an add-on specified by its syncGUID. The callbackObj has the optional keys *onSuccess* and *onFailure*. Each receives as an argument the passed *syncGUID*.
+
The add-ons engine subscribes to changes in the Add-on Reconciler to trigger instant sync.
  
Both of these APIs will require the AddonManager to have an additional relationship with the add-on providers (via APIs). The providers will need to provide a routine to install add-ons from *syncData* instances. And, the AddonManager will need to know how to call into these.
+
At the end of every sync, the sync engine requests the reconciler to delete data older than 7 days. This is for privacy reasons as well as to ensure the change log doesn't grow without bound. Even if the change log would grow unbounded, it is doubtful it would ever get so large to become unwieldy because the number of add-on change events (install, uninstall, enable, disable) isn't very high (maybe a few a week).
 +
|Feature ux design=UX has stated that there will be no new UX for this feature. Individual add-ons may trigger UX when they are modified, but there is nothing we can do about that.
 +
|Feature security review=The feature follows the same security model as other sync engines: add-on records are encrypted using Sync's bulk keys (themselves encrypted with the user's Sync Key), and the IDs for each add-on are randomly generated.
  
The add-ons Sync engine will discover the set of add-ons that can be synced via the following procedure:
+
The entire feature is implemented in JavaScript and runs in the chrome process - the same process as Sync.
  
# Query AddonManager.getAllAddons()
+
For the initial feature drop, synchronized add-ons will be limited to:
# Filter the returned list by items that have the *syncData* and *syncGUID* properties and are installed in the profile add-on scope (addon.scope == AddonManager.SCOPE_PROFILE)
+
  
The engine will process incoming records via the following procedure:
+
* XPI extensions or themes
 +
* from the same application ID as other Sync profiles
 +
* installed in the profile directory
 +
* installed explicitly by the user (those put in the profile directory by nefarious applications will be ignored - !addon.foreignInstall)
 +
* installed from addons.mozilla.org
 +
** In the implementation, the hostname is defined by a preference. the default value is *addons.mozilla.org*
  
# Obtain the set of locally-installed add-ons (using above)
+
Eventually, we'll want to expand to all XPI extensions and will want to handle add-ons from non-AMO URIs. But, these will be covered by separate feature(s) and security review(s).
# For each incoming record: TODO
+
  
The Sync add-on tracker will install add-on listeners in the AddonManager and will listen for the following events:
+
UX has deemed it best for the feature to have no explicit UX in the browser, as Sync should be transparent. However, modification of add-ons could result in changes in browser behavior. Toolbars and buttons could appear/disappear "randomly" (corresponding with when Sync runs - which is transparent to the user). Tabs could be opened for add-ons which open tabs on install events. While these aren't security vulnerabilities, they could be perceived as such. "Why is my browser changing - was it hacked?" UX rationalizes it by saying that any add-on behavior must have been triggered by user behavior somewhere. This is true. However, a user might be surprised to see add-ons magically being changed upon (transparent) upgrade to Firefox X. Upon add-on modification, about:addons should reflect the change immediately.
  
* onEnabled
+
If a user's Sync server credentials (but not the Sync Key) are compromised, the server records would reveal the last modified time of individual add-on records. Without access to a Firefox profile, it would be unknown which add-on each record corresponded to. This data leakage is minor and is on par with other leakages currently in the Sync service.
* onDisabled
+
* onInstalled
+
* onUninstalled
+
  
When these are observed, the tracker will:
+
Sync transmits each add-ons ID between devices. The add-on ID is looked up on addons.mozilla.org. Assuming it is found, Firefox will download the extensions or theme from addons.mozilla.org and install it. The installation process uses existing AddonManager APIs. This will result in more requests to addons.mozilla.org. However, such requests shouldn't be traceable back to Sync. We (theoretically) already trust the privacy model of addons.mozilla.org, so even if data is leaked, it should be no big deal.
  
# Verify the changed add-on is in the set of Sync-able add-ons (using same heuristics as add-on discovery documented above)
+
This is the first component of Sync which will indirectly communicate with a non-Sync server (addons.mozilla.org). Sync will be talking with it via the AddonRepository JS APIs. Sync assumes those APIs are doing the proper things to secure against MITM attacks, etc.
# Mark the GUID as changed
+
|Feature operations review=This feature will utilize a new server-side collection, *addons*. The server people might want to add it to the known/common collections set.
# This will result in a new record for that GUID being created automagically. The createRecord() procedure will create the necessary record which will be queued for upload to the Sync server.
+
  
On start-up, the add-on engine will query AddonManager.getStartupChanges() for changes applied on application start-up. These are not observed by Sync because they occur before Sync is registered and running. Even if Sync does catch them in its tracker, it should be safe to mark records as changed. The only side-effect will be a slightly different modified time.
+
When add-ons are synced across devices, the receiving device installs the add-on from addons.mozilla.org, not from Sync. For every add-on to be installed on receiving devices, AMO will see traffic. It will first see a search for this add-on by its ID. If that returns something, the XPI will be downloaded as part of the install process.
  
AddonManager.getStartupChanges() will be queried for the following change types:
+
When this feature launches and add-ons are synchronized across devices, AMO could see a small amount of increased activity, proportional to the number of multi-device Sync users with the feature enabled and the frequency of add-on changes on those devices. We should keep an eye on this for launch day.
 
+
* STARTUP_CHANGE_INSTALLED
+
* STARTUP_CHANGE_CHANGED
+
* STARTUP_CHANGE_UNINSTALLED
+
* STARTUP_CHANGE_DISABLED
+
* STARTUP_CHANGE_ENABLED
+
 
+
TODO: Sync should catch all startup change types (the constants above) and react to them. We may need an API or some kind of verification/test to ensure newly-introduced startup changes/constants aren't missed by Sync. (This is all because getStartupChanges() takes a type as a parameter.)
+
 
+
Open Issues:
+
 
+
* What's the best way to reconcile installed add-ons with different Sync GUIDs? This will happen when two clients have installed the same add-on on different clients and then sets up Sync. The first Sync client will upload the records. Then, the 2nd will download that set and apply them. Should the Sync engine query AddonManager to see which add-ons (from the opaque *syncData* field) are not present or just call out into AddonManager and have it automagically recognize the dupe and update the Sync GUID? Either way, the Sync engine will need to know which Sync GUID disappeared so it can create a record saying the add-on was deleted/updated.
+
 
}}
 
}}
 
{{FeatureInfo
 
{{FeatureInfo
 
|Feature priority=P2
 
|Feature priority=P2
 +
|Feature theme=Experience
 
|Feature roadmap=Sync
 
|Feature roadmap=Sync
|Feature theme=Experience
 
 
|Feature list=Services
 
|Feature list=Services
 
|Feature engineering team=Sync
 
|Feature engineering team=Sync
 
}}
 
}}
{{FeatureTeamStatus}}
+
{{FeatureTeamStatus
Discussion notes from 2011-08-16:
+
|Feature products notes=; Update syncing cut : Syncing on add-on update is cut because an updating mechanism is already part of Firefox. I will follow up with FF folks to see if Sync does bring value. We can address it later.
 
+
; Only sync between the same application : Add-ons will initially only sync between applications of the same application ID. This is because most add-ons aren't compatible across different applications.
* add 'guid' column to 'addon' table in extensions.sqlite
+
|Feature security status=sec-review-complete
* add GUID support to AddonsManager (have it automatically generated, 12 chars base64url)
+
|Feature security health=OK
* findings addons shouldn't count as daily update pings, or if they do, is it a problem?
+
|Feature security notes=[[Security/Reviews/Firefox/AddOnSync|Notes]]
* generate one record per app per addon, silently drop records from other apps and unknown addons (unknown to AMO)
+
}}
* add option to locally disable enabled state sync (the "web developer case") in about:config
+

Latest revision as of 12:32, 22 December 2011

Please use "Edit with form" above to edit this page.

Status

Addon Sync
Stage Landed
Status Complete
Release target Firefox 11
Health OK
Status note Feature landed in Firefox 11.

Team

Product manager Jennifer Arguello
Directly Responsible Individual Jennifer Arguello
Lead engineer Gregory Szorc
Security lead Yvan Boily
Privacy lead `
Localization lead `
Accessibility lead `
QA lead Tracy Walker
UX lead `
Product marketing lead Jaclyn Fu
Operations lead `
Additional members Ibai Garcia (SUMO)

Open issues/risks

Issue/Risk Status

Do we need some prompts or feedback when add-ons are synced, at all?

Probably. Many add-ons still aren't restartless, so installing, uninstalling, enabling, or disabling will require restart. When Sync is driving the add-on install, the Add-on Manager won't display any visual prompts. So, it will be Sync's responsibility to trigger a UI element to prompt restart, if desired. Sync has full control over that element. We could display the one used by the Add-on Manager or make our own.
Answer from Faaborg: Is we do not need any extra UI. If the user happens to go to the Add-ons tab, the updated add-ons should show a restart is necessary.

Are there any problems with large sets of add-on state being updated at once? Say the user has not used a device for a while and they use it again and a whole bunch of add-ons need to be updated.

Stage 1: Definition

1. Feature overview

Sync is a service to keep the Firefox experience consistent across multiple devices by ensuring user data is synced across various devices. This feature will enable add-ons to be synced across devices. Add-ons are small pieces of software that add new features or functionality to an installation of Firefox. Add-ons can augment Firefox with new features, foreign language dictionaries, or change its visual appearance. Through add-ons, you can customize Firefox to meet your needs and tastes.

Sync will ensure that add-ons are installed, uninstalled, disabled,and enabled as they are changed on each client for the same application. This means that desktop to desktop add-ons will sync, and mobile to mobile add-ons will sync.

For the initial release, only XPI extensions and themes from addons.mozilla.org will be supported. In a future release, we can expand scope to add-ons not from addons.mozilla.org.

2. Users & use cases

Desktop browser to browser add-on install
  • A user has sync set up his work and home desktops
  • He goes to AMO and installs an add-on on his work computer
  • When he goes home and starts his Firefox browser the new add-on will be usable and shows up in the add-on tab
Desktop browser to browser add-on uninstall
  • A user has sync set up his work and home desktops
  • At work, he goes to the add-on tab in the browser and removes the add-on
  • When he goes home and starts his Firefox browser this add-on will remove itself and not show up in the add-on tab
Desktop browser to browser add-on disable
  • A user has sync set up his work and home desktops
  • At work, he goes to the add-on tab in the browser and disables an add-on
  • When he goes home and starts his Firefox browser this add-on will disable itself and not show up in the add-on tab
Desktop browser to browser add-on enable
  • A user has sync set up his work and home desktops
  • At work, he goes to the add-on tab in the browser and enables a disabled add-on
  • When he goes home and starts his Firefox browser this add-on will enable itself and not show up in the add-on tab

3. Dependencies

Sync GUID added to XPI Provider 
Sync requires non-deterministic IDs to be affiliated with synchronized records. XPI add-ons currently don't have a suitable ID so once will need to be created.

4. Requirements

  • When a user installs an add-on, the add-on will be installed on all the user's devices connected with Sync.
  • When a user uninstalls an add-on, the add-on will be uninstalled on all the user's devices connected with Sync
  • When a user disables an add-on, the add-on will be disabled on all the user's devices connected with Sync
  • When a user enables an add-on, the add-on will be enabled on all the user's devices connected with Sync
  • Not sure about the update version requirement.


Non-impact on add-on manager metrics 
The presence of Sync should not skew the metrics in the add-on manager and addons.mozilla.org. Currently, some APIs on the AddonManager upload metrics.

Non-goals

Syncing add-on information across different Application IDs
Sync will not synchronize non-XPI add-ons such as plugins, lightweight themes, and search engines. Sync will also not synchronize add-ons installed outside of the currently running profile.

Stage 2: Design

5. Functional specification

A syncGUID field has been added to the extensions SQLite database (bug 682027). All extensions now have a randomly-generated ID suitable for syncing.

To track changes, Sync has written a component outside of the add-ons engine called the "Add-ons Reconciler." This provides what the Add-on Manager does not: a persisted state of add-on changes. It installs itself as a listener for Add-on Manager events. When things changed, it records that change and updates its own minimal copy of the global state. These changes are persisted to disk in a JSON file in the profile directory, alongside other persistent Sync metadata. Periodically (at the top of a sync) the reconciler examines the state of the world and ensures that it agrees with the Add-on Manager.

The add-ons engine subscribes to changes in the Add-on Reconciler to trigger instant sync.

At the end of every sync, the sync engine requests the reconciler to delete data older than 7 days. This is for privacy reasons as well as to ensure the change log doesn't grow without bound. Even if the change log would grow unbounded, it is doubtful it would ever get so large to become unwieldy because the number of add-on change events (install, uninstall, enable, disable) isn't very high (maybe a few a week).

6. User experience design

UX has stated that there will be no new UX for this feature. Individual add-ons may trigger UX when they are modified, but there is nothing we can do about that.

Stage 3: Planning

7. Implementation plan

`

8. Reviews

Security review

The feature follows the same security model as other sync engines: add-on records are encrypted using Sync's bulk keys (themselves encrypted with the user's Sync Key), and the IDs for each add-on are randomly generated.

The entire feature is implemented in JavaScript and runs in the chrome process - the same process as Sync.

For the initial feature drop, synchronized add-ons will be limited to:

  • XPI extensions or themes
  • from the same application ID as other Sync profiles
  • installed in the profile directory
  • installed explicitly by the user (those put in the profile directory by nefarious applications will be ignored - !addon.foreignInstall)
  • installed from addons.mozilla.org
    • In the implementation, the hostname is defined by a preference. the default value is *addons.mozilla.org*

Eventually, we'll want to expand to all XPI extensions and will want to handle add-ons from non-AMO URIs. But, these will be covered by separate feature(s) and security review(s).

UX has deemed it best for the feature to have no explicit UX in the browser, as Sync should be transparent. However, modification of add-ons could result in changes in browser behavior. Toolbars and buttons could appear/disappear "randomly" (corresponding with when Sync runs - which is transparent to the user). Tabs could be opened for add-ons which open tabs on install events. While these aren't security vulnerabilities, they could be perceived as such. "Why is my browser changing - was it hacked?" UX rationalizes it by saying that any add-on behavior must have been triggered by user behavior somewhere. This is true. However, a user might be surprised to see add-ons magically being changed upon (transparent) upgrade to Firefox X. Upon add-on modification, about:addons should reflect the change immediately.

If a user's Sync server credentials (but not the Sync Key) are compromised, the server records would reveal the last modified time of individual add-on records. Without access to a Firefox profile, it would be unknown which add-on each record corresponded to. This data leakage is minor and is on par with other leakages currently in the Sync service.

Sync transmits each add-ons ID between devices. The add-on ID is looked up on addons.mozilla.org. Assuming it is found, Firefox will download the extensions or theme from addons.mozilla.org and install it. The installation process uses existing AddonManager APIs. This will result in more requests to addons.mozilla.org. However, such requests shouldn't be traceable back to Sync. We (theoretically) already trust the privacy model of addons.mozilla.org, so even if data is leaked, it should be no big deal.

This is the first component of Sync which will indirectly communicate with a non-Sync server (addons.mozilla.org). Sync will be talking with it via the AddonRepository JS APIs. Sync assumes those APIs are doing the proper things to secure against MITM attacks, etc.

Privacy review

`

Localization review

`

Accessibility

`

Quality Assurance review

`

Operations review

This feature will utilize a new server-side collection, *addons*. The server people might want to add it to the known/common collections set.

When add-ons are synced across devices, the receiving device installs the add-on from addons.mozilla.org, not from Sync. For every add-on to be installed on receiving devices, AMO will see traffic. It will first see a search for this add-on by its ID. If that returns something, the XPI will be downloaded as part of the install process.

When this feature launches and add-ons are synchronized across devices, AMO could see a small amount of increased activity, proportional to the number of multi-device Sync users with the feature enabled and the frequency of add-on changes on those devices. We should keep an eye on this for launch day.

Stage 4: Development

9. Implementation

`

Stage 5: Release

10. Landing criteria

`


Feature details

Priority P2
Rank 999
Theme / Goal Experience
Roadmap Sync
Secondary roadmap `
Feature list Services
Project `
Engineering team Sync

Team status notes

  status notes
Products ` ; Update syncing cut : Syncing on add-on update is cut because an updating mechanism is already part of Firefox. I will follow up with FF folks to see if Sync does bring value. We can address it later.
Only sync between the same application 
Add-ons will initially only sync between applications of the same application ID. This is because most add-ons aren't compatible across different applications.
Engineering ` `
Security sec-review-complete Notes
Privacy ` `
Localization ` `
Accessibility ` `
Quality assurance ` `
User experience ` `
Product marketing ` `
Operations ` `