Preserve first-session design context
This commit is contained in:
parent
d22dbcbb72
commit
afa2128953
@ -47,6 +47,7 @@ And its project motto keeps the same principle courteous:
|
||||
## Project documents
|
||||
|
||||
- [Wake-up point and roadmap](ROADMAP.md)
|
||||
- [First-session continuity notes](SESSION_NOTES.md)
|
||||
- [Coarse-grained concept](CONCEPT.md)
|
||||
- [Architecture decisions](ARCHITECTURE.md)
|
||||
- [Certificate Investigator design](DESIGN.md)
|
||||
|
||||
273
SESSION_NOTES.md
Normal file
273
SESSION_NOTES.md
Normal file
@ -0,0 +1,273 @@
|
||||
# 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.
|
||||
|
||||
## Exact next implementation seam
|
||||
|
||||
Implement named trust providers before adding more global policy behavior.
|
||||
|
||||
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:
|
||||
|
||||
- provider ID and human name;
|
||||
- provider kind;
|
||||
- snapshot ID/version;
|
||||
- observation or effective time;
|
||||
- exact recognized/distrusted anchor fingerprint;
|
||||
- supporting reason codes.
|
||||
|
||||
Build two browserless reference providers first:
|
||||
|
||||
1. An explicit in-memory anchor set.
|
||||
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
|
||||
|
||||
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).
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user