Compare commits
No commits in common. "main" and "trustlab-v0.1.0" have entirely different histories.
main
...
trustlab-v
@ -108,50 +108,11 @@ privileged-extension integration spike. Expected additions are:
|
|||||||
access.
|
access.
|
||||||
10. Isolate Browsec branding, profiles, updates, signing keys, and audit data.
|
10. Isolate Browsec branding, profiles, updates, signing keys, and audit data.
|
||||||
|
|
||||||
## ADR-006: Security extensions have private evidence storage
|
|
||||||
|
|
||||||
Privileged security extensions need durable, general-purpose private storage,
|
|
||||||
not merely access to the formal trust-policy overlay. An extension may retain
|
|
||||||
observations, indexes, historical certificates, intermediate analysis, remote
|
|
||||||
responses, user annotations, model state, or other information required by its
|
|
||||||
declared security function.
|
|
||||||
|
|
||||||
The browser brokers storage rather than exposing arbitrary Firefox databases or
|
|
||||||
the storage of another extension. Each extension receives an isolated namespace
|
|
||||||
with explicit capability grants, quotas, schema/version ownership, migration,
|
|
||||||
backup, inspection, export, and deletion controls. Stored information does not
|
|
||||||
become trusted evidence merely because a privileged extension wrote it; all
|
|
||||||
later journal contributions still identify their source and provenance.
|
|
||||||
|
|
||||||
The built-in Velvet Hammer extension separately owns durable policy and
|
|
||||||
investigation storage. Trust decisions remain structured and auditable even
|
|
||||||
when their supporting evidence comes from an extension's general store.
|
|
||||||
|
|
||||||
## ADR-007: Users can initiate evidence capture
|
|
||||||
|
|
||||||
Browsec must provide an unforgeable browser-chrome action available on both
|
|
||||||
successful and failed TLS connections. Its working label is **Record security
|
|
||||||
concern**; final wording requires user research. It must not prematurely assert
|
|
||||||
that the site is insecure.
|
|
||||||
|
|
||||||
Activation freezes a browser-produced observation of the current security
|
|
||||||
context and opens the protected investigation surface. The record may include
|
|
||||||
TLS facts, presented and constructed certificates, path analysis, applicable
|
|
||||||
policy, timestamps, and user-supplied notes. It excludes page contents,
|
|
||||||
credentials, cookies, authorization headers, private keys, and TLS session
|
|
||||||
secrets unless a future, separately consented forensic capability explicitly
|
|
||||||
defines otherwise.
|
|
||||||
|
|
||||||
Authorized security extensions may receive the immutable capture event and add
|
|
||||||
attributed evidence or store extension-private analysis. They cannot rewrite
|
|
||||||
the browser observation or silently transmit it without a separately granted
|
|
||||||
network capability and applicable user consent.
|
|
||||||
|
|
||||||
## Deferred decisions
|
## Deferred decisions
|
||||||
|
|
||||||
- Firefox source revision and ESR release;
|
- Firefox source revision and ESR release;
|
||||||
- plugin package format and signing envelope;
|
- plugin package format and signing envelope;
|
||||||
- persistent policy and extension-private storage technology;
|
- persistent policy database technology;
|
||||||
- P2P transport and community governance;
|
- P2P transport and community governance;
|
||||||
- release governance and threshold signing;
|
- release governance and threshold signing;
|
||||||
- precise UI design and accessibility treatment.
|
- precise UI design and accessibility treatment.
|
||||||
|
|||||||
14
CONCEPT.md
14
CONCEPT.md
@ -69,20 +69,6 @@ the user's browsing targets to peers merely because a certificate validated.
|
|||||||
Hostnames, addresses, fingerprints, and timing are separate declared disclosure
|
Hostnames, addresses, fingerprints, and timing are separate declared disclosure
|
||||||
capabilities, and local policy controls which may leave the browser.
|
capabilities, and local policy controls which may leave the browser.
|
||||||
|
|
||||||
Each privileged security extension has an isolated, durable, general-purpose
|
|
||||||
data store. It may retain observations and any extension-specific information
|
|
||||||
needed for future analysis; storage is not limited to formalized trust
|
|
||||||
decisions. The browser controls capability grants, quotas, inspection, export,
|
|
||||||
deletion, and network disclosure. An extension cannot access another
|
|
||||||
extension's store or treat stored material as unattributed browser fact.
|
|
||||||
|
|
||||||
The user can also initiate investigation through an unforgeable browser-chrome
|
|
||||||
control on successful or failed connections. The working action **Record
|
|
||||||
security concern** captures the current immutable security context and opens
|
|
||||||
the protected investigation UI. It records that the user requested evidence,
|
|
||||||
not that the service has already been proven unsafe. Authorized extensions may
|
|
||||||
analyse and retain the capture while preserving provenance and privacy limits.
|
|
||||||
|
|
||||||
Trust plugins control trust only. They do not gain general authority over
|
Trust plugins control trust only. They do not gain general authority over
|
||||||
navigation, page contents, cookies, credentials, downloads, browser settings,
|
navigation, page contents, cookies, credentials, downloads, browser settings,
|
||||||
or arbitrary Firefox internals. Their enforceable output is a scoped **trusted**
|
or arbitrary Firefox internals. Their enforceable output is a scoped **trusted**
|
||||||
|
|||||||
30
DESIGN.md
30
DESIGN.md
@ -38,10 +38,6 @@ trust policy.
|
|||||||
weaken them.
|
weaken them.
|
||||||
7. Keep all decisions inspectable, revocable, exportable, and attributable.
|
7. Keep all decisions inspectable, revocable, exportable, and attributable.
|
||||||
8. Isolate research browsing from the user's everyday browser data.
|
8. Isolate research browsing from the user's everyday browser data.
|
||||||
9. Let the user begin an investigation on any connection, including one that
|
|
||||||
conventional TLS validation accepted.
|
|
||||||
10. Let privileged security extensions retain arbitrary extension-specific
|
|
||||||
evidence and analysis in isolated, user-governed storage.
|
|
||||||
|
|
||||||
## 3. Non-goals
|
## 3. Non-goals
|
||||||
|
|
||||||
@ -139,32 +135,6 @@ Every decision has a visible expiration, can be revoked immediately, and is
|
|||||||
written to a local audit log. The investigation report stores fingerprints and
|
written to a local audit log. The investigation report stores fingerprints and
|
||||||
metadata, never private keys or page contents.
|
metadata, never private keys or page contents.
|
||||||
|
|
||||||
### 6.5 A valid certificate does not end investigation
|
|
||||||
|
|
||||||
The absence of a TLS warning does not prove that a service is benign or that
|
|
||||||
its certificate was expected. Browsec therefore exposes a browser-owned
|
|
||||||
**Record security concern** action on successful and failed connections. The
|
|
||||||
action captures facts rather than asserting a conclusion, then opens the same
|
|
||||||
protected investigation surface used for automatic TLS failures.
|
|
||||||
|
|
||||||
The initial capture includes the requested origin, observation time, TLS
|
|
||||||
parameters, original certificates, validation and path results, applicable
|
|
||||||
local policy, and optional user notes. It excludes browsing content and secrets.
|
|
||||||
Extensions may append attributed findings according to their capabilities.
|
|
||||||
|
|
||||||
### 6.6 Evidence storage is broader than policy storage
|
|
||||||
|
|
||||||
The formal trust-policy database stores narrow enforceable decisions. It is not
|
|
||||||
a sufficient data model for security extensions. Each privileged security
|
|
||||||
extension also receives isolated general-purpose storage for information it
|
|
||||||
chooses to collect for later security analysis.
|
|
||||||
|
|
||||||
The browser must provide quotas, storage-use visibility, export, deletion,
|
|
||||||
migration, and per-extension network controls. One extension cannot read
|
|
||||||
another extension's store. Writing data does not grant it evidentiary authority:
|
|
||||||
when stored information later enters an investigation journal, its extension
|
|
||||||
source and derivation remain visible.
|
|
||||||
|
|
||||||
## 7. Investigation page
|
## 7. Investigation page
|
||||||
|
|
||||||
### 7.1 Page structure
|
### 7.1 Page structure
|
||||||
|
|||||||
@ -1,285 +0,0 @@
|
|||||||
# Firefox integration spike
|
|
||||||
|
|
||||||
Status: active design and source reconnaissance
|
|
||||||
Date: 2026-08-17
|
|
||||||
|
|
||||||
## First running prototype
|
|
||||||
|
|
||||||
The adjacent Firefox checkout now has branch `codex/browsec-spike` with commit
|
|
||||||
`5ec348b0f1` (*Add Velvet Hammer certificate investigation prototype*).
|
|
||||||
|
|
||||||
The prototype adds a visibly distinct, browser-owned Velvet Hammer frame to
|
|
||||||
`about:certerror`. Its investigation action reads Firefox's protected
|
|
||||||
`FailedCertSecurityInfo`, displays the requested host, original NSS error,
|
|
||||||
failure category, conventional override eligibility, HSTS state, and the number
|
|
||||||
of handshake certificates, then computes and displays SHA-256 fingerprints from
|
|
||||||
the original DER certificate strings.
|
|
||||||
|
|
||||||
It deliberately remains read-only and displays `NOT TRUSTED`; no prototype UI
|
|
||||||
action silently changes Firefox trust. The dedicated browser test
|
|
||||||
`browser_aboutCertError_velvetHammer.js` passes all seven assertions, including
|
|
||||||
the complete DER-derived fingerprint and unchanged terminal trust state.
|
|
||||||
|
|
||||||
This first visible surface uses data already exposed to Firefox's trusted
|
|
||||||
certificate-error document. It does not yet provide the richer immutable
|
|
||||||
`TlsFacts`, append-only journal, plugin chain, policy broker, or fresh retry
|
|
||||||
required by the architecture below.
|
|
||||||
|
|
||||||
The following commit `e4623c33b3` (*Connect certificate investigation to parent
|
|
||||||
trust host*) establishes the first real process boundary. A built-in
|
|
||||||
`BrowsecTrustHost.sys.mjs` runs in the Firefox parent process through the
|
|
||||||
`NetErrorParent` actor. It validates bounded DER input, computes fingerprints,
|
|
||||||
normalizes a Trust API 0.1 failure record, attributes evidence to the Firefox
|
|
||||||
TLS adapter, and invokes the irremovable fail-closed final handler. The content
|
|
||||||
page now only requests evaluation and renders the returned facts, journal, and
|
|
||||||
Boolean verdict. Its browser test passes 11/11 assertions.
|
|
||||||
|
|
||||||
This is a host integration slice, not yet the complete TrustLab runner. It has
|
|
||||||
one evidence adapter and the built-in final handler; package discovery,
|
|
||||||
capability grants, ordered third-party plugins, deadlines, and interactive
|
|
||||||
decisions remain to be ported. The input also still travels from trusted
|
|
||||||
`about:certerror` to the parent actor. It becomes authoritative only when the
|
|
||||||
native PSM continuation freezes and registers the observation before any page
|
|
||||||
is created.
|
|
||||||
|
|
||||||
## Pinned reconnaissance baseline
|
|
||||||
|
|
||||||
The first source inspection uses an adjacent, shallow Firefox checkout:
|
|
||||||
|
|
||||||
```text
|
|
||||||
Checkout: /home/sergeych/dev/browsec-firefox
|
|
||||||
Upstream: https://github.com/mozilla-firefox/firefox.git
|
|
||||||
Branch: main
|
|
||||||
Depth: 1
|
|
||||||
Commit: b462c13f11417e13461f1202d71b14e2784f5db0
|
|
||||||
Commit date: 2026-08-17T09:27:35Z
|
|
||||||
Version: 156.0a1
|
|
||||||
```
|
|
||||||
|
|
||||||
This is a reconnaissance baseline, not the release baseline. Browsec will
|
|
||||||
select an ESR only after the integration seam has been proven. The exact
|
|
||||||
commit, rather than the moving branch name, defines all source references in
|
|
||||||
this document.
|
|
||||||
|
|
||||||
The Firefox checkout is deliberately not nested in this repository. Git
|
|
||||||
history can be added only when needed:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
git fetch --deepen=50 origin main
|
|
||||||
# Or, only if full history becomes necessary:
|
|
||||||
git fetch --unshallow origin
|
|
||||||
```
|
|
||||||
|
|
||||||
## Architectural boundary
|
|
||||||
|
|
||||||
An ordinary WebExtension cannot enforce Browsec trust semantics. Firefox core
|
|
||||||
must remain the reference monitor. It alone may:
|
|
||||||
|
|
||||||
- receive authoritative results and certificate bytes from PSM/NSS;
|
|
||||||
- pause or terminate a TLS connection;
|
|
||||||
- validate a plugin verdict against identity, capabilities, scope, lifetime,
|
|
||||||
policy version, connection identity, and overridable error classes;
|
|
||||||
- make a stored policy visible to later certificate verification;
|
|
||||||
- require a genuinely fresh connection after a new decision; and
|
|
||||||
- host browser chrome that content and ordinary extensions cannot imitate.
|
|
||||||
|
|
||||||
Velvet Hammer and other security extensions remain JavaScript/TypeScript. They
|
|
||||||
receive immutable facts, append attributed journal entries, and return the
|
|
||||||
strict API's Boolean verdicts. They never receive an NSS handle, arbitrary
|
|
||||||
XPCOM access, or direct access to another extension's data.
|
|
||||||
|
|
||||||
## Confirmed certificate-verification path
|
|
||||||
|
|
||||||
At the pinned Firefox revision, the ordinary TLS path is:
|
|
||||||
|
|
||||||
1. `AuthCertificateHookInternal` in
|
|
||||||
`security/manager/ssl/SSLServerCertVerification.cpp` captures the peer DER
|
|
||||||
chain and dispatches an `SSLServerCertVerificationJob`.
|
|
||||||
2. `SSLServerCertVerificationJob::Run()` executes on a certificate-verification
|
|
||||||
thread in the parent process.
|
|
||||||
3. `AuthCertificate()` calls `CertVerifier::VerifySSLServerCert()` and obtains
|
|
||||||
the constructed DER chain, validation result, EV state, CT information,
|
|
||||||
issuer-source information, and related facts.
|
|
||||||
4. `AuthCertificateParseResults()` categorizes a failed result and consults
|
|
||||||
Firefox's existing `nsICertOverrideService` for eligible exact-certificate
|
|
||||||
overrides.
|
|
||||||
5. Both successful and failed results are moved through
|
|
||||||
`BaseSSLServerCertVerificationResult::Dispatch()`.
|
|
||||||
6. `SSLServerCertVerificationResult::Run()` executes on the socket transport
|
|
||||||
thread, populates `CommonSocketControl`, and finally calls
|
|
||||||
`SetCertVerificationResult(mFinalError)`.
|
|
||||||
|
|
||||||
The result object already carries both the constructed chain and peer-presented
|
|
||||||
chain as original DER byte arrays. This makes it the narrowest promising seam
|
|
||||||
for producing `TlsFacts` without reparsing lossy display objects.
|
|
||||||
|
|
||||||
HTTP/3 has an additional path in `netwerk/protocol/http/Http3Session.cpp`, which
|
|
||||||
uses `AuthCertificateHookWithInfo()`. It reaches the same verification
|
|
||||||
machinery, but must receive explicit integration tests; shared implementation
|
|
||||||
does not by itself prove equivalent pause, retry, and connection-reuse
|
|
||||||
semantics.
|
|
||||||
|
|
||||||
## Proposed native seam
|
|
||||||
|
|
||||||
Add a browser-internal `BrowsecTrustHost` continuation between receipt of the
|
|
||||||
PSM result and the final call to `SetCertVerificationResult`:
|
|
||||||
|
|
||||||
```text
|
|
||||||
NSS/PSM verification
|
|
||||||
|
|
|
||||||
v
|
|
||||||
SSLServerCertVerificationResult::Run
|
|
||||||
|
|
|
||||||
v
|
|
||||||
freeze Browsec TLS observation
|
|
||||||
|
|
|
||||||
+---- conventional success ---> bounded pre-accept chain
|
|
||||||
|
|
|
||||||
`---- conventional failure ---> normal failure + investigation record
|
|
||||||
|
|
|
||||||
v
|
|
||||||
protected Velvet Hammer UI
|
|
||||||
```
|
|
||||||
|
|
||||||
This should be an asynchronous native state machine, not a thread-blocking call
|
|
||||||
from C++ into JavaScript. On conventional success, the socket remains in its
|
|
||||||
existing certificate-authentication wait state while the request is dispatched
|
|
||||||
to the privileged extension host. Each JavaScript `onBeforeTlsAccept` callback
|
|
||||||
must return synchronously once invoked, but delivery and continuation across
|
|
||||||
Firefox threads are naturally asynchronous. A short browser-enforced deadline
|
|
||||||
fails closed.
|
|
||||||
|
|
||||||
Heavy work, network access, and interactive UI are forbidden in that hook.
|
|
||||||
Extensions perform such work in the background and consult prepared local state
|
|
||||||
when the hook arrives.
|
|
||||||
|
|
||||||
On conventional failure, the first slice need not retain the failed socket.
|
|
||||||
Core freezes an investigation record, completes the failure normally, and
|
|
||||||
correlates the resulting navigation with a protected investigation page. If the
|
|
||||||
user creates a valid exception, Browsec stores the policy and starts a fresh
|
|
||||||
navigation on a fresh connection.
|
|
||||||
|
|
||||||
## Why the existing override service is only a bootstrap adapter
|
|
||||||
|
|
||||||
`nsICertOverrideService` already stores host, port, origin attributes, exact
|
|
||||||
certificate, and session-or-persistent lifetime. PSM consults it only for
|
|
||||||
errors Firefox categorizes as overridable and rejects overrides where policy
|
|
||||||
such as HSTS forbids them. This is useful for the first exact-leaf prototype.
|
|
||||||
|
|
||||||
It cannot represent Browsec's complete policy model:
|
|
||||||
|
|
||||||
- exact DER authority trust restricted to a namespace;
|
|
||||||
- explicit distrust of otherwise accepted authorities;
|
|
||||||
- arbitrary timed lifetime;
|
|
||||||
- plugin identity and decision provenance;
|
|
||||||
- journal references and the exact set of errors authorized by a verdict;
|
|
||||||
- independent extension evidence storage; or
|
|
||||||
- user-inspectable policy history.
|
|
||||||
|
|
||||||
Therefore the adapter must be named and documented as provisional. Browsec's
|
|
||||||
durable policy overlay remains the source of truth even while an exact-leaf
|
|
||||||
rule is mirrored into the Firefox service for the first demonstration.
|
|
||||||
|
|
||||||
## Privileged extension host
|
|
||||||
|
|
||||||
The initial host should be a built-in Firefox WebExtension API namespace, not a
|
|
||||||
legacy external Experiment loaded from an arbitrary path. Current Firefox
|
|
||||||
implements parent-process extension APIs under
|
|
||||||
`toolkit/components/extensions/parent/`, with schemas and explicit manifest
|
|
||||||
permissions controlling exposure.
|
|
||||||
|
|
||||||
The Browsec API is available only to packages that pass all of these checks:
|
|
||||||
|
|
||||||
1. Browsec security-extension package type;
|
|
||||||
2. verified package identity;
|
|
||||||
3. requested capability in the package manifest;
|
|
||||||
4. local capability grant;
|
|
||||||
5. permitted execution mode for the current profile/context; and
|
|
||||||
6. API-version compatibility.
|
|
||||||
|
|
||||||
The built-in Velvet Hammer package is compiled into the product, always enabled,
|
|
||||||
and always ordered last. Its irremovability is enforced by the host, not by an
|
|
||||||
ordinary extension preference.
|
|
||||||
|
|
||||||
## First vertical slice
|
|
||||||
|
|
||||||
The spike is complete when an automated browser test demonstrates:
|
|
||||||
|
|
||||||
1. Navigate a clean Browsec profile to a local HTTPS server with an unknown
|
|
||||||
self-signed certificate.
|
|
||||||
2. Capture original DER, host, port, origin attributes, Firefox error, and both
|
|
||||||
available chain representations.
|
|
||||||
3. Display them in a browser-owned Velvet Hammer investigation page.
|
|
||||||
4. Obtain an explicit exact-certificate, exact-host, exact-port, session-scoped
|
|
||||||
user decision.
|
|
||||||
5. Validate and append the verdict to the audit journal.
|
|
||||||
6. Persist the Browsec policy rule and provisionally mirror it through
|
|
||||||
`nsICertOverrideService`.
|
|
||||||
7. Abandon the failed connection and start a fresh navigation.
|
|
||||||
8. Load the site and display a persistent Browsec-controlled indication that
|
|
||||||
conventional validation failed and named local policy permitted it.
|
|
||||||
9. Revoke the rule and prove that another fresh navigation fails again.
|
|
||||||
|
|
||||||
No page content, cookie, credential, authorization header, private key, or TLS
|
|
||||||
session secret is included in the investigation record.
|
|
||||||
|
|
||||||
## Patch sequence
|
|
||||||
|
|
||||||
### Patch 1: built-in UI and exact-leaf prototype
|
|
||||||
|
|
||||||
- add the built-in Velvet Hammer package and protected `about:` surface;
|
|
||||||
- expose immutable failed-connection facts through a minimal internal API;
|
|
||||||
- implement the browser-owned **Record security concern** chrome action;
|
|
||||||
- execute the existing TrustLab failure chain;
|
|
||||||
- use the provisional exact-leaf override adapter; and
|
|
||||||
- add browser and xpcshell tests.
|
|
||||||
|
|
||||||
This patch can begin in artifact-build mode if it changes only packaged
|
|
||||||
JavaScript, HTML, CSS, and existing scriptable interfaces.
|
|
||||||
|
|
||||||
### Patch 2: native pre-accept continuation
|
|
||||||
|
|
||||||
- add the `BrowsecTrustHost` continuation before
|
|
||||||
`SetCertVerificationResult(0)`;
|
|
||||||
- bind every observation and verdict to a unique connection attempt;
|
|
||||||
- enforce deadline, cancellation, and fail-closed behavior;
|
|
||||||
- ensure that plugin failure never becomes implicit trust; and
|
|
||||||
- test ordinary TLS and HTTP/3 paths.
|
|
||||||
|
|
||||||
This requires a full compiled Firefox build.
|
|
||||||
|
|
||||||
### Patch 3: native Browsec policy overlay
|
|
||||||
|
|
||||||
- stop depending on Firefox's override store as the source of truth;
|
|
||||||
- enforce certificate and authority rules with precise error substitution;
|
|
||||||
- implement explicit distrust on conventional-success paths;
|
|
||||||
- add timed and persistent policy lifetimes; and
|
|
||||||
- make policy snapshots auditable and atomically replaceable.
|
|
||||||
|
|
||||||
### Patch 4: network-path audit
|
|
||||||
|
|
||||||
Cover top-level navigation, redirects, subresources, WebSocket, workers,
|
|
||||||
service workers, speculative connections, proxy `CONNECT`, TLS resumption,
|
|
||||||
HTTP/2 and HTTP/3 coalescing, private browsing, containers, and client
|
|
||||||
certificate interactions. A path is not considered covered merely because it
|
|
||||||
eventually calls a shared verifier; its connection reuse and enforcement
|
|
||||||
behavior must be tested.
|
|
||||||
|
|
||||||
## Immediate implementation questions
|
|
||||||
|
|
||||||
The spike should resolve these from code and tests rather than policy intuition:
|
|
||||||
|
|
||||||
- which identifier safely binds the UI investigation to one network attempt;
|
|
||||||
- where a fresh-retry flag can prohibit reuse and coalescing;
|
|
||||||
- how much constructed-chain material remains available for every failure;
|
|
||||||
- which process owns the immutable investigation registry;
|
|
||||||
- whether the first built-in API can remain JS-only or requires new WebIDL;
|
|
||||||
- how the protected page proves to the user that it is browser chrome; and
|
|
||||||
- which Firefox error classes can safely use the provisional override adapter.
|
|
||||||
|
|
||||||
## Maintenance rule
|
|
||||||
|
|
||||||
Every Firefox rebase must rerun the integration tests and re-audit the call path
|
|
||||||
from `VerifySSLServerCert` through `SetCertVerificationResult`, including the
|
|
||||||
HTTP/3 entry point. Silent upstream movement of this boundary is a release
|
|
||||||
blocker, not an implementation detail.
|
|
||||||
@ -48,7 +48,6 @@ And its project motto keeps the same principle courteous:
|
|||||||
|
|
||||||
- [Wake-up point and roadmap](ROADMAP.md)
|
- [Wake-up point and roadmap](ROADMAP.md)
|
||||||
- [First-session continuity notes](SESSION_NOTES.md)
|
- [First-session continuity notes](SESSION_NOTES.md)
|
||||||
- [Public trust user-research questions](USER_RESEARCH.md)
|
|
||||||
- [Coarse-grained concept](CONCEPT.md)
|
- [Coarse-grained concept](CONCEPT.md)
|
||||||
- [Architecture decisions](ARCHITECTURE.md)
|
- [Architecture decisions](ARCHITECTURE.md)
|
||||||
- [Certificate Investigator design](DESIGN.md)
|
- [Certificate Investigator design](DESIGN.md)
|
||||||
|
|||||||
58
ROADMAP.md
58
ROADMAP.md
@ -68,31 +68,30 @@ replacement for the concept, architecture, or detailed design documents.
|
|||||||
- This is still a browser-neutral research tool. It reports what Browsec would
|
- This is still a browser-neutral research tool. It reports what Browsec would
|
||||||
decide but does not yet control a Firefox network connection.
|
decide but does not yet control a Firefox network connection.
|
||||||
|
|
||||||
## Next milestone: Firefox host and privileged security extensions
|
## Next milestone: named trust providers
|
||||||
|
|
||||||
The primary product is a Firefox downstream that hosts full-fledged security
|
Add trust-store comparison without merging stores or erasing provenance. The
|
||||||
extensions. TrustLab and Velvet Hammer are the proven reference implementation,
|
same candidate path should be evaluated independently against providers such as:
|
||||||
not the final delivery environment.
|
|
||||||
|
|
||||||
The first reconnaissance baseline and proposed patch sequence are recorded in
|
- Mozilla's root program snapshot;
|
||||||
[`FIREFOX_INTEGRATION.md`](FIREFOX_INTEGRATION.md). It pins the inspected
|
- the operating-system trust store;
|
||||||
Firefox commit and must be updated whenever that baseline changes.
|
- an explicitly imported PEM/DER anchor collection;
|
||||||
|
- the user's local allow and distrust policy;
|
||||||
|
- configured community trust providers.
|
||||||
|
|
||||||
The next milestone should establish the smallest real Firefox integration:
|
The first implementation should provide:
|
||||||
|
|
||||||
1. Map NSS/PSM validation and certificate data into immutable `TlsFacts`.
|
1. A small trust-provider interface returning exact anchor fingerprints,
|
||||||
2. Define the privileged security-extension package, identity, capability, and
|
provider identity, snapshot identity, observation time, and Boolean
|
||||||
local grant model.
|
recognition or distrust.
|
||||||
3. Invoke the bounded success/failure trust hooks and enforce a fresh scoped
|
2. Safe import of PEM and DER anchor collections with duplicate detection and
|
||||||
retry without granting arbitrary NSS database access.
|
DER-derived metadata.
|
||||||
4. Host the irremovable Velvet Hammer root extension in unforgeable browser UI.
|
3. Independent results per provider. No implicit union of trust stores.
|
||||||
5. Provide isolated general-purpose durable storage to each privileged security
|
4. UI comparison showing why the same path terminates differently under each
|
||||||
extension, including quota, migration, inspection, export, and deletion.
|
provider.
|
||||||
6. Implement durable, auditable Velvet Hammer policy and investigation storage.
|
5. Investigation-bundle preservation of provider and snapshot provenance.
|
||||||
7. Add a browser-chrome **Record security concern** action for user-initiated
|
6. Tests proving that a provider's trust cannot become anonymous global trust
|
||||||
evidence capture on successful as well as failed connections.
|
or escape its configured scope.
|
||||||
8. Prove one end-to-end navigation through a deliberately broken certificate,
|
|
||||||
user decision, stored scoped rule, and fresh connection retry.
|
|
||||||
|
|
||||||
## Later milestones
|
## Later milestones
|
||||||
|
|
||||||
@ -102,15 +101,14 @@ The next milestone should establish the smallest real Firefox integration:
|
|||||||
server-presented, locally stored, and downloaded certificates.
|
server-presented, locally stored, and downloaded certificates.
|
||||||
- Compare investigation bundles across time for key, issuer, SAN, extension,
|
- Compare investigation bundles across time for key, issuer, SAN, extension,
|
||||||
policy, and path changes.
|
policy, and path changes.
|
||||||
- Add named trust providers, trust-store adapters, and historical snapshot
|
- Add several trust-store adapters and historical snapshot comparison.
|
||||||
comparison as optional security extensions.
|
- Design durable, auditable local policy storage.
|
||||||
- Develop distributed/community trust as a later extension family rather than
|
- Map the proven TrustLab contracts onto Firefox NSS/PSM integration points.
|
||||||
a prerequisite for the browser platform.
|
|
||||||
|
|
||||||
## Resume here
|
## Resume here
|
||||||
|
|
||||||
Begin by documenting the Firefox/NSS/PSM integration seam and selecting a
|
Begin by defining the trust-provider TypeScript contract and two browserless
|
||||||
specific Firefox revision for a privileged-extension spike. In parallel, define
|
reference providers: an explicit in-memory anchor set and a local distrust set.
|
||||||
the extension-private storage broker and the browser-produced manual evidence
|
Feed their separately attributed results into the existing path analysis and
|
||||||
capture record. Do not begin distributed-trust implementation before this host
|
display the comparison without changing the current final-decision semantics.
|
||||||
platform works.
|
|
||||||
|
|||||||
162
SESSION_NOTES.md
162
SESSION_NOTES.md
@ -228,30 +228,35 @@ There were **38 passing tests**. Live checks also behaved as intended:
|
|||||||
Use `git status --short` before new work. Existing uncommitted changes, if any,
|
Use `git status --short` before new work. Existing uncommitted changes, if any,
|
||||||
must be treated as belonging to the user.
|
must be treated as belonging to the user.
|
||||||
|
|
||||||
## Corrected next implementation seam
|
## Exact next implementation seam
|
||||||
|
|
||||||
The primary goal is the Browsec Firefox host and its privileged security-
|
Implement named trust providers before adding more global policy behavior.
|
||||||
extension platform. Distributed trust and named trust providers are later
|
|
||||||
extensions that may be implemented by us or the community; they must not delay
|
|
||||||
the browser integration.
|
|
||||||
|
|
||||||
Begin with three connected designs:
|
Start with a strict TypeScript contract that accepts a candidate path and
|
||||||
|
immutable certificate facts, then returns an attributed Boolean recognition or
|
||||||
|
distrust result containing:
|
||||||
|
|
||||||
1. The narrow Firefox NSS/PSM adapter that creates `TlsFacts`, invokes the trust
|
- provider ID and human name;
|
||||||
chain, and performs a fresh scoped retry.
|
- provider kind;
|
||||||
2. The privileged-extension host, package/capability grants, protected UI, and
|
- snapshot ID/version;
|
||||||
isolated general-purpose storage broker. Extensions may retain any
|
- observation or effective time;
|
||||||
information needed for their security function, subject to explicit
|
- exact recognized/distrusted anchor fingerprint;
|
||||||
capabilities, quotas, inspection, export, deletion, and network controls.
|
- supporting reason codes.
|
||||||
3. A browser-owned **Record security concern** action that lets the user capture
|
|
||||||
immutable evidence and open Velvet Hammer even when conventional TLS
|
|
||||||
validation succeeded. User-generated concern is an observation trigger, not
|
|
||||||
a pre-written verdict that the service is unsafe.
|
|
||||||
|
|
||||||
Then connect the already implemented Velvet Hammer reference extension to this
|
Build two browserless reference providers first:
|
||||||
host, add durable policy/investigation storage, and prove an end-to-end failed
|
|
||||||
navigation and retry. Only after the platform works should work resume on named
|
1. An explicit in-memory anchor set.
|
||||||
or distributed trust providers.
|
2. An explicit local distrust set.
|
||||||
|
|
||||||
|
Evaluate them independently against each candidate path. Do not union provider
|
||||||
|
stores, do not collapse conflicting results, and do not change final-decision
|
||||||
|
semantics yet. Show a comparison matrix in TrustLab and preserve provider
|
||||||
|
snapshots in investigation bundles.
|
||||||
|
|
||||||
|
After that, add safe PEM/DER anchor collection import with duplicate detection.
|
||||||
|
Only later add real Mozilla/OS adapters, AIA issuer retrieval, Name Constraints,
|
||||||
|
revocation, Certificate Transparency, historical comparisons, durable policy,
|
||||||
|
and Firefox NSS/PSM integration.
|
||||||
|
|
||||||
## Files to open first next session
|
## Files to open first next session
|
||||||
|
|
||||||
@ -266,120 +271,3 @@ The conceptual documents remain authoritative for broader intent:
|
|||||||
[`CONCEPT.md`](CONCEPT.md), [`ARCHITECTURE.md`](ARCHITECTURE.md), and
|
[`CONCEPT.md`](CONCEPT.md), [`ARCHITECTURE.md`](ARCHITECTURE.md), and
|
||||||
[`DESIGN.md`](DESIGN.md).
|
[`DESIGN.md`](DESIGN.md).
|
||||||
|
|
||||||
## Second-session correction and discussion
|
|
||||||
|
|
||||||
The project reached a clean first milestone tagged `trustlab-v0.1.0`. During the
|
|
||||||
next session we briefly began treating named or distributed trust providers as
|
|
||||||
the immediate milestone. Sergeych correctly stopped this drift and restored the
|
|
||||||
actual product hierarchy:
|
|
||||||
|
|
||||||
1. Browsec is a Firefox-derived host for privileged security extensions.
|
|
||||||
2. Browsec Trust API is the capability-controlled TLS security interface.
|
|
||||||
3. Velvet Hammer is the built-in, irremovable root security extension; its
|
|
||||||
browser-neutral substance already exists in TrustLab.
|
|
||||||
4. Third parties can later build continuity monitors, institutional policies,
|
|
||||||
historical databases, CT/revocation analysers, and community systems.
|
|
||||||
5. Distributed trust is a later extension family, not a prerequisite for the
|
|
||||||
browser platform.
|
|
||||||
|
|
||||||
Two platform requirements were then underlined and added to the authoritative
|
|
||||||
documents:
|
|
||||||
|
|
||||||
- A privileged security extension needs isolated, durable, general-purpose
|
|
||||||
storage for any observations, indexes, historical data, intermediate state,
|
|
||||||
user annotations, or other information required by its security function.
|
|
||||||
This is broader than the structured trust-policy database. Storage remains
|
|
||||||
capability-controlled, quota-visible, inspectable, exportable, deletable,
|
|
||||||
migratable, and isolated from other extensions.
|
|
||||||
- The browser needs an unforgeable user action, provisionally named **Record
|
|
||||||
security concern**, that starts evidence capture and opens Velvet Hammer on a
|
|
||||||
conventionally successful or failed connection. It records concern and facts;
|
|
||||||
it does not prejudge the resource as insecure. Captures exclude page content,
|
|
||||||
credentials, cookies, authorization headers, private keys, and TLS secrets.
|
|
||||||
|
|
||||||
These corrections were committed as `55f614f` (*Restore security extension
|
|
||||||
platform as primary goal*) and pushed to `origin/main`.
|
|
||||||
|
|
||||||
### Distributed-trust exploration, deliberately deferred
|
|
||||||
|
|
||||||
Before the priority correction, we began exploring what users might benefit
|
|
||||||
from in a future distributed-trust extension. A neutral public interview guide
|
|
||||||
was saved as [`USER_RESEARCH.md`](USER_RESEARCH.md). It asks what people want,
|
|
||||||
tolerate, fear, and would immediately reject without assuming that communities
|
|
||||||
are good or conventional authorities are bad.
|
|
||||||
|
|
||||||
Sergeych also described firsthand experience as Cybiko's software director from
|
|
||||||
the beginning through the final production model. Relevant experience—not an
|
|
||||||
architecture to copy—included:
|
|
||||||
|
|
||||||
- one or two RF discovery channels plus a region-dependent data-channel band;
|
|
||||||
- compressed public-profile pings, locally calculated time slots, and a
|
|
||||||
four-dimensional space/time/frequency view of transmission opportunity;
|
|
||||||
- production-assigned unique device IDs and packet origin/serial idempotency;
|
|
||||||
- TTL-limited multi-hop forwarding with battery, foreground activity, traffic
|
|
||||||
density, link quality, ACK/reply overhearing, and neighbor density considered;
|
|
||||||
- direct observations kept distinct from second-hand one-to-two-hop maps;
|
|
||||||
- age-based topology expiry after missed discovery pings;
|
|
||||||
- distance-biased delayed relaying, where farther receivers could forward first
|
|
||||||
and nearer candidates suppress duplicates after overhearing;
|
|
||||||
- an early repeat of an important packet acting as a request that waiting relay
|
|
||||||
candidates transmit sooner;
|
|
||||||
- adaptive frequency choice based on SNR, BER, and delivery history;
|
|
||||||
- Reed–Solomon coding for operation near the permitted noise floor;
|
|
||||||
- optional PC/Internet-connected cells acting as smarter rendezvous and
|
|
||||||
store-and-forward bridges for dial-up/NAT-era networks;
|
|
||||||
- a memorable testing failure: a one-character Atmel-code error broke the exact
|
|
||||||
two-device topology, which was absent from a development site containing
|
|
||||||
dozens of devices.
|
|
||||||
|
|
||||||
The conclusion was not to transplant a 25-year-old mesh design. Its valuable
|
|
||||||
lesson is the experience of deriving a new architecture from goals, physical
|
|
||||||
constraints, failure modes, local observations, ageing, and feedback rather
|
|
||||||
than beginning with an attractive algorithm.
|
|
||||||
|
|
||||||
### Current resume point
|
|
||||||
|
|
||||||
Do not implement distributed trust next. Continue from the Firefox host seam:
|
|
||||||
|
|
||||||
1. Select a Firefox revision for the privileged-extension experiment.
|
|
||||||
2. Map NSS/PSM success and failure into immutable `TlsFacts`.
|
|
||||||
3. Define privileged extension identity, capability grants, protected UI, and
|
|
||||||
isolated evidence storage.
|
|
||||||
4. Define the browser-produced manual security-concern capture record.
|
|
||||||
5. Connect Velvet Hammer and demonstrate failed navigation, informed decision,
|
|
||||||
durable scoped policy, and a fresh enforced retry.
|
|
||||||
|
|
||||||
### Firefox integration reconnaissance (2026-08-17)
|
|
||||||
|
|
||||||
- A depth-1 Firefox checkout now exists beside this repository at
|
|
||||||
`/home/sergeych/dev/browsec-firefox`.
|
|
||||||
- It is pinned for reconnaissance to Firefox `156.0a1`, commit
|
|
||||||
`b462c13f11417e13461f1202d71b14e2784f5db0` from
|
|
||||||
`https://github.com/mozilla-firefox/firefox.git`.
|
|
||||||
- [`FIREFOX_INTEGRATION.md`](FIREFOX_INTEGRATION.md) records the confirmed PSM
|
|
||||||
path, proposed native continuation seam, limitations of
|
|
||||||
`nsICertOverrideService`, patch sequence, and first end-to-end acceptance
|
|
||||||
test.
|
|
||||||
- The promising seam is `SSLServerCertVerificationResult::Run()` immediately
|
|
||||||
before `CommonSocketControl::SetCertVerificationResult()`: both constructed
|
|
||||||
and peer-presented DER chains are still present there.
|
|
||||||
- The JavaScript success hook remains synchronously returning, but its native
|
|
||||||
cross-thread bridge must be continuation-based and bounded rather than
|
|
||||||
blocking a verifier or socket thread while calling JavaScript.
|
|
||||||
- Firefox artifact mode was bootstrapped without system changes and the pinned
|
|
||||||
baseline built successfully. The absent optional `watchman` and repository-
|
|
||||||
wide `cargo-audit` setup do not affect the frontend artifact build.
|
|
||||||
- Branch `codex/browsec-spike`, commit `5ec348b0f1`, contains the first running
|
|
||||||
browser-owned Velvet Hammer certificate investigation surface and its browser
|
|
||||||
test. The test passes 7/7 assertions. The surface exposes protected Firefox
|
|
||||||
failure facts and DER-derived SHA-256 fingerprints but intentionally cannot
|
|
||||||
alter trust yet.
|
|
||||||
- Firefox commit `e4623c33b3` adds the first parent-process Trust API 0.1 host.
|
|
||||||
`about:certerror` sends its provisional observation through an explicitly
|
|
||||||
allowlisted query; the parent validates bounded DER, computes fingerprints,
|
|
||||||
creates normalized facts, appends attributed adapter evidence, and executes
|
|
||||||
the built-in fail-closed final handler. The page renders the returned record
|
|
||||||
and append-only journal. Its expanded browser test passes 11/11 assertions.
|
|
||||||
- This is not yet the complete TrustLab runner or an authoritative native PSM
|
|
||||||
observation. Ordered third-party packages, capabilities, timeouts,
|
|
||||||
interactive decisions, durable policy, and fresh retry remain next.
|
|
||||||
|
|||||||
150
USER_RESEARCH.md
150
USER_RESEARCH.md
@ -1,150 +0,0 @@
|
|||||||
# Public trust user research
|
|
||||||
|
|
||||||
This guide is for conversations with non-specialists before Browsec commits to
|
|
||||||
a distributed-trust architecture. Its purpose is to discover what people would
|
|
||||||
benefit from, tolerate, distrust, and reject—not to persuade them that our
|
|
||||||
current idea is correct.
|
|
||||||
|
|
||||||
Ask one question at a time. Let the participant describe concrete experiences
|
|
||||||
before introducing terminology such as certificate authority, consensus,
|
|
||||||
community trust, reputation, or distributed network.
|
|
||||||
|
|
||||||
## Short conversational interview
|
|
||||||
|
|
||||||
### Existing experience
|
|
||||||
|
|
||||||
1. Have you ever opened a site and received a security or certificate warning?
|
|
||||||
What did you think was happening?
|
|
||||||
2. What did you do next, and why?
|
|
||||||
3. Have you ever wanted to use a site that your browser blocked even though you
|
|
||||||
believed it was legitimate?
|
|
||||||
4. Have you ever trusted a site because the browser showed no warning and later
|
|
||||||
regretted it?
|
|
||||||
|
|
||||||
### What “trustworthy” means
|
|
||||||
|
|
||||||
5. When you call an online service trustworthy, what do you mean?
|
|
||||||
6. Does trustworthiness change with the activity—for example reading news,
|
|
||||||
sending a private message, downloading software, or making a payment?
|
|
||||||
7. What information would help you decide whether to continue to a questionable
|
|
||||||
site?
|
|
||||||
8. Which matters more to you: knowing who operates the service, knowing that
|
|
||||||
other people have used it safely, or knowing that its technical identity has
|
|
||||||
not unexpectedly changed?
|
|
||||||
|
|
||||||
### People and institutions
|
|
||||||
|
|
||||||
9. Whose judgment about an online service would you consider useful?
|
|
||||||
10. Would you treat advice differently if it came from friends, technical
|
|
||||||
specialists, an organization you know, your employer, your government, or
|
|
||||||
strangers with a good history?
|
|
||||||
11. Should several independent sources be able to disagree visibly, or should
|
|
||||||
the browser combine them into one recommendation?
|
|
||||||
12. Would you ever allow a chosen person or group to make a security decision
|
|
||||||
automatically for you? In what situations?
|
|
||||||
13. Whom would you explicitly refuse to give that power?
|
|
||||||
|
|
||||||
### Desired behaviour
|
|
||||||
|
|
||||||
14. If the browser distrusts a service but people you chose consider it
|
|
||||||
legitimate, what should the browser do?
|
|
||||||
15. If the browser accepts a service but a community you trust reports danger,
|
|
||||||
what should happen?
|
|
||||||
16. Should the system merely provide evidence, recommend an action, block the
|
|
||||||
connection, or let you choose among those behaviours?
|
|
||||||
17. How much explanation would you want before continuing: a simple warning, a
|
|
||||||
short reason, or a detailed investigation?
|
|
||||||
18. Should an earlier decision apply once, for the current session, for a fixed
|
|
||||||
time, or until you revoke it?
|
|
||||||
|
|
||||||
### Privacy and social cost
|
|
||||||
|
|
||||||
19. Would you be comfortable if other participants could learn which services
|
|
||||||
your browser checks or visits?
|
|
||||||
20. Would you contribute observations about certificates or service behaviour
|
|
||||||
if the system protected your browsing history? What protection would you
|
|
||||||
expect?
|
|
||||||
21. Would public participation under a stable identity feel safer and more
|
|
||||||
accountable, or more invasive?
|
|
||||||
22. What information about you should never leave your device?
|
|
||||||
23. Would background network activity, battery use, or bandwidth use bother
|
|
||||||
you? How much control would you expect?
|
|
||||||
|
|
||||||
### Abuse and failure
|
|
||||||
|
|
||||||
24. What would make you suspect that a trust community had been manipulated or
|
|
||||||
captured?
|
|
||||||
25. What should happen when trusted participants disagree sharply?
|
|
||||||
26. How should the system respond if a once-reliable participant begins giving
|
|
||||||
harmful advice?
|
|
||||||
27. Should old recommendations expire automatically? How quickly?
|
|
||||||
28. What would be worse: occasionally blocking a legitimate service, or
|
|
||||||
occasionally allowing a harmful one?
|
|
||||||
29. What behaviour by this system would make you disable or uninstall it
|
|
||||||
immediately?
|
|
||||||
|
|
||||||
### Governance and control
|
|
||||||
|
|
||||||
30. Who should be able to create a trust community?
|
|
||||||
31. Who should decide its rules, membership, and removal process?
|
|
||||||
32. Should communities be able to split, merge, or recognize one another?
|
|
||||||
33. Should there always be a local setting that overrides every community and
|
|
||||||
institution?
|
|
||||||
34. Which emergency security announcements, if any, should be allowed to reach
|
|
||||||
everyone—and who should be permitted to issue them?
|
|
||||||
|
|
||||||
### Closing
|
|
||||||
|
|
||||||
35. What useful capability have these questions failed to mention?
|
|
||||||
36. What part of this idea sounds most valuable?
|
|
||||||
37. What part sounds most dangerous or unpleasant?
|
|
||||||
38. Would you personally try such a system? Why or why not?
|
|
||||||
|
|
||||||
## Very short version
|
|
||||||
|
|
||||||
Use these when there is time for only a brief conversation:
|
|
||||||
|
|
||||||
1. What makes an online service trustworthy to you?
|
|
||||||
2. Have browser security warnings ever helped or frustrated you?
|
|
||||||
3. Whose security advice would you accept, and whose would you reject?
|
|
||||||
4. Should advice remain visible as disagreement or become one browser verdict?
|
|
||||||
5. What could such a system do that would make you want it?
|
|
||||||
6. What could it do that would make you uninstall it immediately?
|
|
||||||
7. What information about your browsing must never leave your device?
|
|
||||||
8. When should the system advise, ask, block, or act automatically?
|
|
||||||
|
|
||||||
## Interviewer notes
|
|
||||||
|
|
||||||
- Ask for examples: “Can you remember a time when that happened?”
|
|
||||||
- Do not correct technical misunderstandings during the discovery portion.
|
|
||||||
Misunderstandings reveal what the interface will need to explain.
|
|
||||||
- Avoid presenting “the community” as inherently benevolent or “the authority”
|
|
||||||
as inherently malicious. Both can fail or be captured.
|
|
||||||
- Distinguish what the participant **wants**, what they would merely **tolerate**,
|
|
||||||
and what they would **refuse**.
|
|
||||||
- Record the intended activity. Trust for reading a public page may differ from
|
|
||||||
trust for payment, identity documents, private communication, or executable
|
|
||||||
software.
|
|
||||||
- Ask whether a desired automatic action should be the default or an explicit
|
|
||||||
opt-in.
|
|
||||||
- Record exact phrases when possible; they may suggest better UI language than
|
|
||||||
our engineering vocabulary.
|
|
||||||
- Do not collect names, browsing histories, or sensitive incidents unless the
|
|
||||||
participant knowingly chooses to share them.
|
|
||||||
|
|
||||||
## Synthesis questions for us
|
|
||||||
|
|
||||||
After several interviews, classify responses without forcing consensus:
|
|
||||||
|
|
||||||
- Which benefits recur across technically different participants?
|
|
||||||
- Which feared behaviours would be unacceptable even if technically useful?
|
|
||||||
- Which decisions do people want to retain personally?
|
|
||||||
- Which decisions are they willing to delegate, and to whom?
|
|
||||||
- Which activities require different trust standards?
|
|
||||||
- Where do people prefer visible disagreement over one combined score?
|
|
||||||
- What privacy cost are people unwilling to pay?
|
|
||||||
- Which terms were consistently misunderstood?
|
|
||||||
- Which requested benefits require distributed trust, and which could be solved
|
|
||||||
more safely by a local tool?
|
|
||||||
- What is the smallest system that produces a real user benefit?
|
|
||||||
|
|
||||||
@ -1,21 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
|
|
||||||
firefox_tree="${script_dir}/../browsec-firefox"
|
|
||||||
firefox_binary="${firefox_tree}/obj-x86_64-pc-linux-gnu/dist/bin/firefox"
|
|
||||||
|
|
||||||
if [[ ! -x "${firefox_binary}" ]]; then
|
|
||||||
echo "Browsec Firefox build not found at:" >&2
|
|
||||||
echo " ${firefox_binary}" >&2
|
|
||||||
echo "Build it first with: cd '${firefox_tree}' && ./mach build" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if (( $# == 0 )); then
|
|
||||||
set -- https://expired.badssl.com
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd "${firefox_tree}"
|
|
||||||
exec ./mach run --temp-profile "$@"
|
|
||||||
Loading…
x
Reference in New Issue
Block a user