386 lines
17 KiB
Markdown
386 lines
17 KiB
Markdown
# Session continuity notes
|
|
|
|
These notes preserve the context of Browsec's first design and implementation
|
|
session. Read this file together with [`ROADMAP.md`](ROADMAP.md), then consult
|
|
the detailed concept and architecture documents only as needed.
|
|
|
|
## People and repository
|
|
|
|
- Project creator: **sergeych** (`sergeych <real.sergeych@gmail.com>`).
|
|
- AI design and implementation collaborator: **Codex (OpenAI)**.
|
|
- Repository: `ssh://git@gitea.sergeych.net:2291/SergeychWorks/browsec.git`.
|
|
- Main branch: `main`.
|
|
- The repository was clean and fully pushed when these notes were written.
|
|
- Work was intentionally committed in small conceptual milestones.
|
|
|
|
## Why the project exists
|
|
|
|
The starting problem is that conventional browser TLS trust is governed by a
|
|
global authority model that users cannot meaningfully replace or refine. A user
|
|
may need to investigate broken certificates, trust a precise local certificate
|
|
or CA, distrust an otherwise globally accepted authority, and eventually use
|
|
community trust without surrendering the final decision to another central
|
|
operator.
|
|
|
|
The intended browser is a genuinely independent Firefox downstream. Chromium
|
|
was considered but rejected as a poorer base for the project's independence and
|
|
governance goals. TrustLab exists so the security model can be developed and
|
|
tested browserlessly before modifying Firefox NSS/PSM.
|
|
|
|
The primary scope remains TLS trust substitution. The plugin API should not grow
|
|
into a general browser-extension “Swiss army knife” until that narrow security
|
|
problem is sound.
|
|
|
|
## Naming and character
|
|
|
|
- **Browsec**: the browser project.
|
|
- **Velvet Hammer**: the trust engine.
|
|
- **TrustLab**: the browser-neutral research and diagnostic tool.
|
|
- **Browsec Trust API**: the strict plugin contract.
|
|
|
|
The engine name expresses a deliberate combination: a calm and comprehensible
|
|
surface around rigid security boundaries. The proposed emblem is a restrained,
|
|
polished spherical hammer head with a short handle, possibly meeting a
|
|
certificate-chain link.
|
|
|
|
Project language established during the session includes *Velvet verdict*,
|
|
*Hammer rule*, and *TrustLab powered by Velvet Hammer*.
|
|
|
|
Two sentences capture the project's temperament:
|
|
|
|
> The hammer permits no silent widening of scope.
|
|
|
|
> If one must be struck by security policy, let it be by a respectable velvet
|
|
> hammer: precise, accountable, and courteous enough to explain why.
|
|
|
|
## Core design decisions
|
|
|
|
### The plugin chain contains the decision
|
|
|
|
There is no hidden “browser god” outside the plugin chain making an unexplained
|
|
final trust choice. The immutable Browsec final handler is itself the final
|
|
plugin and cannot be removed or replaced. This keeps the model compositionally
|
|
honest while preserving a fail-closed terminus.
|
|
|
|
Every configured plugin has one explicit role:
|
|
|
|
- observer;
|
|
- advisor;
|
|
- decision authority;
|
|
- veto authority.
|
|
|
|
Roles are local configuration, not powers self-declared by plugin packages.
|
|
Plugins may contribute evidence, warnings, and advisory votes as appropriate,
|
|
but only explicitly authorized roles can return terminal Boolean verdicts.
|
|
|
|
### Facts, interpretation, and decisions remain separate
|
|
|
|
The TLS connection produces immutable facts. Plugins append attributed entries
|
|
to a journal; they cannot rewrite the facts or previous entries. A terminal
|
|
verdict references the journal entries supporting it.
|
|
|
|
The final trust boundary is Boolean. Nuance and uncertainty remain visible in
|
|
evidence and votes rather than producing an ambiguous terminal value.
|
|
|
|
### Scope is explicit and rigid
|
|
|
|
A verdict declares:
|
|
|
|
- `trusted: true | false`;
|
|
- exact certificate-for-host or exact DER authority-for-host scope;
|
|
- port scope;
|
|
- optional subdomain scope for an authority;
|
|
- connection, session, timed, or persistent lifetime;
|
|
- supporting journal entries;
|
|
- the exact TLS errors it overrides.
|
|
|
|
“Trust once” was rejected as ambiguous terminology. The implementation uses
|
|
explicit connection and session lifetimes.
|
|
|
|
An authority rule identifies the SHA-256 fingerprint of the exact DER CA
|
|
certificate, not merely a subject name or public key. The CA must occur in the
|
|
active chain, have DER-confirmed Basic Constraints, permit `keyCertSign`, and
|
|
contain no unsupported critical extensions. Authority trust may repair only
|
|
trust-anchor failures; it cannot excuse expiry, hostname mismatch, signature
|
|
failure, or another independent error.
|
|
|
|
Local distrust has precedence over matching local trust.
|
|
|
|
### Interactive and background work
|
|
|
|
`onBeforeTlsAccept` is deliberately synchronous and fast. It may use already
|
|
available local state but cannot wait for network or UI.
|
|
|
|
Failed navigation is handled through asynchronous `onTlsFailure`, where an
|
|
authorized plugin may present clearly browser-owned UI and then request a fresh
|
|
connection retry. Background evidence collection is independent of the fast
|
|
success path.
|
|
|
|
Plugins may eventually perform community or peer-to-peer background work, but
|
|
those mechanisms do not receive implicit decision authority.
|
|
|
|
### Security UI cannot look like web content
|
|
|
|
The future browser-owned decision surface must be unmistakably distinct from
|
|
ordinary pages and extension content. TrustLab currently simulates this with a
|
|
fixed security frame and synthetic/live/offline seals. This distinction must be
|
|
implemented with stronger browser chrome when Firefox integration begins.
|
|
|
|
## What was implemented
|
|
|
|
### Trust runtime
|
|
|
|
- Strict TypeScript API version `0.1`.
|
|
- Dependency-free JavaScript reference runner.
|
|
- Immutable normalized TLS facts.
|
|
- Append-only attributed journal.
|
|
- Plugin timeouts, mode enforcement, and immutable final handler.
|
|
- In-memory scoped policy overlay exposed as an ordinary plugin.
|
|
- Connection/session/timed/persistent rules and explicit rule history.
|
|
|
|
### Live TLS microscope
|
|
|
|
From `trustlab/`:
|
|
|
|
```sh
|
|
npm run probe -- example.com
|
|
npm run probe -- expired.badssl.com --json
|
|
npm run ui
|
|
```
|
|
|
|
The read-only probe records TLS protocol and cipher, conventional OpenSSL trust,
|
|
certificate DER/SPKI fingerprints, identities, dates, signatures, normalized
|
|
failure categories, and observed-chain caveats. It never modifies a trust store.
|
|
|
|
The local UI server binds to `127.0.0.1`, accepts a small same-origin JSON POST,
|
|
and enforces a ten-second probe timeout. A browser can enter a live hostname and
|
|
use the same TrustLab plugin chain and diagnostic UI as synthetic fixtures.
|
|
|
|
Node/OpenSSL does not expose a reliable boundary between server-sent
|
|
certificates and certificates added during construction. The current report
|
|
therefore labels its chain as an observed peer chain and duplicates it into the
|
|
API's presented/constructed fields rather than pretending certainty.
|
|
|
|
### DER explorer
|
|
|
|
The browser-compatible DER reader is dependency-free and enforces definite,
|
|
minimal lengths, container boundaries, node-count limits, and nesting limits.
|
|
It retains a byte-offset tree and every extension's original bytes.
|
|
|
|
Implemented semantic decoders include:
|
|
|
|
- Basic Constraints;
|
|
- Key Usage;
|
|
- Extended Key Usage OIDs;
|
|
- Subject Key Identifier;
|
|
- Authority Key Identifier;
|
|
- Subject Alternative Name DNS/IP/email/URI forms.
|
|
|
|
The UI synchronizes ASN.1 nodes with hexadecimal bytes in both directions and
|
|
allows original `.der` export. Recognizing an extension's name is intentionally
|
|
different from supporting its semantics; an unsupported critical extension
|
|
fails closed even if its OID has a friendly label.
|
|
|
|
### Explainable path construction
|
|
|
|
The live probe evaluates every possible issuer pair among observed certificates
|
|
and records:
|
|
|
|
- issuer/subject match;
|
|
- cryptographic signature verification;
|
|
- AKI/SKI match when both identifiers exist;
|
|
- issuer CA and signing eligibility;
|
|
- critical-extension blockers.
|
|
|
|
It enumerates acyclic candidate paths and independently records structural
|
|
termination, provider-attributed trust, validity failures, and path-length
|
|
constraint violations. Thus “where a path goes” is distinct from “whether the
|
|
path is valid” and “who trusts its terminus.”
|
|
|
|
### Offline investigation bundles
|
|
|
|
Versioned `.browsec-investigation.json` files include original public DER,
|
|
facts, findings, path analysis, decision journal, verdict, and policy history.
|
|
They explicitly declare that no private keys or TLS session secrets are present.
|
|
|
|
Import is capped at 10 MiB, reparses DER, recomputes SHA-256 fingerprints, and
|
|
rebuilds DER-derived CA, Key Usage, critical-extension, SAN, SKI, and AKI facts.
|
|
Imported verdicts and policy remain historical evidence and are not activated.
|
|
|
|
## Verification at handoff
|
|
|
|
The last complete local verification passed:
|
|
|
|
```sh
|
|
cd trustlab
|
|
npm test
|
|
npm run check
|
|
npm run build
|
|
```
|
|
|
|
There were **38 passing tests**. Live checks also behaved as intended:
|
|
|
|
- `example.com`: one structurally and cryptographically valid path, attributed
|
|
to the Node/OpenSSL conventional-validation terminus.
|
|
- `expired.badssl.com`: a structurally linked path independently marked invalid
|
|
because two exact certificates were expired.
|
|
|
|
Use `git status --short` before new work. Existing uncommitted changes, if any,
|
|
must be treated as belonging to the user.
|
|
|
|
## Corrected next implementation seam
|
|
|
|
The primary goal is the Browsec Firefox host and its privileged security-
|
|
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:
|
|
|
|
1. The narrow Firefox NSS/PSM adapter that creates `TlsFacts`, invokes the trust
|
|
chain, and performs a fresh scoped retry.
|
|
2. The privileged-extension host, package/capability grants, protected UI, and
|
|
isolated general-purpose storage broker. Extensions may retain any
|
|
information needed for their security function, subject to explicit
|
|
capabilities, quotas, inspection, export, deletion, and network controls.
|
|
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
|
|
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
|
|
or distributed trust providers.
|
|
|
|
## Files to open first next session
|
|
|
|
1. [`ROADMAP.md`](ROADMAP.md)
|
|
2. [`trustlab/sdk/plugin-api.ts`](trustlab/sdk/plugin-api.ts)
|
|
3. [`trustlab/src/path-analysis.js`](trustlab/src/path-analysis.js)
|
|
4. [`trustlab/src/der-explorer.js`](trustlab/src/der-explorer.js)
|
|
5. [`trustlab/src/investigation-bundle.js`](trustlab/src/investigation-bundle.js)
|
|
6. [`trustlab/ui/app.js`](trustlab/ui/app.js)
|
|
|
|
The conceptual documents remain authoritative for broader intent:
|
|
[`CONCEPT.md`](CONCEPT.md), [`ARCHITECTURE.md`](ARCHITECTURE.md), and
|
|
[`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.
|