Skip to content

johnwmail/webpass

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

226 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

πŸ” WebPass

A web-based password manager with zero-knowledge architecture. All cryptography happens client-side in the browser using OpenPGP.js. The server stores only encrypted blobs β€” it never sees plaintext passwords or private keys.

CI Integration Tests License: MIT Go Version

✨ Features

  • Client-side encryption β€” PGP encryption/decryption in the browser with OpenPGP.js
  • Zero-knowledge architecture β€” Server never sees plaintext passwords or private keys
  • Multi-user support β€” Each user identified by their PGP key fingerprint
  • Two-factor authentication β€” Optional TOTP (2FA) for server access
  • Import/Export β€” Compatible with standard .password-store directory format (pass CLI compatible)
  • Password generator β€” Configurable random password generation
  • Session management β€” 5-minute JWT sessions with automatic expiry
  • Git sync β€” Backup and sync encrypted entries to any Git repository (GitHub, GitLab, Gitea)
  • TOTP codes β€” Store and generate TOTP codes using otpauth:// URI format (pass-otp compatible)
  • Theme toggle β€” Auto-switching light/dark themes based on time of day (8AM-10PM)
  • Account management β€” Clear local data or permanently delete account with passphrase confirmation
  • Auto-hide sensitive content β€” Password and notes auto-hide after 15 seconds with countdown timer
  • PGP key auto-lock β€” Decrypted PGP key auto-locks after 30s of inactivity
  • Rate limiting β€” Sliding window rate limiting on authentication endpoints (5 attempts / 15 min default)
  • Registration protection β€” TOTP-based registration codes to prevent unauthorized account creation

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Browser (SPA)                      β”‚
β”‚  + OpenPGP.js + IndexedDB           β”‚
β”‚  + PGP encrypt/decrypt              β”‚
β”‚  + TOTP code generation             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ HTTPS + CORS + JWT
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Go API Server (SQLite backend)     β”‚
β”‚  + JWT Auth + bcrypt + TOTP         β”‚
β”‚  + Rate limiting                    β”‚
β”‚  + Git sync (go-git)                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
               β”‚ HTTPS (PAT) / SSH (key)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Remote Git Repo (optional)         β”‚
β”‚  └── *.gpg (encrypted blobs)        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ› οΈ Tech Stack

Layer Technology
Frontend TypeScript + Preact + Vite
Crypto OpenPGP.js + Web Crypto API (PBKDF2)
Backend Go 1.26 + SQLite (pure-Go, no CGO)
Git go-git (pure Go, no Git CLI needed)
Auth bcrypt + JWT (5-min) + TOTP (2FA)
Testing Playwright (81 E2E tests) + Vitest
Deploy Docker (single container)

πŸš€ Quick Start

Prerequisites

  • Go 1.26+
  • Node.js 24+
  • npm
  • Docker (for container deployment)

Build

# Build backend
go build -o webpass-server ./cmd/srv

# Build frontend (optional, for static serving)
cd frontend && npm run build

Run

# Set environment variables
export JWT_SECRET=$(openssl rand -hex 32)
export DB_PATH=./db.sqlite3

# Run server (development)
go run ./cmd/srv

# Or run the compiled binary
./webpass-server

Server listens on :8080 by default.

Deployment

Docker

# Build image
docker build -t webpass:latest .

# Run container
docker run -d \
  --name webpass \
  -p 8080:8080 \
  -v webpass-data:/data \
  -e JWT_SECRET="$(openssl rand -hex 32)" \
  --read-only \
  --security-opt no-new-privileges:true \
  webpass:latest

Docker Compose

# Configure environment
cp .env.example .env
# Edit .env and set JWT_SECRET

# Start
docker compose up -d

Database Migrations & Upgrades

Migrations are applied automatically on startup via embedded SQL files in db/migrations/. They are numbered (NNN-name.sql) and tracked in a migrations table β€” each runs exactly once.

Forward upgrade βœ… β€” Fully supported. All migrations only add columns/tables, never remove or rename. Upgrading from older versions (e.g. v0.4.6) to latest is safe.

Rollback ❌ β€” Not supported. Because sqlc generates SELECT * queries, the old binary will fail to scan rows if new columns were added. To downgrade, restore both the binary and the database from backup.

Security Hardening

The container runs with:

  • Non-root user (UID/GID 8080)
  • Read-only filesystem (--read-only)
  • No privilege escalation (--security-opt no-new-privileges:true)
  • Writable path only /data (SQLite + git repos)

Testing

Unit Tests

# Backend tests
go test ./...

# Frontend unit tests
cd frontend && npm test

E2E Tests (Playwright)

81 browser-based integration tests across 5 phases:

# Run comprehensive test suite
./frontend/playwright-e2e-test.sh

# Or use npx directly
cd frontend && npx playwright test

# Run with interactive UI
npx playwright test --ui

# Run with visible browser
npx playwright test --headed

# View HTML report
npx playwright show-report

Test Coverage:

  • Phase 1: Rate limit tests (3 tests)
  • Phase 2: All tests in Protected mode (62 tests)
  • Phase 3: Registration tests in Open mode (6 tests)
  • Phase 4: Registration tests in Protected mode (8 tests)
  • Phase 5: Registration tests in Disabled mode (2 tests)

Git Sync Test Configuration

Git sync E2E tests require a real Git repository. Set credentials via:

# Option 1: .env file (gitignored)
WEBPASS_REPO_URL="https://gitea.example.com/user/password-store.git"
WEBPASS_REPO_PAT="your-personal-access-token"

# Option 2: Environment variables
export WEBPASS_REPO_URL="..."
export WEBPASS_REPO_PAT="..."

# Option 3: GitHub Secrets (CI/CD)
# Add WEBPASS_REPO_URL and WEBPASS_REPO_PAT to repository secrets

πŸ“‘ API Endpoints

All endpoints require JWT authentication except where noted.

Authentication & User Management

Method Path Auth Description
POST /api No Create user (first-time setup)
GET /api/{fingerprint} JWT Get user info
POST /api/{fingerprint}/login No Login β†’ returns JWT or 2FA challenge
POST /api/{fingerprint}/login/2fa No Complete 2FA login
DELETE /api/{fingerprint}/account JWT Delete account permanently
POST /api/{fingerprint}/password JWT Change password

Registration (TOTP-based)

Method Path Auth Description
GET /api/registration/mode No Get registration mode (open/protected/disabled)
POST /api/registration/validate No Validate registration TOTP code

TOTP Setup

Method Path Auth Description
POST /api/{fingerprint}/totp/setup JWT Begin TOTP 2FA setup
POST /api/{fingerprint}/totp/confirm JWT Confirm TOTP 2FA setup

Entries (Password Store)

Method Path Auth Description
GET /api/{fingerprint}/entries JWT List all entry paths
GET /api/{fingerprint}/entries/* JWT Download encrypted blob
PUT /api/{fingerprint}/entries/* JWT Upload encrypted blob
DELETE /api/{fingerprint}/entries/* JWT Delete entry
POST /api/{fingerprint}/entries/move JWT Rename/move entry

Import/Export

Method Path Auth Description
GET /api/{fingerprint}/export JWT Export all entries as .tar.gz
POST /api/{fingerprint}/import JWT Import password store (JSON or .tar.gz)

Git Sync

Method Path Auth Description
GET /api/{fingerprint}/git/status JWT Get git sync status
GET /api/{fingerprint}/git/config JWT Get git configuration
POST /api/{fingerprint}/git/config JWT Configure git sync
POST /api/{fingerprint}/git/session JWT Set git token for current session
POST /api/{fingerprint}/git/push JWT Manual push to remote (force overwrite)
POST /api/{fingerprint}/git/pull JWT Manual pull from remote (fresh clone)
POST /api/{fingerprint}/git/toggle-sync JWT Enable/disable git sync
GET /api/{fingerprint}/git/log JWT Get sync operation history (last 50)

System

Method Path Auth Description
GET /api/health No Health check
GET /api/version No Get server version

πŸ”’ Security Model

  • Private keys never leave the browser β€” Stored AES-wrapped in IndexedDB
  • Server stores only PGP-encrypted blobs β€” Database leak reveals nothing
  • Password validates locally first β€” Wrong password fails before network call
  • 5-minute sessions β€” JWT expiry enforced server-side
  • PGP key auto-lock β€” Private key automatically locked after 30s of inactivity (hardcoded in frontend/src/lib/session.ts)
  • CORS locked to specific origins via CORS_ORIGINS env var
  • All traffic over HTTPS required in production
  • Rate limiting on authentication endpoints (sliding window, 5 attempts / 15 min default)
  • Registration protection with TOTP-based codes (optional, configurable)

Reporting Vulnerabilities

Please do not open public issues for security vulnerabilities.

  1. Email: Send details to the maintainers privately
  2. GitHub: Use private vulnerability reporting

Response Timeline:

  • Acknowledgment: Within 48 hours
  • Initial Assessment: Within 1 week
  • Fix Timeline: Depends on severity (Critical: 24-72h, High: 1-2 weeks, Medium: 2-4 weeks)

βš™οΈ Environment Variables

See .env.example for all available options with detailed comments.

Variable Required Description
JWT_SECRET Yes 32-byte hex string for JWT signing
DB_PATH No Path to SQLite database (default: /data/db/db.sqlite3)
STATIC_DIR No Path to frontend dist/ directory
CORS_ORIGINS No Comma-separated allowed origins
PORT No HTTP listen port (default: 8080)
GIT_REPO_ROOT No Git repos directory (default: /data/git-repos)
SESSION_HARDLIMIT_MINUTES No JWT hard limit (max session time) in minutes (default: 30, range: 5-480)
SESSION_SOFTLIMIT_MINUTES No JWT soft limit (browser close detection) in minutes (default: 5, range: 1-60)
DISABLE_FRONTEND No Disable frontend (1 or true)
BCRYPT_COST No Password hashing cost factor (default: 12, range: 10-15)
RATE_LIMIT_ATTEMPTS No Max requests per window (default: 5)
RATE_LIMIT_WINDOW_MINUTES No Time window in minutes (default: 15)

Registration Configuration

Variable Default Description
REGISTRATION_ENABLED false Enable registration (1 or true)
REGISTRATION_TOTP_SECRET (empty) Base32 TOTP secret (required for protected mode)
REGISTRATION_TOTP_PERIOD 3600 Code validity period in seconds (15-86400)
REGISTRATION_TOTP_ALGO SHA1 Hash algorithm (SHA1/SHA256/SHA512)
REGISTRATION_CODE_FILE /data/registration_code.txt Path to write current code

Registration Modes:

REGISTRATION_ENABLED REGISTRATION_TOTP_SECRET Mode
false (any) Disabled β€” No registration allowed
true (not set) Open β€” No code required
true (set) Protected β€” 6-digit TOTP code required

πŸ”„ Git Sync

One-way overwrite sync with fresh clone/export:

  • Pull: Remote β†’ Local (clone remote, replace local DB)
  • Push: Local β†’ Remote (export local DB, force-push to remote)
  • No merge conflicts β€” Last write wins
  • Fresh operations β€” Local git repo is temporary, cleaned before/after each operation
  • Per-user configuration β€” Each user has their own repo URL
  • Two authentication methods:
    • HTTPS β€” PGP-encrypted Personal Access Token
    • SSH β€” PGP-encrypted SSH private key with TOFU host key verification

Git Repository Structure

repo-root/
β”œβ”€β”€ .git/
β”œβ”€β”€ email.gpg
β”œβ”€β”€ work/
β”‚   └── database.gpg
└── social/
    └── twitter.gpg
  • All files are .gpg encrypted blobs (client-side PGP encryption)
  • Files at repo root (no .password-store/ subdirectory)
  • Compatible with standard pass CLI after cloning

Branch Detection

Default branch auto-detection (branch = "HEAD"):

  1. Read remote HEAD symbolic reference
  2. If HEAD not found β†’ try main
  3. If main not found β†’ try master

Theme System

Auto-switching theme system with manual override:

Theme Description
Ocean Dark blue professional theme (default for night)
Daylight Clean white/blue light theme (default for day)

Auto mode (default):

  • 8:00 AM - 10:00 PM β†’ Daylight theme
  • 10:00 PM - 8:00 AM β†’ Ocean theme

Manual override: Click theme toggle button to cycle: πŸ”„ Auto β†’ πŸŒ™ Ocean β†’ β˜€οΈ Daylight β†’ Auto

Preference saved to localStorage and persists across sessions.

πŸ“ Project Structure

.
β”œβ”€β”€ .github/workflows/   # CI/CD pipelines
β”œβ”€β”€ cmd/srv/            # Main binary entrypoint
── srv/                # HTTP server + handlers
β”œβ”€β”€ db/                 # Database migrations + sqlc queries
β”œβ”€β”€ frontend/           # Preact + TypeScript SPA
β”‚   β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ index.html
β”‚   └── package.json
── Dockerfile
β”œβ”€β”€ docker-compose.yml
└── .github/            # GitHub Actions workflows

🀝 Contributing

Contributions are welcome! Please read CONTRIBUTING.md for guidelines and AGENTS.md for the development guide.

Quick Start for Contributors

# Clone repository
git clone https://github.com/johnwmail/webpass.git
cd webpass

# Backend
go mod download
go test ./...

# Frontend
cd frontend
npm install
npm run dev

Testing Requirements

  • Backend: go test ./... must pass
  • Frontend unit: npm test must pass
  • E2E tests: ./frontend/playwright-e2e-test.sh must pass (81 tests)
  • Type check: npm run typecheck must pass

Code Standards

Go:

  • Follow Effective Go
  • Use gofmt or goimports
  • Add tests for new packages

TypeScript:

  • Use TypeScript for all new code
  • Follow existing code style
  • Add types for function signatures

General:

  • Write self-documenting code
  • Keep PRs under 400 lines when possible
  • Update tests with code changes

Security Considerations

Never commit:

  • Passwords or secrets
  • API keys or tokens
  • Private encryption keys
  • Production database files

πŸ“„ License

MIT License β€” see LICENSE for details.

πŸ™ Acknowledgments

About

πŸ” Zero-knowledge web password manager with client-side PGP encryption. Docker-ready, Git sync compatible with pass.

Resources

License

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors