Submission and review
BRT releases are immutable, signed snapshots. A site never runs mutable JavaScript from a publisher's server.
Generate a publisher key once
node tools/web-extensions/brt-extension.mjs keygen \
--private-key ~/.config/brt/extensions/publisher-private.pem \
--public-key ./publisher-public-key.txt
The command creates an Ed25519 key pair. The private key file is written with owner-only permissions when the operating system supports them.
- Keep at least one protected active key per publisher identity.
- Store it in a secret manager or protected developer configuration directory.
- Back it up through an approved secure process.
- Never put it in the extension project, ZIP, submission directory, chat, ticket, or source control.
- Send BRT only the public-key file and its displayed SHA-256 fingerprint.
If a private key is lost or exposed, add a replacement public key in the developer console, move protected signing to the replacement, then revoke the old key. You cannot revoke the last active key. A revoked publisher cannot be restored.
Package a release
Update manifest.json version, then run:
node tools/web-extensions/brt-extension.mjs package ./my-extension \
--out ./dist/my-extension-1.0.0 \
--private-key ~/.config/brt/extensions/publisher-private.pem
The command performs a clean validation, builds a deterministic ZIP, computes exact SHA-256 hashes, signs the BRT release envelope, and writes five review files.
Running the command twice against unchanged source and the same key produces the same manifest hash, artifact hash, and signature. This makes review and CI results reproducible.
Do not edit any output file. Repackage after every source or manifest change.
Verify before sending
node tools/web-extensions/brt-extension.mjs verify ./dist/my-extension-1.0.0
The verification command reopens the ZIP, validates its contents, recomputes all hashes, checks the public-key fingerprint, and verifies the signature.
Submit in the developer console
Create the publisher and package in the developer console, then upload the five generated files together:
bundle.zip Signed runtime files
manifest.json Exact signed manifest bytes
publisher-public-key.txt Base64 Ed25519 public key
signature.txt Base64 release signature
submission.json Names, version, canonical path, hashes, and key fingerprint
The private key is never part of a submission.
The console runs the production validator immediately. A passing report joins the BRT review queue. A failing report stays with the submission and shows what to correct. You may correct, sign, and resubmit the same semantic version until BRT approves it. Once approved, that release version is immutable and can never be reused.
BRT keeps the submission record, hashes, validation report, and decision trail. Uploaded working files remain private while a passing submission awaits review. BRT deletes those working files after approval, withdrawal, rejection, a changes-requested decision, or automated validation failure. The approved bundle is copied to immutable release storage before the working files are deleted.
What BRT reviews
BRT runs the production validators without publishing or installing the extension:
php artisan siteadmin:review-extension ./dist/my-extension-1.0.0
php artisan siteadmin:review-extension ./dist/my-extension-1.0.0 --json
This verifies the exact manifest, ZIP contract, hashes, Ed25519 signature, public-key fingerprint, requested capabilities, and visual property definitions. The command makes no database or storage changes.
Passing validation is necessary, not sufficient. BRT also reviews:
- Publisher identity and key custody.
- Whether each capability is necessary for the visible feature.
- Safe rendering of BRT-returned and visitor-entered values.
- Accessibility, responsive behavior, empty states, and error states.
- Claims, labels, and navigation behavior.
- Dependency provenance and license obligations.
- Upgrade compatibility and property migration impact.
Trusting a publisher, approving a release, and publishing a marketplace listing are separate BRT operator decisions. An extension cannot publish itself. A BRT operator cannot approve a release they submitted. A verified release grants no site capability until a store user reviews and approves it during installation.
Public, private, and paid distribution
- A public free extension can be installed from the marketplace after the store user reviews its requested capabilities.
- A private or unlisted extension is available only to a store that redeems a publisher-issued installation link.
- Paid and contact-pricing listings are discoverable in the marketplace, but BRT does not collect the publisher's extension fee. The publisher completes its own agreement and sends the store a private installation link for the approved release.
- A private link can be locked to one store ID, limited by use count, and given an expiration in UTC. BRT stores only a hash of the link token.
- Opening a private link is a read-only preview. The signed-in store must select Accept private extension to grant access. Reopening an already accepted link for the same store does not consume another use.
- Revoking a link stops future redemption. Revoking a release or publisher stops the code from launching.
Publisher team invitations
Publisher owners add owners, administrators, and developers with a private, seven-day invitation link. Creating an invitation does not add the recipient to the team and does not reveal whether that email already has a BRT account. The signed-in recipient must use the matching email address and explicitly accept the invitation. Invite a second owner before removing an owner or deleting an owner’s BRT user account. BRT operators can assign the first owner to a trusted legacy publisher that predates the developer console, but they cannot replace an existing owner.
Release updates
- Increase the semantic version for every release whose behavior or source has changed after an earlier version was approved.
- Keep the namespace unchanged.
- You may reuse a version only while correcting an unapproved, rejected, or withdrawn submission. Never reuse an approved version.
- Preserve property names and types when possible.
- Treat a newly requested capability as a product change that needs a clear explanation.
- Test the previous configuration against the new version.
BRT keeps the prior verified release for one-step rollback. Do not rely on rollback as a substitute for upgrade testing.