Privacy-focused peer-to-peer communication platform built on Cloudflare Workers. Provides secure video chat, voice communication, AI-powered notes, and explicit consent management.
- Reliability Targets
- Roadmap
- Open Issues β Priority Tracker
- Open PRs β Merge Priority
- Features
- Architecture
- Quick Start
- Development Commands
- Testing
- Deployment
- Routes
- Repository Structure
- Security Notes
- Contributing
- License
The primary goal is for users to rely on BLT-SafeCloak in two distinct modes:
| Mode | Target | Status |
|---|---|---|
| Full Video | Up to 5 participants with camera + mic + screen share | π Stabilising (active bug fixes) |
| Audio / Walkie-Talkie | Up to 500 participants with push-to-talk floor control | ποΈ Architecture redesign required |
- 5-person video runs as a full WebRTC mesh (each peer connects to every other peer). This works well at β€5 nodes. The participant cap (
MAX_VIDEO_PARTICIPANTS = 5) is already enforced inpublic/js/video.js. - Walkie-talkie mode activates automatically above 5 participants, disabling video and enabling push-to-talk floor control. The current mesh architecture is estimated to support roughly 20β30 practical P2P audio peers (pending benchmark validation β see Phase 3). Reaching 500 requires a relay or selective-forwarding architecture (see Phase 3 below).
- M1 β Cloudflare Worker foundation with clean URL routing (
/,/video-chat,/video-room,/notes,/consent) - M2 β Separate pre-join lobby and in-room experience
- M3 β Voice effects, user preference persistence across lobby and room
- M4 β Walkie-talkie mode (auto-activated above 5 participants) with push-to-talk floor control
- M5 β Stable E2E test suite running in CI with local PeerJS signaling
- M6 β Consent-centred UX: declining recording does not block joining, alerts all peers instead
Goal: any group of up to 5 people can start a video call from scratch without hitting a blocking bug.
Must-fix bugs (blocking reliability):
- #116 Auto-join skips name prompt β joiners appear without a display name
- #100 Refresh reconnects a disconnected participant automatically
- #99 Screen-share makes local camera tile disappear
- #91 Noise suppression toggle in lobby has no effect
Priority PRs to review/merge:
- #123 Walkie-talkie audio constraints, peer-unavailable handling, device fallback + E2E test β merge first
- #63 Safari lobby camera/mic permission prompt not appearing
- #46 URL join handling β invalid peer ID init
- #38 Screen-share toggle fix
- #92 Noise suppression fix (resolves #91)
- #50 Toast warning style fix (resolves #111 β invisible toasts in light mode)
- #107 Allow call join on consent decline (resolves #106)
- #68 Validate legal checkbox in consent form (resolves #67)
- #114 Room-owner badge and stop invite-link auto-join from lobby (resolves #116 partially)
Goal: a club, class, or event team can use walkie-talkie mode reliably without floor-control glitches or audio dropouts.
- Automated stress tests for walkie-talkie mode with 10+ simulated peers
- Floor-request queue β show who is waiting to speak
- Reconnect logic hardening when a floor-holder drops mid-transmission
- Audio level visualiser in walkie-talkie mode (show who is transmitting)
- Mobile push-to-talk UX (large tap target, hold-to-speak gesture)
- Merge #101 β deafen control (auto-mutes mic, remote audio-only playback)
β οΈ The current full-mesh P2P model cannot scale to 500 simultaneous audio streams. Each peer would need ~499 connections. This phase requires a new architectural component.
Architecture options under consideration:
- Selective Forwarding Unit (SFU) β e.g. mediasoup or Janus. Each client sends one stream to the SFU, which forwards it selectively. Requires a long-running server outside Cloudflare Workers (traditional VPS/container infrastructure).
- Audio relay over Cloudflare Durable Objects β Durable Objects provide persistent state and long-running WebSocket connections on Cloudflare's edge, making them a candidate for a lightweight audio relay without leaving the Cloudflare platform; full SFU-grade media processing is not natively supported, so this option is best suited for signaling and floor-control relay with WebRTC media still flowing between peers at smaller scales. Feasibility TBD.
- Hierarchical audio mesh β a small set of "super-peers" relay audio to sub-groups. Lower infrastructure cost but harder floor control.
Prerequisite tasks:
- Open an architectural design issue and gather community input on SFU vs. relay approach
- Benchmark current mesh limit (measure degradation at 10, 20, 30 nodes)
- Evaluate Cloudflare Calls API or Durable Objects as a relay layer
- Add server-side signaling to coordinate floor control at scale
- Update E2E test harness to cover relay path
- Merge #57 / #30 β replace npx/npm wrangler with pywrangler (resolves #32; removes Node.js toolchain dependency from the Python-centric deployment path; see issue #32 for discussion)
- Merge #112 β comprehensive README + milestone docs
- Merge #43 β call health panel with WebRTC stats (helps diagnose relay issues)
- Merge #60 β PWA manifest + service worker (offline resilience)
- Merge #36 / #13 β sanitize caller name in consent modal (XSS fix)
- Merge #89 β use
Crypto.randomId()for consent entry IDs - Merge #49 β SRI integrity hashes for CDN assets
- Merge #48 β consolidate duplicate
escHtmlinto sharedui.js
| # | Title | Phase | Priority |
|---|---|---|---|
| #116 | Auto-join skips name prompt | 1 | π΄ High |
| #100 | Refresh reconnects disconnected participant | 1 | π΄ High |
| #99 | Screen share makes local video disappear | 1 | π΄ High |
| #91 | Noise suppression button no effect in lobby | 1 | π΄ High |
| #106 | Consent screen blocks join instead of alerting peers | 1 | π Medium |
| #111 | Toast notifications invisible in light mode | 1 | π Medium |
| #67 | Legal checkbox not validated before consent submit | 1 | π Medium |
| #108 | Avatar upload with real-time P2P propagation | 4 | π‘ Low |
| #32 | Move away from npx/npm | 4 | π‘ Low |
| #21 | Global light/dark theme toggle | 4 | π‘ Low |
| #19 | Consent modal contrast failure | 1 | π Medium |
| #18 | "Connect Securely" affordance improvement | 1 | π‘ Low |
PRs are grouped by the phase they unblock. Review Phase 1 PRs first.
| PR | Title | Resolves |
|---|---|---|
| #123 | Walkie-talkie audio constraints, error handling, device fallback | β |
| #114 | Room-owner badge; stop invite-link auto-join from lobby | #116 |
| #121 | Security headers + disable recording on consent decline | #106 |
| #115 | Allowlist-based CORS origin validation | β |
| #107 | Allow call join on consent decline | #106 |
| #92 | Noise suppression lobby fix | #91 |
| #63 | Safari camera/mic permission prompt | β |
| #50 | Toast warning style (light-mode visibility) | #111 |
| #46 | URL join handling β invalid peer init prevention | β |
| #38 | Screen-share toggle fix | #99 |
| #68 | Validate legal checkbox before consent submit | #67 |
| #37 | Modal contrast and design alignment | #19 |
| #36 / #13 | Sanitize caller name in consent modal (XSS) | β |
| PR | Title |
|---|---|
| #101 | Deafen control with mic auto-mute |
| #122 | Resizable sidebar for video room |
| PR | Title |
|---|---|
| #112 | Comprehensive README refresh |
| #57 / #30 | Replace npx/npm wrangler with pywrangler |
| #60 | PWA manifest + service worker |
| #56 | Room validation endpoints |
| #49 | SRI integrity hashes for CDN assets |
| #48 | Consolidate duplicate escHtml into ui.js |
| #47 | Font Awesome icon classes for mic/camera toggle |
| #45 | Fix anchor scroll offset |
| #43 | Call health panel with WebRTC stats |
| #41 | Anti-recording noise cloak |
| #31 | Increase E2E test timeout to 120 s |
| #28 | Emoji reactions + P2P chat |
| #12 | Real-time voice-changing effects |
| #10 | Options to start or join an existing call |
| #89 | Crypto.randomId() for consent entry IDs |
| #73 | Public room creation and homepage discovery |
| #66 | Mirror camera |
| #61 | Store passphrase in sessionStorage |
| #51 | Fix license field and setup script typo |
| #8 | Google Meet integration button |
| #7 | Footer: last updated time + commit SHA |
- P2P Video/Voice Chat: WebRTC-based communication with end-to-end encryption
- Adaptive mode: automatic switch to audio-only walkie-talkie when room exceeds 5 participants
- Consent Management: Built-in consent tracking; declining recording alerts peers rather than blocking the caller
- Secure Notes: AI-powered note-taking with client-side encryption
- Edge Computing: Deployed on Cloudflare's global network for low latency
- Zero-Knowledge Architecture: Server never accesses unencrypted content
- Backend: Python Workers on Cloudflare Edge
- Frontend: Vanilla JavaScript with WebRTC (PeerJS)
- Signaling: PeerJS public server (production) / local PeerJS server (CI/dev)
- Deployment: Cloudflare Workers with asset hosting
- Encryption: Client-side AES-GCM cryptography for all sensitive data
- Node.js 18+
- Python 3.11+
- Cloudflare account (for deployment)
npm install
npm run setupnpm run devApp runs at http://localhost:8787.
# format Python + frontend files
npm run format
# check formatting only
npm run format:check
# static type checks
npm run typecheck
# main quality gate (format:check + typecheck)
npm run check
# clean __pycache__ directories
npm run cleanInstall Playwright once before running video-chat E2E tests:
python -m playwright install chromium --with-depsRun all tests:
pytest tests/ -v --tb=shortCI runs the same suite via .github/workflows/test.yml.
npm run deployWrangler config is in wrangler.toml.
/β home / product overview/video-chatβ pre-join lobby/video-roomβ secure in-call room/notesβ secure notes interface/consentβ consent management
src/
main.py # Worker entrypoint and routing
libs/
utils.py # response helper utilities
pages/ # HTML pages
public/
css/ # styles
js/ # client logic (video, voice, notes, consent, ui, crypto)
img/ # static images
tests/
test_video_chat.py # end-to-end + integration behaviour checks
test_utils.py # backend utility and routing tests
.github/workflows/
test.yml # CI workflow
- All sensitive data is encrypted client-side before transmission.
- Server acts as a signaling relay only; no persistent storage of communication content.
- Consent verification is integrated into call workflows.
- If you find a vulnerability, please open a private/security-focused report through OWASP BLT project channels before public disclosure.
See CONTRIBUTING.md for development guidelines and resources.
MIT License β see LICENSE for details.
This project is part of the OWASP Bug Logging Tool (BLT) initiative.