A secure, self-destructing message service built with Go and HTMX
OnceRead allows you to send encrypted messages that can only be read once. Perfect for sharing sensitive information like passwords, API keys, or confidential messages. Once a message is accessed, it's automatically deleted from the database forever.
- AES-256-GCM Encryption - Military-grade authenticated encryption
- PBKDF2 Key Derivation - 100,000 iterations with SHA-256
- Cryptographically Secure Random - Salt and nonce generation
- Environment Variables - No hardcoded secrets
- Security Headers - XSS, clickjacking, and MIME-type protection
- Input Validation - Comprehensive sanitization and length limits
- Read Once Policy - Messages automatically delete after first access
- Atomic Operations - Race condition protection
- No Trace Left - Complete removal from database
- Zero-Password Mode - Send messages without passwords
- Password-Protected Mode - Add extra security layer
- Secure Password Handling - Never stored in plaintext
- Dark Theme UI - Beautiful gradient design
- HTMX Powered - Smooth, reactive user experience
- Mobile Responsive - Works on all devices
- One-Click Copy - Easy URL and message copying
- Tailwind CSS - Clean, modern styling
- Go Backend - Fast, concurrent, memory-safe
- Supabase Database - Scalable PostgreSQL backend
- Template System - Efficient server-side rendering
- Lightweight - Minimal dependencies
- Go 1.23+
- Supabase account (free tier available)
- Git
git clone https://github.com/rajsibajsi/message-encrypt.git
cd message-encrypt# Copy environment template
cp .env.example .env
# Edit .env with your Supabase credentials
SUPABASE_URL=your_supabase_project_url
SUPABASE_ANON_KEY=your_supabase_anon_key
PORT=8080Create a table in your Supabase database:
CREATE TABLE messages (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
message TEXT NOT NULL,
has_password BOOLEAN NOT NULL DEFAULT false,
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);
-- Enable Row Level Security (recommended)
ALTER TABLE messages ENABLE ROW LEVEL SECURITY;
-- Optional: Add auto-cleanup for old messages
CREATE OR REPLACE FUNCTION cleanup_old_messages()
RETURNS void AS $$
BEGIN
DELETE FROM messages WHERE created_at < NOW() - INTERVAL '7 days';
END;
$$ LANGUAGE plpgsql;# Install dependencies
go mod tidy
# Generate templates
go install github.com/a-h/templ/cmd/templ@latest
templ generate
# Build and run
go build -o server main.go
./serverOpen your browser to http://localhost:8080
Returns the main interface for creating encrypted messages.
{"message": "alive"}{"message": "ready"}Form Data:
message(required): The message to encrypt (max 10,000 chars)password(optional): Password for additional protection (max 1,000 chars)
Response: Returns a unique URL for accessing the message
- Without password: Message displayed immediately and deleted
- With password: Shows password prompt
Form Data:
message(required): Encrypted message datapassword(required): Password for decryption
Response: Decrypted message or error
All responses include:
X-Content-Type-Options: nosniffX-Frame-Options: DENYX-XSS-Protection: 1; mode=block
| Variable | Description | Default |
|---|---|---|
SUPABASE_URL |
Your Supabase project URL | Required |
SUPABASE_ANON_KEY |
Your Supabase anonymous key | Required |
PORT |
Server port | 8080 |
- Message limit: 10,000 characters
- Password limit: 1,000 characters
- PBKDF2 iterations: 100,000
- Encryption: AES-256-GCM
- Key size: 32 bytes
- Salt size: 16 bytes
βββ main.go # Entry point
βββ src/
β βββ message-encrypt/
β β βββ entities/
β β β βββ Message.go # Message entity
β β βββ providers/
β β β βββ MessageProvider.go # Database operations
β β βββ routes/
β β β βββ GetIndex.go # Homepage handler
β β β βββ GetMessage.go # Message retrieval
β β β βββ PostDecrypt.go # Decryption handler
β β β βββ PostStore.go # Message creation
β β βββ services/
β β βββ EncryptionService.go # Crypto operations
β βββ public/
β βββ components/
β β βββ header.templ # HTML head component
β β βββ span_with_copy.templ # Copy-to-clipboard component
β βββ views/
β βββ index.templ # Homepage template
β βββ message.templ # Message display template
βββ .env.example # Environment template
βββ README.md # This file
# Install dependencies
go mod tidy
# Generate Go files from templates
templ generate
# Build
go build -o onceread main.go
# Run
./onceread# Watch mode (requires air)
go install github.com/cosmtrek/air@latest
air
# Run tests
go test ./...
# Format code
go fmt ./...
# Vet code
go vet ./...FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY . .
RUN go mod tidy && go install github.com/a-h/templ/cmd/templ@latest
RUN templ generate && go build -o onceread main.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/onceread .
EXPOSE 8080
CMD ["./onceread"]SUPABASE_URL=https://your-project.supabase.co
SUPABASE_ANON_KEY=your-production-key
PORT=8080- Use HTTPS in production
- Set up proper CORS policies
- Configure rate limiting
- Monitor logs and metrics
- Regular security updates
- Database backups
- Algorithm: AES-256-GCM (Authenticated Encryption)
- Key Derivation: PBKDF2 with SHA-256, 100,000 iterations
- Random Generation: Cryptographically secure (
crypto/rand) - Salt: 16 bytes, unique per message
- Nonce: 12 bytes, unique per message
- Messages are encrypted before database storage
- Passwords are never stored (only used for key derivation)
- All database operations use parameterized queries
- Input validation prevents injection attacks
- Security headers protect against common web vulnerabilities
Protects Against:
- Database breaches (data is encrypted)
- Network interception (HTTPS + encryption)
- Unauthorized access (read-once policy)
- XSS and injection attacks (input sanitization)
Does NOT Protect Against:
- Compromised Supabase credentials
- Client-side malware
- Social engineering attacks
- Physical access to unlocked devices
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests if applicable
- Ensure all tests pass
- Submit a pull request
- Follow Go standard formatting (
go fmt) - Use meaningful variable names
- Add comments for complex logic
- Keep functions small and focused
This project is licensed under the MIT License - see the LICENSE file for details.
- Go - Backend language
- Templ - Type-safe HTML templates
- HTMX - Modern web interactions
- Tailwind CSS - Utility-first CSS
- Supabase - Backend-as-a-Service
- Bluemonday - HTML sanitization
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Message expiration settings
- File attachment support
- API rate limiting
- Message statistics
- Custom message URLs
- Bulk message operations
- Integration with password managers
Made with β€οΈ using Go and modern web technologies.