> ## Documentation Index
> Fetch the complete documentation index at: https://extension.js.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Get your Firefox Add-ons credentials

> Create an AMO developer account, accept the distribution agreement, and generate the JWT issuer and secret that automated Firefox Add-ons submissions need.

Automated Firefox Add-ons (AMO) submissions need one credential pair and, in
most cases, one identifier:

| Value | What it looks like | Where it comes from |
| - | - | - |
| JWT issuer (API key) | `user:12345678:987` | The AMO API key page |
| JWT secret (API secret) | 64 hexadecimal characters, shown once | Generated with the issuer |
| Add-on GUID | `{c1b2a3d4-0000-4000-8000-a1b2c3d4e5f6}` or an email-style ID like `my-addon@example.com` | Your add-on's Developer Hub page |

## Prerequisites

1. Create a [Firefox account](https://accounts.firefox.com) and sign in at
   [addons.mozilla.org](https://addons.mozilla.org).
2. Accept the Firefox Add-on Distribution Agreement. The API key page stays
   locked behind this acceptance, even for accounts that have published
   add-ons through the web UI for years.

## Generate the API credentials

1. Open the
   [AMO API key page](https://addons.mozilla.org/developers/addon/api/key/).
2. Generate new credentials.
3. Copy the **JWT issuer**. Its shape is `user:12345678:987`. This is the
   value most tools call the API key.
4. Copy the **JWT secret** immediately.

<Warning>
  The JWT secret is shown only once. If you lose it, generate new credentials,
  which revokes the old pair everywhere it is in use.
</Warning>

## The add-on ID and the first submission

The add-on ID, which AMO calls the GUID, identifies your add-on across every
submission. It is also the value that goes in
`browser_specific_settings.gecko.id`. Extension.js reads that key when it is
present, and never writes one for you.

The rules depend on the release channel:

* **Listed** (public listing on AMO): an existing GUID is required. Do the
  first submission by hand in the
  [Developer Hub](https://addons.mozilla.org/developers/), then automate
  updates.
* **Unlisted** (signed for self-distribution): leave the GUID empty on the
  first submission and AMO creates a new add-on, assigning a GUID.

<Warning>
  The empty-GUID convenience is a one-time event, and nothing writes the
  assigned GUID back for you. After the first unlisted submission, open the
  add-on's page in the Developer Hub, copy the assigned GUID, and save it in
  your store settings. Every later submission with an empty GUID creates another
  brand-new add-on instead of updating the first one.
</Warning>

Set the release channel explicitly. An unset channel falls back to `listed`
at submission time, which either fails (no GUID) or publishes a public
listing you may not have intended (GUID set).

## Manifest requirement for new add-ons

New add-ons must declare data collection permissions in the manifest, or AMO
rejects the submission:

```json theme={null}
{
  "browser_specific_settings": {
    "gecko": {
      "data_collection_permissions": { "required": ["none"] }
    }
  }
}
```

AMO has required the key for every new submission since 2025-11-03. You do
not have to discover the rejection at upload time. A production build for a
Firefox target warns when the resolved Gecko manifest lacks
`browser_specific_settings.gecko.data_collection_permissions`.

Use `["none"]` only when the extension transmits nothing. The declaration,
the privacy section of [STORE.md](/docs/workflows/store-metadata), and the
code must agree. See
[Firefox store readiness](/docs/features/multi-platform-builds#firefox-store-readiness-data-collection-permissions)
for the full rules.

## Source zip for bundled builds

AMO requires a source zip when the upload is minified or bundled, which an
Extension.js production build is. Build it with:

```bash theme={null}
npx extension build --browser firefox --zip --zip-source
```

Explain how to build from source in the reviewer notes section of `STORE.md`.

## Blast radius and rotation

<Warning>
  AMO API credentials are account-wide. The issuer and secret can upload to
  every add-on your account controls. If you manage add-ons for several clients,
  keep each client's add-ons under that client's own AMO account.
</Warning>

AMO credentials have no scheduled expiry. Rotate by generating a new pair on
the API key page, which revokes the old one, then re-enter the new values
wherever they are stored.

## Name map

The environment variable each value answers to:

| Value | Env var |
| - | - |
| JWT issuer | `FIREFOX_JWT_ISSUER` |
| JWT secret | `FIREFOX_JWT_SECRET` |
| Add-on GUID | `FIREFOX_EXTENSION_ID` |
| Release channel | `FIREFOX_CHANNEL` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.