mirror of
https://github.com/tlsnotary/tlsn-extension.git
synced 2026-01-08 04:34:01 -05:00
* demo: split generate and start in separate scripts * Include demo html and plugin files in docker image * Build docker images for demo * Add Cargo.lock
582 lines
18 KiB
Markdown
Executable File
582 lines
18 KiB
Markdown
Executable File
<img src="packages/extension/src/assets/img/icon-128.png" width="64"/>
|
|
|
|
# TLSN Extension Monorepo
|
|
|
|
A Chrome Extension for TLSNotary with plugin SDK and verifier server.
|
|
|
|
> [!IMPORTANT]
|
|
> When running the extension against a notary server, please ensure that the server's version is the same as the version of this extension.
|
|
|
|
## Table of Contents
|
|
|
|
- [Monorepo Structure](#monorepo-structure)
|
|
- [Architecture Overview](#architecture-overview)
|
|
- [Getting Started](#getting-started)
|
|
- [Development](#development)
|
|
- [Production Build](#production-build)
|
|
- [End-to-End Testing](#end-to-end-testing)
|
|
- [Running the Demo](#running-the-demo)
|
|
- [Websockify Integration](#websockify-integration)
|
|
- [Publishing](#publishing)
|
|
- [License](#license)
|
|
|
|
## Monorepo Structure
|
|
|
|
This repository is organized as an npm workspaces monorepo with six main packages:
|
|
|
|
```
|
|
tlsn-extension/
|
|
├── packages/
|
|
│ ├── extension/ # Chrome Extension (Manifest V3)
|
|
│ │ ├── src/
|
|
│ │ │ ├── entries/
|
|
│ │ │ │ ├── Background/ # Service worker for extension logic
|
|
│ │ │ │ ├── Content/ # Content scripts injected into pages
|
|
│ │ │ │ ├── DevConsole/ # Developer Console with code editor
|
|
│ │ │ │ ├── Popup/ # Extension popup UI (optional)
|
|
│ │ │ │ └── Offscreen/ # Offscreen document for DOM operations
|
|
│ │ │ ├── manifest.json
|
|
│ │ │ └── utils/
|
|
│ │ ├── webpack.config.js
|
|
│ │ └── package.json
|
|
│ │
|
|
│ ├── plugin-sdk/ # SDK for developing TLSN plugins
|
|
│ │ ├── src/
|
|
│ │ ├── examples/
|
|
│ │ └── package.json
|
|
│ │
|
|
│ ├── common/ # Shared utilities (logging system)
|
|
│ │ ├── src/
|
|
│ │ │ └── logger/ # Centralized logging with configurable levels
|
|
│ │ └── package.json
|
|
│ │
|
|
│ ├── verifier/ # Rust-based verifier server
|
|
│ │ ├── src/
|
|
│ │ │ └── main.rs # Server setup, routing, and verification
|
|
│ │ ├── config.yaml # Webhook configuration
|
|
│ │ └── Cargo.toml
|
|
│ │
|
|
│ ├── demo/ # Demo server with Docker setup
|
|
│ │ ├── *.js # Example plugin files
|
|
│ │ ├── docker-compose.yml # Docker services configuration
|
|
│ │ └── start.sh # Setup script with configurable URLs
|
|
│ │
|
|
│ ├── tutorial/ # Tutorial examples
|
|
│ │ └── *.js # Tutorial plugin files
|
|
│ │
|
|
│ └── tlsn-wasm-pkg/ # Pre-built TLSN WebAssembly package
|
|
│ └── (WASM binaries)
|
|
│
|
|
├── package.json # Root workspace configuration
|
|
└── README.md
|
|
```
|
|
|
|
### Package Details
|
|
|
|
#### 1. **extension** - Chrome Extension (Manifest V3)
|
|
A browser extension that enables TLSNotary functionality with the following key features:
|
|
- **Multi-Window Management**: Track multiple browser windows with request interception
|
|
- **Developer Console**: Interactive code editor for writing and testing TLSN plugins
|
|
- **Request Interception**: Capture HTTP/HTTPS requests from managed windows
|
|
- **Plugin Execution**: Run sandboxed JavaScript plugins using QuickJS
|
|
- **TLSN Overlay**: Visual display of intercepted requests
|
|
|
|
**Key Entry Points:**
|
|
- `Background`: Service worker for extension logic, window management, and message routing
|
|
- `Content`: Scripts injected into pages for communication and overlay display
|
|
- `DevConsole`: Code editor page accessible via right-click context menu
|
|
- `Popup`: Optional extension popup UI
|
|
- `Offscreen`: Background DOM operations for service worker limitations
|
|
|
|
#### 2. **plugin-sdk** - Plugin Development SDK
|
|
SDK for developing and running TLSN WebAssembly plugins with QuickJS sandboxing:
|
|
- Secure JavaScript execution in isolated WebAssembly environment
|
|
- Host capability system for controlled plugin access
|
|
- React-like hooks: `useHeaders()`, `useRequests()`, `useEffect()`, `useState()`, `setState()`
|
|
- Isomorphic package for Node.js and browser environments
|
|
- TypeScript support with full type declarations
|
|
|
|
#### 3. **common** - Shared Utilities
|
|
Centralized logging system used across packages:
|
|
- Configurable log levels: `DEBUG`, `INFO`, `WARN`, `ERROR`
|
|
- Timestamped output with level prefixes
|
|
- Singleton pattern for consistent logging across modules
|
|
|
|
#### 4. **verifier** - Verifier Server
|
|
Rust-based HTTP/WebSocket server for TLSNotary verification:
|
|
- Health check endpoint (`GET /health`)
|
|
- Session creation endpoint (`WS /session`)
|
|
- WebSocket verification endpoint (`WS /verifier?sessionId=<id>`)
|
|
- WebSocket proxy endpoint (`WS /proxy?token=<host>`) - compatible with notary.pse.dev
|
|
- Webhook API for POST notifications to external services
|
|
- YAML configuration for webhook endpoints (`config.yaml`)
|
|
- CORS enabled for cross-origin requests
|
|
- Runs on `localhost:7047` by default
|
|
|
|
#### 5. **demo** - Demo Server
|
|
Docker-based demo environment with:
|
|
- Pre-configured example plugins (Twitter, SwissBank)
|
|
- Docker Compose setup with verifier and nginx
|
|
- Configurable verifier URLs via environment variables
|
|
- Plugin file generator (`generate.sh`) with SSL support
|
|
- Docker startup script (`start.sh`)
|
|
|
|
#### 6. **tlsn-wasm-pkg** - TLSN WebAssembly Package
|
|
Pre-built WebAssembly binaries for TLSNotary functionality in the browser.
|
|
|
|
## Architecture Overview
|
|
|
|
### Extension Architecture
|
|
|
|
The extension uses a message-passing architecture with five main entry points:
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Browser Extension │
|
|
│ │
|
|
│ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ Background │◄────►│ Content │◄──── Page Scripts │
|
|
│ │ (SW) │ │ Script │ │
|
|
│ └──────┬───────┘ └──────────────┘ │
|
|
│ │ │
|
|
│ ├─► Window Management (WindowManager) │
|
|
│ ├─► Request Interception (webRequest API) │
|
|
│ ├─► Session Management (SessionManager) │
|
|
│ └─► Message Routing │
|
|
│ │
|
|
│ ┌──────────────┐ ┌──────────────┐ │
|
|
│ │ DevConsole │ │ Offscreen │ │
|
|
│ │ (Editor) │ │ (Background)│ │
|
|
│ └──────────────┘ └──────────────┘ │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
│
|
|
▼
|
|
┌──────────────┐
|
|
│ Verifier │
|
|
│ Server │
|
|
│ (localhost: │
|
|
│ 7047) │
|
|
└──────────────┘
|
|
```
|
|
|
|
### Message Flow
|
|
|
|
**Opening a Managed Window:**
|
|
```
|
|
Page → window.tlsn.open(url)
|
|
↓ window.postMessage(TLSN_OPEN_WINDOW)
|
|
Content Script → event listener
|
|
↓ browser.runtime.sendMessage(OPEN_WINDOW)
|
|
Background → WindowManager.registerWindow()
|
|
↓ browser.windows.create()
|
|
↓ Returns window info with UUID
|
|
```
|
|
|
|
**Request Interception:**
|
|
```
|
|
Browser → HTTP request in managed window
|
|
↓ webRequest.onBeforeRequest
|
|
Background → WindowManager.addRequest()
|
|
↓ browser.tabs.sendMessage(UPDATE_TLSN_REQUESTS)
|
|
Content Script → Update TLSN overlay UI
|
|
```
|
|
|
|
## Getting Started
|
|
|
|
### Prerequisites
|
|
|
|
- **Node.js** >= 18
|
|
- **Rust** (for verifier server) - Install from [rustup.rs](https://rustup.rs/)
|
|
- **Chrome/Chromium** browser
|
|
|
|
### Installation
|
|
|
|
1. Clone the repository:
|
|
```bash
|
|
git clone https://github.com/tlsnotary/tlsn-extension.git
|
|
cd tlsn-extension
|
|
```
|
|
|
|
2. Install all dependencies:
|
|
```bash
|
|
npm install
|
|
```
|
|
|
|
This installs dependencies for all packages in the monorepo and automatically sets up workspace links between packages.
|
|
|
|
## Development
|
|
|
|
### Running the Extension in Development Mode
|
|
|
|
1. Start the development server:
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
This automatically builds all dependencies (common, plugin-sdk) and then starts webpack-dev-server on port 3000 with hot module replacement. Files are written to `packages/extension/build/`.
|
|
|
|
2. Load the extension in Chrome:
|
|
- Navigate to `chrome://extensions/`
|
|
- Enable "Developer mode" toggle (top right)
|
|
- Click "Load unpacked"
|
|
- Select the `packages/extension/build/` folder
|
|
|
|
3. The extension will auto-reload on file changes (manual refresh needed for manifest changes).
|
|
|
|
### Running the Verifier Server
|
|
|
|
The verifier server is required for E2E testing. Run it in a separate terminal:
|
|
|
|
```bash
|
|
cd packages/verifier
|
|
cargo run
|
|
```
|
|
|
|
The server will start on `http://localhost:7047`.
|
|
|
|
**Verifier API Endpoints:**
|
|
- `GET /health` - Health check
|
|
- `WS /session` - Create new verification session
|
|
- `WS /verifier?sessionId=<id>` - WebSocket verification endpoint
|
|
- `WS /proxy?token=<host>` - WebSocket proxy for TLS connections (compatible with notary.pse.dev)
|
|
|
|
**Webhook Configuration:**
|
|
Configure `packages/verifier/config.yaml` to receive POST notifications after successful verifications:
|
|
```yaml
|
|
webhooks:
|
|
"api.x.com":
|
|
url: "https://your-backend.example.com/webhook/twitter"
|
|
headers:
|
|
Authorization: "Bearer your-secret-token"
|
|
"*": # Wildcard for unmatched server names
|
|
url: "https://your-backend.example.com/webhook/default"
|
|
```
|
|
|
|
### Package-Specific Development
|
|
|
|
**Extension:**
|
|
```bash
|
|
cd packages/extension
|
|
npm run dev # Development mode
|
|
npm run test # Run tests
|
|
npm run test:watch # Watch mode
|
|
npm run test:coverage # Coverage report
|
|
npm run lint # Lint check
|
|
npm run lint:fix # Auto-fix linting issues
|
|
```
|
|
|
|
**Plugin SDK:**
|
|
```bash
|
|
cd packages/plugin-sdk
|
|
npm run build # Build SDK
|
|
npm run test # Run tests
|
|
npm run lint # Run all linters
|
|
npm run lint:fix # Auto-fix issues
|
|
```
|
|
|
|
> **Note:** The plugin-SDK builds automatically when the extension is built, so manual building is usually not necessary.
|
|
|
|
**Verifier:**
|
|
```bash
|
|
cd packages/verifier
|
|
cargo run # Development mode
|
|
cargo build --release # Production build
|
|
cargo test # Run tests
|
|
```
|
|
|
|
## Production Build
|
|
|
|
### Build Extension for Production
|
|
|
|
From the repository root:
|
|
|
|
```bash
|
|
NODE_ENV=production npm run build
|
|
```
|
|
|
|
This automatically:
|
|
1. Builds dependencies (`@tlsn/common` and `@tlsn/plugin-sdk`)
|
|
2. Builds the extension with production optimizations
|
|
3. Creates:
|
|
- Optimized build in `packages/extension/build/`
|
|
- Packaged extension in `packages/extension/zip/extension-{version}.zip`
|
|
|
|
The zip file is ready for Chrome Web Store submission.
|
|
|
|
**Alternative build commands:**
|
|
- `npm run build:extension` - Build only the extension (assumes dependencies are built)
|
|
- `npm run build:deps` - Build only the dependencies
|
|
|
|
### Build All Packages
|
|
|
|
```bash
|
|
npm run build:all
|
|
```
|
|
|
|
This builds all packages in the monorepo (extension, plugin-sdk).
|
|
|
|
### Build Verifier for Production
|
|
|
|
```bash
|
|
cd packages/verifier
|
|
cargo build --release
|
|
```
|
|
|
|
The binary will be in `target/release/`.
|
|
|
|
## End-to-End Testing
|
|
|
|
To test the complete TLSN workflow:
|
|
|
|
### 1. Start the Verifier Server
|
|
|
|
In a terminal:
|
|
```bash
|
|
cd packages/verifier
|
|
cargo run
|
|
```
|
|
|
|
Verify it's running:
|
|
```bash
|
|
curl http://localhost:7047/health
|
|
# Should return: ok
|
|
```
|
|
|
|
### 2. Start the Extension in Development Mode
|
|
|
|
In another terminal:
|
|
```bash
|
|
npm run dev
|
|
```
|
|
|
|
Load the extension in Chrome (see [Getting Started](#getting-started)).
|
|
|
|
### 3. Open the Developer Console
|
|
|
|
1. Right-click anywhere on any web page
|
|
2. Select "Developer Console" from the context menu
|
|
3. A new tab will open with the code editor
|
|
|
|
### 4. Run a Test Plugin
|
|
|
|
The Developer Console comes with a default X.com profile prover plugin. To test:
|
|
|
|
1. Ensure the verifier is running on `localhost:7047`
|
|
2. Review the default code in the editor (or modify as needed)
|
|
3. Click "▶️ Run Code" button
|
|
4. The plugin will:
|
|
- Open a new window to X.com
|
|
- Intercept requests
|
|
- Create a prover connection to the verifier
|
|
- Display a UI overlay showing progress
|
|
- Execute the proof workflow
|
|
|
|
**Console Output:**
|
|
- Execution status and timing
|
|
- Plugin logs and results
|
|
- Any errors encountered
|
|
|
|
### 5. Verify Request Interception
|
|
|
|
When a managed window is opened:
|
|
1. An overlay appears showing "TLSN Plugin In Progress"
|
|
2. Intercepted requests are listed in real-time
|
|
3. Request count updates as more requests are captured
|
|
|
|
### Testing Different Plugins
|
|
|
|
You can write custom plugins in the Developer Console editor:
|
|
|
|
```javascript
|
|
// Example: Simple plugin that generates a proof
|
|
const config = {
|
|
name: 'My Plugin',
|
|
description: 'A custom TLSN plugin'
|
|
};
|
|
|
|
async function onClick() {
|
|
console.log('Starting proof...');
|
|
|
|
// Wait for specific headers to be intercepted
|
|
const [header] = useHeaders(headers => {
|
|
return headers.filter(h => h.url.includes('example.com'));
|
|
});
|
|
|
|
console.log('Captured header:', header);
|
|
|
|
// Generate proof using unified prove() API
|
|
const proof = await prove(
|
|
// Request options
|
|
{
|
|
url: 'https://example.com/api/endpoint',
|
|
method: 'GET',
|
|
headers: {
|
|
'Authorization': header.requestHeaders.find(h => h.name === 'Authorization')?.value,
|
|
'Accept-Encoding': 'identity',
|
|
'Connection': 'close',
|
|
},
|
|
},
|
|
// Prover options
|
|
{
|
|
verifierUrl: 'http://localhost:7047',
|
|
proxyUrl: 'wss://notary.pse.dev/proxy?token=example.com',
|
|
maxRecvData: 16384,
|
|
maxSentData: 4096,
|
|
handlers: [
|
|
{ type: 'SENT', part: 'START_LINE', action: 'REVEAL' },
|
|
{ type: 'RECV', part: 'START_LINE', action: 'REVEAL' },
|
|
{ type: 'RECV', part: 'BODY', action: 'REVEAL',
|
|
params: { type: 'json', path: 'username' } }
|
|
]
|
|
}
|
|
);
|
|
|
|
console.log('Proof generated:', proof);
|
|
done(JSON.stringify(proof));
|
|
}
|
|
|
|
function main() {
|
|
const [header] = useHeaders(headers => {
|
|
return headers.filter(h => h.url.includes('example.com'));
|
|
});
|
|
|
|
// Open a managed window on first render
|
|
useEffect(() => {
|
|
openWindow('https://example.com');
|
|
}, []);
|
|
|
|
// Render plugin UI component
|
|
return div({}, [
|
|
div({}, [header ? 'Ready to prove' : 'Waiting for headers...']),
|
|
header ? button({ onclick: 'onClick' }, ['Generate Proof']) : null
|
|
]);
|
|
}
|
|
|
|
export default {
|
|
main,
|
|
onClick,
|
|
config,
|
|
};
|
|
```
|
|
|
|
### Testing Tips
|
|
|
|
- **Monitor Background Service Worker**: Open Chrome DevTools for the background service worker via `chrome://extensions/` → Extension Details → "Inspect views: service worker"
|
|
- **Check Console Logs**: Look for WindowManager logs, request interception logs, and message routing logs
|
|
- **Test Multiple Windows**: Try opening multiple managed windows simultaneously (max 10)
|
|
- **Verifier Connection**: Ensure verifier is accessible at `localhost:7047` before running proofs
|
|
|
|
## Running the Demo
|
|
|
|
The demo package provides a complete environment for testing TLSNotary plugins.
|
|
|
|
### Quick Start with Docker
|
|
|
|
```bash
|
|
# Start all services (verifier + demo server)
|
|
npm run docker:up
|
|
|
|
# Stop services
|
|
npm run docker:down
|
|
```
|
|
|
|
This starts:
|
|
- Verifier server on port 7047
|
|
- Demo static files served via nginx on port 80
|
|
|
|
### Manual Demo Setup
|
|
|
|
```bash
|
|
# Serve demo files locally
|
|
npm run demo
|
|
|
|
# Open http://localhost:8080 in your browser
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
Configure the demo for different environments:
|
|
```bash
|
|
# Local development (default)
|
|
cd packages/demo
|
|
./generate.sh && ./start.sh
|
|
|
|
# Production with SSL
|
|
cd packages/demo
|
|
VERIFIER_HOST=verifier.tlsnotary.org SSL=true ./generate.sh
|
|
./start.sh
|
|
|
|
# Docker detached mode
|
|
./generate.sh && ./start.sh -d
|
|
```
|
|
|
|
The demo uses two scripts:
|
|
- **`generate.sh`** - Generates plugin files with configured verifier URLs (use environment variables here)
|
|
- **`start.sh`** - Starts Docker Compose services (assumes `generated/` directory exists)
|
|
|
|
### Tutorial
|
|
|
|
```bash
|
|
# Serve tutorial examples
|
|
npm run tutorial
|
|
|
|
# Open http://localhost:8080 in your browser
|
|
```
|
|
|
|
## Websockify Integration
|
|
|
|
For WebSocket proxying of TLS connections (optional):
|
|
|
|
### Build Websockify Docker Image
|
|
```bash
|
|
git clone https://github.com/novnc/websockify && cd websockify
|
|
./docker/build.sh
|
|
```
|
|
|
|
### Run Websockify
|
|
```bash
|
|
# For X.com
|
|
docker run -it --rm -p 55688:80 novnc/websockify 80 api.x.com:443
|
|
|
|
# For Twitter
|
|
docker run -it --rm -p 55688:80 novnc/websockify 80 api.twitter.com:443
|
|
```
|
|
|
|
This proxies HTTPS connections through WebSocket for browser-based TLS operations.
|
|
|
|
## Publishing
|
|
|
|
### Chrome Web Store
|
|
|
|
1. Create a production build:
|
|
```bash
|
|
NODE_ENV=production npm run build
|
|
```
|
|
|
|
2. Test the extension thoroughly
|
|
|
|
3. Upload `packages/extension/zip/extension-{version}.zip` to [Chrome Web Store Developer Dashboard](https://chrome.google.com/webstore/devconsole)
|
|
|
|
4. Follow the [Chrome Web Store publishing guide](https://developer.chrome.com/webstore/publish)
|
|
|
|
### Pre-built Extension
|
|
|
|
The easiest way to install the TLSN browser extension is from the [Chrome Web Store](https://chromewebstore.google.com/detail/tlsn-extension/gcfkkledipjbgdbimfpijgbkhajiaaph).
|
|
|
|
## Resources
|
|
|
|
- [TLSNotary Documentation](https://docs.tlsnotary.org/)
|
|
- [Webpack Documentation](https://webpack.js.org/concepts/)
|
|
- [Chrome Extension Documentation](https://developer.chrome.com/docs/extensions/)
|
|
- [Manifest V3 Migration Guide](https://developer.chrome.com/docs/extensions/mv3/intro/)
|
|
- [webextension-polyfill](https://github.com/mozilla/webextension-polyfill)
|
|
|
|
## License
|
|
|
|
This repository is licensed under either of:
|
|
|
|
- [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0)
|
|
- [MIT license](http://opensource.org/licenses/MIT)
|
|
|
|
at your option.
|