347 lines
17 KiB
Markdown
347 lines
17 KiB
Markdown
# MD Hub Secure - Project Plan
|
|
|
|
**Version:** 1.0\
|
|
**Date:** 2026-04-28\
|
|
**Status:** Draft
|
|
|
|
## Vision
|
|
|
|
A minimal-dependency, ultra-fast documentation platform that publishes markdown notes as a responsive web application. Features wiki-style linking, collaborative comments, offline-capable sync, and fine-grained access control — all deployable via a single `docker-compose.yml` with zero vendor lock-in.
|
|
|
|
## Design Principles
|
|
|
|
1. **Paranoid Security**: Cryptographic content verification, battle-tested dependencies only, supply-chain attack mitigation through minimal external code
|
|
2. **Operational Simplicity**: Single binary, single SQLite database, filesystem storage — nothing that can't be understood in an afternoon
|
|
3. **Performance First**: Sub-100ms initial page loads, instant client-side navigation, no JavaScript required for reading
|
|
4. **Offline Capability**: Read cached, sync when connected
|
|
5. **No Vendor Lock-in**: Works on any Docker host; no cloud-specific APIs
|
|
|
|
---
|
|
|
|
## Milestones
|
|
|
|
### Milestone 1: Foundation (Weeks 1-2)
|
|
|
|
**Goal:** Working server that can serve markdown files as HTML
|
|
|
|
- Go HTTP server with chi router
|
|
- libsql database with schema migration system
|
|
- Markdown-to-HTML pipeline with most common extensions enabled
|
|
- Static file serving for attachments
|
|
- Basic Dockerfile and docker-compose.yml
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
- [ ] Server starts and listens on configurable port
|
|
- [ ] Database auto-migrates on startup
|
|
- [ ] Markdown files with wiki-links, tags, callouts, mermaid, math render correctly
|
|
- [ ] Attachments served securely with content-type headers
|
|
- [ ] Docker compose brings up full stack with one command
|
|
- [ ] All dependencies pinned with checksum verification
|
|
- [ ] Build reproducible (same input → same binary hash)
|
|
|
|
---
|
|
|
|
### Milestone 2: Sync Protocol (Weeks 3-4)
|
|
|
|
**Goal:** Bidirectional file sync between server and filesystem/web client
|
|
|
|
- Content-addressed storage (SHA-256 filesystem layout)
|
|
- WebSocket sync protocol implementation
|
|
- File watcher for local filesystem sync
|
|
- Client-side IndexedDB cache
|
|
- Offline queue with conflict detection
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
- [ ] File changes on disk automatically sync to server within 5 seconds
|
|
- [ ] Web client can sync after reconnection, even with changes made offline
|
|
- [ ] Concurrent edits to different files succeed without conflict
|
|
- [ ] Concurrent edits to same file detected and queued for resolution
|
|
- [ ] All synced content verified against SHA-256 hashes
|
|
- [ ] Sync protocol documented with state machine diagrams
|
|
|
|
---
|
|
|
|
### Milestone 3: Authentication & Authorization (Weeks 5-6)
|
|
|
|
**Goal:** Secure access control with passkeys and granular permissions
|
|
|
|
- Passkey (WebAuthn) primary authentication
|
|
- Password fallback with Argon2id
|
|
- Session management with signed cookies
|
|
- Role-based access control (RBAC)
|
|
- Content signing with Ed25519 (optional per-user)
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
- [ ] Users can register and log in with passkeys on modern browsers
|
|
- [ ] Password fallback works with proper hashing
|
|
- [ ] Sessions expire securely and are revocable
|
|
- [ ] Read/write/admin permissions work per-document and per-collection
|
|
- [ ] All auth endpoints rate-limited and logged
|
|
- [ ] Security audit: no plaintext secrets, no timing attacks on auth
|
|
|
|
---
|
|
|
|
### Milestone 4: Collaboration Features (Weeks 7-8)
|
|
|
|
**Goal:** Comments, notifications, and conflict resolution
|
|
|
|
- Comment system linked to file versions (by hash)
|
|
- Email notifications via Postmark adapter
|
|
- Web-based conflict resolution UI
|
|
- Notification preferences (per-file, per-folder, global, digest)
|
|
- Comment threading and email replies
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
- [ ] Users can comment on specific lines/sections of a document
|
|
- [ ] Comments persist and are linked to document versions
|
|
- [ ] Email notifications sent for watched file changes
|
|
- [ ] Replying to notification email creates a comment
|
|
- [ ] Conflicts display side-by-side diff with resolution actions
|
|
- [ ] Digest mode batches notifications by time window
|
|
|
|
---
|
|
|
|
### Milestone 5: Search & UI Polish (Weeks 9-10)
|
|
|
|
**Goal:** Fast search, design system, and production readiness
|
|
|
|
- Full-text search with SQLite FTS5
|
|
- Client-side search index sync
|
|
- Design system with browser-based CSS editor
|
|
- Responsive mobile layout
|
|
- Error boundaries and loading states
|
|
- Performance benchmarking
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
- [ ] Search returns results in <50ms on client
|
|
- [ ] Search works offline after initial sync
|
|
- [ ] Design system documented at `/design` route
|
|
- [ ] All screens responsive down to 320px width
|
|
- [ ] Lighthouse score >90 on all metrics
|
|
- [ ] Initial page load <100ms (server-rendered HTML)
|
|
|
|
---
|
|
|
|
### Milestone 6: Production Hardening (Weeks 11-12)
|
|
|
|
**Goal:** Deploy with confidence
|
|
|
|
- Comprehensive test suite (unit, integration, e2e)
|
|
- Security audit and penetration testing guide
|
|
- Backup and restore procedures
|
|
- Monitoring and health checks
|
|
- Documentation for operators
|
|
|
|
**Acceptance Criteria:**
|
|
|
|
- [ ] 80% test coverage
|
|
- [ ] No critical or high-severity security findings
|
|
- [ ] Backup script exports database + attachments as tar.gz
|
|
- [ ] Health check endpoint returns status of all dependencies
|
|
- [ ] Operator docs cover: install, upgrade, backup, security incident response
|
|
- [ ] Load test: 1000 concurrent readers, 100 concurrent editors
|
|
|
|
---
|
|
|
|
## Architecture Overview
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Client Browser │
|
|
│ ┌──────────────┐ ┌──────────────┐ ┌─────────────────┐ │
|
|
│ │ Preact UI │ │ File Sync │ │ Search Index │ │
|
|
│ │ (hydrated) │ │ (IndexedDB) │ │ (FTS5) │ │
|
|
│ └──────────────┘ └──────────────┘ └─────────────────┘ │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
│
|
|
WebSocket / HTTP
|
|
│
|
|
┌─────────────────────────────────────────────────────────────┐
|
|
│ Go Application Server │
|
|
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌──────────┐ │
|
|
│ │ HTTP │ │ WebSocket │ │ Markdown │ │ Auth │ │
|
|
│ │ Router │ │ Sync │ │ Renderer │ │ (WebAuthn)│ │
|
|
│ └────────────┘ └────────────┘ └────────────┘ └──────────┘ │
|
|
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
|
│ │ Email │ │ Search │ │ File Watch │ │
|
|
│ │ (Postmark)│ │ (FTS5) │ │ (fsnotify)│ │
|
|
│ └────────────┘ └────────────┘ └────────────┘ │
|
|
└─────────────────────────────────────────────────────────────┘
|
|
│
|
|
┌──────────────────┴──────────────────┐
|
|
│ │
|
|
┌──────────────┐ ┌──────────────┐
|
|
│ libsql │ │ Content- │
|
|
│ (SQLite) │ │ Addressed │
|
|
│ │ │ Filesystem │
|
|
└──────────────┘ └──────────────┘
|
|
```
|
|
|
|
See [architecture-overview.md](architecture-overview.md) for detailed component design.
|
|
|
|
---
|
|
|
|
## Technology Stack
|
|
|
|
### Backend (Go 1.22+)
|
|
|
|
| Component | Library | Justification |
|
|
| ------------- | ------------------------------------------- | ---------------------------------------- |
|
|
| HTTP Router | `github.com/go-chi/chi` | Minimal, idiomatic, stdlib-compatible |
|
|
| Database | `github.com/tursodatabase/libsql-client-go` | Embedded SQLite with replication option |
|
|
| Migrations | `github.com/golang-migrate/migrate` | Battle-tested, version-controlled schema |
|
|
| Auth/Passkeys | `github.com/go-webauthn/webauthn` | Reference implementation, well-audited |
|
|
| Password Hash | `golang.org/x/crypto/argon2` | Winner of Password Hashing Competition |
|
|
| Markdown | `github.com/yuin/goldmark` + extensions | Fast, extensible, CommonMark compliant |
|
|
| WebSocket | `github.com/gorilla/websocket` | Most widely used Go WS library |
|
|
| File Watch | `github.com/fsnotify/fsnotify` | Cross-platform, stdlib-adjacent |
|
|
| Email | `github.com/keighl/postmark` + `net/smtp` | Postmark adapter + SMTP fallback |
|
|
| Crypto | `crypto/ed25519`, `crypto/sha256` | Standard library, no external deps |
|
|
| Templates | `html/template` | Stdlib, auto-escaping, SSR-safe |
|
|
|
|
### Frontend (Preact + TypeScript)
|
|
|
|
| Component | Library | Justification |
|
|
| --------- | ------------------------------ | --------------------------------------- |
|
|
| Framework | `preact` (10KB) | React API, tiny bundle, fast hydration |
|
|
| Routing | `preact-iso` | Lightweight isomorphic routing |
|
|
| Markdown | `marked` + `micromark` | Server+client compatible |
|
|
| Search | `flexsearch` | Client-side full-text, zero server load |
|
|
| Styling | Native CSS + custom properties | No build-time CSS processing needed |
|
|
| Icons | Inline SVG | No icon font dependency |
|
|
| Build | `vite` | Fast HMR, modern output, minimal config |
|
|
|
|
### Infrastructure
|
|
|
|
| Component | Technology | Justification |
|
|
| ------------- | ------------------ | --------------------------------------------- |
|
|
| Container | Docker + Compose | Universal deployment target |
|
|
| Reverse Proxy | Traefik (optional) | Auto-HTTPS, included in compose |
|
|
| Database | libsql/SQLite | Single file, zero external dependency |
|
|
| Storage | Local filesystem | Content-addressed, immutable, backup-friendly |
|
|
|
|
---
|
|
|
|
## Security Model
|
|
|
|
### Threats Addressed
|
|
|
|
1. **Supply Chain Attacks**: Minimal external dependencies; all pinned with go.sum; vendored if needed
|
|
2. **Data Tampering**: All document versions SHA-256 hashed; optional Ed25519 signatures
|
|
3. **Unauthorized Access**: RBAC with principle of least privilege; content never served without auth check
|
|
4. **Session Hijacking**: Signed cookies with HttpOnly, Secure, SameSite=Strict; short expiry with refresh
|
|
5. **CSRF**: Double-submit cookie pattern for state-changing operations
|
|
6. **XSS**: Go html/template auto-escaping; strict CSP headers; no inline scripts except nonce-tagged
|
|
7. **DoS**: Rate limiting on auth endpoints; file upload size limits; query timeouts
|
|
|
|
### Content Security
|
|
|
|
- Attachment uploads: Magic number validation, extension whitelist, size limits
|
|
- Markdown rendering: Sanitized HTML output; no raw HTML injection
|
|
- File paths: Canonicalization prevents directory traversal
|
|
|
|
### Audit & Compliance
|
|
|
|
- Every data modification logged with user, timestamp, IP, and content hash
|
|
- Immutable history table — updates are inserts
|
|
- GDPR-compliant: full data export and deletion capability
|
|
|
|
---
|
|
|
|
## Performance Targets
|
|
|
|
| Metric | Target | Measurement |
|
|
| ------------------- | ------------------------- | -------------------------------- |
|
|
| Initial Page Load | <100ms | TTFB + First Contentful Paint |
|
|
| Time to Interactive | <200ms | Hydration complete |
|
|
| Search Query | <50ms | Client-side after initial sync |
|
|
| File Sync | <5s | From disk save to server persist |
|
|
| Bundle Size | <100KB | Gzipped JS + CSS |
|
|
| Concurrent Users | 1000 readers, 100 editors | Load tested |
|
|
|
|
---
|
|
|
|
## Monorepo Structure
|
|
|
|
```
|
|
md-hub-secure/
|
|
├── README.md
|
|
├── docker-compose.yml
|
|
├── Dockerfile
|
|
├── Makefile
|
|
├── docs/ # Project documentation
|
|
│ ├── project-plan.md # This file
|
|
│ ├── architecture-overview.md # System architecture
|
|
│ ├── adrs/ # Architecture Decision Records
|
|
│ ├── milestones/ # Detailed milestone plans
|
|
│ └── specs/ # Technical specifications
|
|
├── apps/
|
|
│ ├── server/ # Go HTTP application
|
|
│ │ ├── main.go
|
|
│ │ ├── internal/
|
|
│ │ │ ├── api/ # HTTP handlers
|
|
│ │ │ ├── auth/ # Authentication & authorization
|
|
│ │ │ ├── config/ # Configuration management
|
|
│ │ │ ├── db/ # Database models & migrations
|
|
│ │ │ ├── markdown/ # Markdown rendering pipeline
|
|
│ │ │ ├── search/ # Full-text search
|
|
│ │ │ ├── sync/ # SimpleSync protocol
|
|
│ │ │ ├── email/ # Postmark integration
|
|
│ │ │ └── fs/ # Content-addressed filesystem
|
|
│ │ └── web/static/ # Built frontend assets
|
|
│ └── web/ # Preact frontend application
|
|
│ ├── src/
|
|
│ │ ├── components/ # Reusable UI components
|
|
│ │ ├── pages/ # Route-level components
|
|
│ │ ├── lib/ # Utilities & API client
|
|
│ │ ├── stores/ # State management
|
|
│ │ └── styles/ # CSS custom properties & themes
|
|
│ ├── design-system.html # Browser-based design tool
|
|
│ └── index.html
|
|
└── packages/
|
|
└── protocol/ # Shared sync protocol spec
|
|
├── sync.proto # Protocol buffer definition
|
|
└── go/ # Go generated types
|
|
```
|
|
|
|
---
|
|
|
|
## Risk Register
|
|
|
|
| Risk | Likelihood | Impact | Mitigation |
|
|
| -------------------------------- | ---------- | ------ | ----------------------------------------------------------------------------------- |
|
|
| WebAuthn/passkey adoption issues | Medium | Medium | Password fallback always available; extensive browser testing |
|
|
| SQLite performance at scale | Low | High | libsql replication path; FTS5 for search; benchmark early |
|
|
| Markdown extension parser bugs | Medium | Medium | Fuzz testing; strict CommonMark base; gradual feature rollout |
|
|
| Email deliverability | Medium | Medium | Postmark reputation monitoring; SPF/DKIM setup; SMTP fallback |
|
|
| Frontend bundle bloat | Medium | Medium | Bundle analysis in CI; tree-shaking enforced; lazy loading |
|
|
| File sync conflicts in teams | High | Medium | Clear UX for conflict resolution; email notification; automatic merge when possible |
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. Review and approve this plan
|
|
2. Set up repository structure and CI pipeline
|
|
3. Begin Milestone 1: Foundation
|
|
4. Schedule weekly architecture review meetings during Milestone 2 (sync protocol)
|
|
|
|
---
|
|
|
|
## Glossary
|
|
|
|
- **ADR**: Architecture Decision Record
|
|
- **CRDT**: Conflict-free Replicated Data Type (not used, but considered)
|
|
- **CSRF**: Cross-Site Request Forgery
|
|
- **CSP**: Content Security Policy
|
|
- **FTS5**: SQLite Full-Text Search version 5
|
|
- **RBAC**: Role-Based Access Control
|
|
- **SSR**: Server-Side Rendering
|
|
- **TTFB**: Time to First Byte
|
|
- **WebAuthn**: Web Authentication API (passkeys)
|