✨ Modern Self-Hosted Credential Management with Zero-Knowledge Encryption ✨
Dream it, Pixel it - Made with ❤️ by Pink Pixel
- 🎯 Project Purpose
- 🏗️ Architecture Overview
- 🔒 Security Implementation
- 🛠️ Technology Stack
- 📁 Project Structure
- 🗄️ Database Schema
- 🎨 User Interface
- ⚡ Performance Features
- 📱 Progressive Web App
- 🚀 Deployment & Distribution
- 🧪 Testing Strategy
- 📊 Current Status
- 🔮 Future Roadmap
Keyper is a modern, self-hosted credential management application designed to provide complete control over sensitive data while maintaining enterprise-grade security. The project addresses the growing need for secure credential storage with a zero-knowledge architecture that ensures even the database administrator cannot access user secrets.
- 🔒 Zero-Knowledge Security: All encryption happens client-side
- 🏠 Self-Hosted Control: Complete data ownership and privacy
- 👤 Multi-User Support: Self-service registration, secure user switching, and isolated per-user vaults
- 📱 Modern Experience: Progressive Web App with native-like features
- 📄 Secure Document Handling: Encrypted document credential storage with metadata-aware detail UX
- ⚡ High Performance: Optimized loading and runtime performance
- 🎨 Beautiful UI: Glassmorphism design with accessibility in mind
graph TB
subgraph "Client (Browser / Electron)"
UI[React App]
Crypto[Crypto Layer]
PWA[Service Worker]
end
subgraph "Application Server"
CLI[Node.js CLI]
Vite[Vite Server]
end
subgraph "Database Layer"
Router{DB Provider Router}
Supabase[Supabase]
SQLite[SQLite / sql.js]
PG[(PostgreSQL)]
IDB[(IndexedDB)]
RLS[Row Level Security]
end
UI --> Crypto
Crypto --> Router
Router -->|Supabase mode| Supabase
Router -->|SQLite mode| SQLite
CLI --> Vite
Vite --> UI
Supabase --> PG
PG --> RLS
SQLite --> IDB
- Zero-Knowledge Architecture: Encryption/decryption occurs exclusively in the browser
- Stateless Backend: Database stores only encrypted blobs and metadata
- User Isolation: Multi-tenant support with strict data separation
- Progressive Enhancement: Works offline with cached data
- Security First: Multiple layers of protection and validation
| Component | Implementation | Purpose |
|---|---|---|
| Key Derivation | Argon2id (preferred) / PBKDF2 (fallback) | Password-to-key transformation |
| Encryption | AES-256-GCM | Authenticated symmetric encryption |
| Salt Generation | Crypto.getRandomValues() | Unique salt per credential |
| IV Generation | Crypto.getRandomValues() | Unique initialization vector |
- 🔐 End-to-End Encryption: All sensitive data encrypted before database storage
- 🔑 Master Passphrase Protection: Single passphrase controls vault access
- ⏰ Auto-Lock: 15-minute inactivity timeout with activity detection
- 🛡️ Row Level Security: Database-level access control
- 👤 Per-User Vault Isolation: Independent vault metadata and encrypted payloads per
user_id - 🚫 No Admin Backdoors: Registration and user switching never bypass passphrase verification
- 🔒 Content Security Policy: Browser-level protection against XSS
- 🚫 No Telemetry: Zero tracking or data collection
sequenceDiagram
participant U as User
participant C as Client App
participant D as Database
U->>C: Enter credential + passphrase
C->>C: Generate salt & IV
C->>C: Derive key (Argon2id/PBKDF2)
C->>C: Encrypt with AES-256-GCM
C->>D: Store encrypted blob
D->>C: Confirm storage
C->>U: Success confirmation
| Technology | Version | Purpose |
|---|---|---|
| React | 19.1.1 | Modern UI framework with concurrent features |
| TypeScript | 5.8.3 | Type safety and developer experience |
| Vite | 7.0.6 | Lightning-fast build tool and dev server |
| Tailwind CSS | 3.4.11 | Utility-first styling framework |
| Radix UI | Various | Unstyled, accessible UI primitives |
| shadcn/ui | Latest | Pre-built component library |
| Electron | 33.3.0 | Cross-platform desktop app runtime |
| Technology | Version | Purpose |
|---|---|---|
| Node.js | 18+ | Runtime for CLI and build tools |
| Supabase | 2.53.0 | Backend-as-a-Service platform (cloud mode) |
| PostgreSQL | 15+ | Relational database with advanced features |
| sql.js | 1.12.0 | SQLite compiled to WebAssembly (local mode) |
| Docker / nginx | 1.27+ | Containerised SPA serving |
| Library | Purpose |
|---|---|
| argon2-browser | Memory-hard key derivation |
| Web Crypto API | Browser-native cryptographic operations |
| Zod | Runtime type validation |
| Tool | Purpose |
|---|---|
| ESLint | Code linting and quality |
| Vitest | Unit and integration testing |
| Wrangler | Cloudflare deployment |
keyper/
├── 📁 bin/ # CLI executable
│ └── keyper.js # Node.js server launcher
├── 📁 electron/ # Electron main-process source
│ ├── main.ts # app:// protocol, security headers
│ ├── preload.ts # context-bridge (window.keyperElectron)
│ └── tsconfig.json # CommonJS TypeScript config
├── 📁 electron-dist/ # Compiled Electron output (git-ignored)
├── 📁 dist-electron/ # electron-builder output — installers (git-ignored)
├── 📄 electron-builder.yml # Packager config (AppImage, deb, DMG)
├── 📄 Dockerfile # Multi-stage Node→nginx image
├── 📄 nginx.conf # SPA routing, WASM MIME, security headers
├── 📄 docker-compose.yml # Single-command stack launch
├── 📁 docs/ # Documentation
├── 📁 public/ # Static assets
│ ├── logo.png # Application logo
│ ├── favicon.ico # Browser favicon
│ └── manifest.json # PWA manifest
├── 📁 src/ # Source code
│ ├── 📁 components/ # React components
│ │ ├── 📁 dashboard/ # Dashboard components
│ │ ├── 📁 ui/ # UI primitives
│ │ ├── PassphraseGate.tsx # Vault unlock component
│ │ ├── Settings.tsx # Configuration interface
│ │ └── SelfHostedDashboard.tsx # Main app component
│ ├── 📁 crypto/ # Cryptography layer
│ │ ├── crypto.ts # Core encryption functions
│ │ ├── encoding.ts # Data encoding utilities
│ │ └── types.ts # Crypto type definitions
│ ├── 📁 hooks/ # React hooks
│ ├── 📁 integrations/ # External service integrations
│ │ ├── 📁 supabase/ # Supabase client + provider router
│ │ └── 📁 database/ # SQLite / sql.js client (local mode)
│ ├── 📁 lib/ # Utility libraries
│ ├── 📁 pages/ # Route components
│ ├── 📁 security/ # Security utilities
│ ├── 📁 services/ # Business logic
│ └── 📁 types/ # TypeScript definitions
├── 📁 supabase/ # Database configuration
├── 📄 supabase-setup.sql # Database initialization script
├── 📄 package.json # Project configuration
├── 📄 vite.config.ts # Build configuration
├── 📄 tailwind.config.ts # Styling configuration
├── 📄 README.md # User documentation
├── 📄 SELF-HOSTING.md # Deployment guide
├── 📄 CONTRIBUTING.md # Contributor guide
└── 📄 LICENSE # Apache 2.0 license
Primary table for encrypted credential storage:
CREATE TABLE credentials (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL DEFAULT 'self-hosted-user',
title TEXT NOT NULL,
description TEXT,
credential_type TEXT NOT NULL CHECK (credential_type IN ('api_key', 'login', 'secret', 'token', 'certificate', 'document', 'misc')),
priority TEXT NOT NULL DEFAULT 'medium' CHECK (priority IN ('low', 'medium', 'high', 'critical')),
username TEXT,
url TEXT,
tags TEXT[] DEFAULT '{}',
category TEXT,
notes TEXT,
expires_at TIMESTAMP WITH TIME ZONE,
last_accessed TIMESTAMP WITH TIME ZONE,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
-- Encrypted storage
secret_blob JSONB NOT NULL,
encrypted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);Sensitive values are encrypted into secret_blob and are type-scoped in active add/edit flows:
login:passwordapi_key:api_keysecret:secret_valuetoken:token_valuecertificate:certificate_datadocument:document_name,document_mime_type,document_content_base64,document_size_bytesmisc:misc_value
This prevents unrelated secret fields from leaking across credential types in detail views.
Secure key management configuration with dual authentication systems:
CREATE TABLE vault_config (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL DEFAULT 'self-hosted-user',
-- New bcrypt-only system for simplified security
raw_dek BYTEA, -- Plain DEK for new users
bcrypt_hash TEXT, -- Bcrypt hash of master passphrase
-- Legacy wrapped DEK system (backwards compatibility)
wrapped_dek JSONB, -- Encrypted DEK for existing users
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(user_id)
);```
#### **categories**
Organization and categorization system:
```sql
CREATE TABLE categories (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id TEXT NOT NULL DEFAULT 'self-hosted-user',
name TEXT NOT NULL,
color TEXT DEFAULT '#6366f1',
icon TEXT DEFAULT 'folder',
description TEXT,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
UNIQUE(user_id, name)
);- ✅ Row Level Security (RLS) enabled on all tables
- ✅ Comprehensive policies for multi-user isolation
- ✅ Performance indexes on frequently queried columns
- ✅ Automatic triggers for timestamp maintenance
- ✅ Helper functions for statistics and verification
- Theme: Dark-first with glassmorphism aesthetics
- Colors: Cyan-focused palette with semantic color coding
- Typography: Clean, readable fonts with proper hierarchy
- Layout: Responsive grid system with mobile-first approach
- Accessibility: ARIA labels, keyboard navigation, screen reader support
| Component | Purpose | Features |
|---|---|---|
| PassphraseGate | Vault security checkpoint | Unlock flow + create-new-user entrypoint |
| UserRegistration | New account onboarding | Username validation + passphrase confirmation |
| UserSwitcher | Multi-user controls | Registered-user list + secure context switching |
| DashboardSettings | Settings shell | User Management tab + security messaging |
| DashboardHeader | Navigation and branding | Search, user profile, actions |
| CredentialsGrid | Main credential display | Filtering, sorting, infinite scroll |
| CredentialModal | Detailed credential view | Reveal, copy, edit, delete actions |
| SearchAndFilters | Advanced filtering system | Real-time search, tag filtering |
- Mobile: Touch-optimized interfaces, swipe gestures
- Tablet: Adaptive layouts, contextual toolbars
- Desktop: Full feature set, keyboard shortcuts
- Large Screens: Multi-column layouts, enhanced workflows
- Code Splitting: Automatic route and component chunking
- Tree Shaking: Dead code elimination
- Asset Optimization: Image compression and format selection
- Bundle Analysis: Chunk size monitoring and optimization
- Lazy Loading: Deferred component loading
- Memoization: React.memo and useMemo optimization
- Virtual Scrolling: Efficient large list rendering
- Caching: Service Worker and HTTP caching strategies
- Argon2 Optimization: Memory and CPU tuning
- PBKDF2 Fallback: Compatibility for older devices
- Streaming Crypto: Efficient handling of large datasets
- Worker Threads: Non-blocking encryption operations
- ✅ Installable: Add to home screen on all platforms
- ✅ Offline Support: Core functionality without internet
- ✅ Push Notifications: Security alerts and reminders
- ✅ Background Sync: Data synchronization when online
- ✅ App Shell: Fast loading with cached resources
// Workbox configuration
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg}'],
runtimeCaching: [
{
urlPattern: /^https:\/\/.*\.supabase\.co\/.*/i,
handler: 'NetworkFirst',
options: {
cacheName: 'supabase-cache',
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 24 // 24 hours
}
}
}
]
}- NPM Package: Global installation via
npm install -g @pinkpixel/keyper - Direct Download: Published desktop installers where available for the current release
- Docker Image: Containerized deployment (nginx-based, production-ready)
- Cloud Deployment: Cloudflare Pages, Netlify, Vercel support
- Electron Desktop App: Native desktop packaging support, with published Windows and Linux installers for the current release
# Global installation
npm install -g @pinkpixel/keyper
# Quick start
keyper # Default port 4173
keyper --port 3000 # Custom port
keyper --help # Show help# Clone and start with Docker Compose (default port 8080)
git clone https://github.com/pinkpixel-dev/keyper.git
cd keyper
docker compose up -d
# Custom port
HOST_PORT=3030 docker compose up -d
# Or run directly
docker build -t keyper .
docker run -d -p 8080:80 --name keyper --restart unless-stopped keyperThe container serves the compiled Vite/React SPA on port 80 internally. No Node.js or environment variables required on the host — all configuration (Supabase credentials or SQLite provider selection) is entered in-app and stored in browser localStorage.
Current published installer links are available for Windows and Linux builds. Electron packaging also supports additional targets from source:
| Platform | Format | Download |
|---|---|---|
| Windows | NSIS installer | KeyperSetup.v1.1.1.exe |
| Linux | AppImage | Keyper-1.1.1.AppImage |
| Linux | .deb (x86_64) |
keyper_1.1.1_amd64.deb |
| Linux | .deb (ARM64) |
keyper_1.1.1_arm64.deb |
| Platform | Format | Architecture |
|---|---|---|
| Windows | NSIS | x64 |
| Linux | AppImage | x86_64, ARM64 |
| Linux | .deb |
x86_64, ARM64 |
To build the currently documented desktop installers from source:
npm run electron:build:linux # AppImage + deb
npm run electron:build:win # NSIS / Windows build tooling required- Local Network: Internal company deployment
- Cloud VPS: DigitalOcean, AWS, Google Cloud
- Edge Networks: Cloudflare Workers/Pages
- Container Platforms: Docker, Kubernetes
- GitHub Actions: Automated testing on PRs
- Build Verification: Cross-platform compatibility
- Security Scanning: Dependency vulnerability checks
- Performance Monitoring: Bundle size tracking
- Current Version: 1.1.1
- Release Date: March 2026
- Last Updated: March 2026
- Status: Stable Production Release 🟢
- License: Apache 2.0 | User Interface | ✅ Complete | Full responsive design | | Database Layer | ✅ Complete | Supabase + SQLite dual-provider | | SQLite Support | ✅ Complete | Local-first, zero-config (browser/PWA + Electron) | | PWA Features | ✅ Complete | Full offline support | | CLI Tools | ✅ Complete | Multi-platform support | | Docker Build | ✅ Complete | nginx-based container | | Desktop App | ✅ Complete | Electron v33, all platforms | | Documentation | ✅ Complete | Comprehensive guides |
- Mobile Biometrics: Planned for a future release
- Team Sharing: Enterprise feature roadmap
- API Access: External integration support
- Audit Logging: Enhanced security tracking
- 🔐 Biometric Authentication: Touch/Face ID support
- 📊 Enhanced Analytics: Usage patterns and insights
- 🔄 Automatic Backups: Encrypted cloud backup options
- 🚀 Performance Optimizations: Further speed improvements
- 👥 Team Collaboration: Secure credential sharing
- 🔗 External Integrations: API access and webhooks
- 📱 Native Mobile Apps: iOS and Android applications
- 🛡️ Advanced Security: Hardware key support
- 🏢 Enterprise Features: SSO, LDAP integration
- 🔍 Advanced Audit: Comprehensive logging and compliance
- 🌐 Multi-Instance: Federated deployment support
- 🤖 AI-Powered: Smart categorization and security insights
Keyper is an open-source project welcoming contributions from developers worldwide. Please refer to CONTRIBUTING.md for detailed guidelines.
git clone https://github.com/pinkpixel-dev/keyper.git
cd keyper
npm install
npm run dev- 🐛 Bug Reports: Help improve stability
- ✨ Feature Requests: Suggest new capabilities
- 📝 Documentation: Enhance user guides
- 🔐 Security: Cryptographic improvements
- 🎨 Design: UI/UX enhancements
- 🌐 Website: pinkpixel.dev
- 📧 Email: admin@pinkpixel.dev
- 💬 Discord: @sizzlebop
- 🐛 Issues: GitHub Issues
- ☕ Support: Buy me a coffee
⭐ Star this project if it helps secure your digital life! ⭐
Made with ❤️ by Pink Pixel - Dream it, Pixel it ✨