Zero-knowledge .env secret sharing for developers. Secrets are encrypted in your browser before they ever leave your machine β the server stores only ciphertext.
When collaborating on a codebase, sharing .env files over WhatsApp, Discord, or email is common β and dangerous. Those messages live in logs, backups, and screenshots forever.
SecretTunnel fixes this. Paste your secrets β get a one-time link β share it β link self-destructs after first view.
Browser (yours) Server Browser (theirs)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Paste .env content
β
AES-256-GCM encrypt
(Web Crypto API)
β
POST /api/secrets ββββββββΊ Store ciphertext in Redis βββ GET /api/secrets/:token
(with TTL + burn flag) β
β Decrypt in browser
Receive token + key βββββββ Return token β
β Plaintext shown once
Share link with key β
(key never hits server) Redis entry deleted
The encryption key lives only in the URL fragment (#key=...). Fragments are never sent to the server. The server is provably blind to your plaintext.
- π Client-side AES-256-GCM encryption via Web Crypto API
- π₯ Burn after read β secret deleted from Redis on first view
- β±οΈ Configurable TTL β from minutes to weeks
- π Optional password protection β adds a second decryption layer
- π Web UI β intuitive interface for sharing secrets
- π» CLI tool β
secrettnlcommand-line interface for automation - π Audit logging β track who viewed your secrets
- π Webhook notifications β get notified when secrets are accessed
- π Versioned secrets β manage multiple versions of secret groups
- π€ User authentication β GitHub OAuth and credential-based auth
- π¨ Modern UI β built with shadcn/ui and Tailwind CSS
- Turbo β Monorepo management
- Next.js 16 β React framework with API routes
- TypeScript β Type-safe development
- React 19 β UI library
- Tailwind CSS 4 β Utility-first CSS
- shadcn/ui β Component library
- React Hook Form β Form state management
- Zod β Schema validation
- Sonner β Toast notifications
- Next.js API Routes β Serverless backend
- Prisma β ORM for PostgreSQL
- PostgreSQL β Main database
- @prisma/adapter-pg β Prisma PostgreSQL adapter
- NextAuth.js β Authentication library
- GitHub OAuth β Social login
- Credential-based auth β Email/password authentication
- Password hashing β scrypt with salt for secure storage
- @upstash/redis β Serverless Redis for caching & TTL
- @upstash/qstash β Messaging queue for webhook delivery
- Axios β HTTP client
- Web Crypto API β Browser-native encryption
secrettunnel/
βββ apps/ # Applications
β βββ cli/ # Command-line interface
β β βββ src/
β β β βββ index.ts # CLI entry point
β β β βββ push.ts # Push (create secret) command
β β β βββ pull.ts # Pull (read secret) command
β β β βββ config.ts # Configuration
β β β βββ type.ts # TypeScript types
β β β βββ utils.ts # Shared utilities
β β βββ package.json
β β βββ tsconfig.json
β β βββ tsup.config.ts
β β
β βββ web/ # Next.js web application
β βββ src/
β β βββ app/ # App router (Next.js)
β β β βββ api/ # API routes
β β β β βββ audit/ # Audit log endpoint
β β β β βββ auth/ # NextAuth.js routes
β β β β βββ secrets/ # Secret CRUD endpoints
β β β β βββ test/ # Test endpoint
β β β β βββ versioned-secrets/ # Versioned secrets API
β β β β βββ webhooks/ # Webhook delivery
β β β βββ dashboard/ # Dashboard page
β β β βββ signin/ # Sign-in page
β β β βββ signup/ # Sign-up page
β β β βββ s/ # Public secret view page
β β β βββ vs/ # Versioned secrets view
β β βββ components/ # React components
β β β βββ auth/ # Auth components (forms, buttons)
β β β βββ ui/ # shadcn/ui components
β β β βββ AppHeader.tsx # Navigation header
β β β βββ SecretForm.tsx # Secret creation form
β β β βββ SecretViewer.tsx
β β β βββ AuditTable.tsx # Audit log display
β β β βββ VersionedSecretsSection.tsx
β β βββ lib/ # Server/shared utilities
β β β βββ auth.ts # NextAuth configuration
β β β βββ prisma.ts # Prisma client
β β β βββ password.ts # Password hashing
β β β βββ redis.ts # Redis client
β β β βββ rate-limit.ts # Rate limiting
β β β βββ schema.ts # Zod validation schemas
β β β βββ user-store.ts # User data management
β β β βββ utils.ts # Utilities
β β β βββ webhook-url.ts # Webhook URL handling
β β βββ types/ # TypeScript types
β β β βββ next-auth.d.ts # NextAuth type extensions
β β βββ proxy.ts # Request proxy
β β βββ globals.css # Global styles
β βββ prisma/ # Database schema
β β βββ schema.prisma # Prisma schema
β β βββ migrations/ # Database migrations
β βββ public/ # Static assets
β βββ package.json
β βββ tsconfig.json
β βββ next.config.ts
β βββ postcss.config.mjs
β βββ tailwind.config.ts
β βββ eslint.config.js
β
βββ packages/ # Shared packages
β βββ encryption/ # Encryption utilities
β β βββ src/
β β β βββ crypto.ts # Crypto functions
β β β βββ index.ts # Export
β β βββ package.json
β βββ eslint-config/ # Shared ESLint configurations
β β βββ base.js
β β βββ next.js
β β βββ react-internal.js
β βββ typescript-config/ # Shared TypeScript configurations
β βββ base.json
β βββ nextjs.json
β βββ react-library.json
β
βββ package.json # Root package.json
βββ turbo.json # Turbo configuration
βββ README.md # This file
SecretTunnel uses PostgreSQL with Prisma ORM. Key models:
- Stores user account information
- Fields:
id,name,email,profilePhoto,emailVerified,createdAt,updatedAt - Relations: Has many
Accounts
- Oauth/credential provider accounts linked to users
- Fields:
id,userId,provider,providerAccountId,access_token,refresh_token,expires_at,password_hash, etc. - Supports GitHub OAuth and credential-based auth
- Relations: Belongs to
User
- Groups of versioned secrets (e.g., "production .env")
- Fields:
id,userId,name,createdAt - Relations: Has many
SecretVersions
- Individual versions of secrets within a group
- Fields:
id,groupId,versionNumber,ciphertext,iv,createdAt - Encrypted content stored as ciphertext + IV
- Relations: Belongs to
SecretGroup
- Node.js β₯ 18
- Bun β₯ 1.2.23 (or npm/yarn as fallback)
- PostgreSQL database (or Docker PostgreSQL)
- Optional: Redis/Upstash for session/TTL
- Optional: GitHub OAuth credentials for authentication
-
Clone the repository
git clone https://github.com/yourusername/secrettunnel.git cd secrettunnel -
Install dependencies
bun install
-
Set up environment variables
Create a
.env.localfile inapps/web/:# Database DATABASE_URL=postgresql://user:password@localhost:5432/secrettunnel # NextAuth NEXTAUTH_URL=http://localhost:3000 NEXTAUTH_SECRET=your-secret-key-here # GitHub OAuth (optional) GITHUB_ID=your-github-oauth-app-id GITHUB_SECRET=your-github-oauth-app-secret # Upstash Redis (for TTL/caching) UPSTASH_REDIS_REST_URL=https://your-redis-url UPSTASH_REDIS_REST_TOKEN=your-token # Upstash QStash (for webhooks) QSTASH_TOKEN=your-qstash-token QSTASH_CURRENT_SIGNING_KEY=your-signing-key QSTASH_NEXT_SIGNING_KEY=your-next-signing-key # Optional: API URL for CLI SECRETTUNNEL_API_URL=http://localhost:3000 API_URL=http://localhost:3000
-
Set up the database
cd apps/web bun prisma migrate deploy # Apply migrations # or bun prisma db push # For development
-
Run the development server
# From root bun devThis starts:
- Web app: http://localhost:3000
- Turbo UI: http://localhost:3000
Individual apps:
# Web app only cd apps/web && bun run dev # CLI cd apps/cli && bun run dev
# Development
bun dev # Run all apps in dev mode
# Building
bun run build # Build all apps and packages
# Type checking
bun run check-types # Type-check all apps
# Linting
bun run lint # Lint all apps
# Formatting
bun run format # Format code with Prettiercd apps/web
# Development
bun run dev # Start dev server on :3000
# Building
bun run build # Production build
bun run start # Start production server
# Type checking & linting
bun run check-types # TypeScript check
bun run lint # ESLint
# Database
bun prisma migrate dev # Create and apply migration
bun prisma migrate deploy # Apply migrations
bun prisma db push # Sync schema (dev)
bun prisma studio # Open Prisma Studiocd apps/cli
# Development
bun run dev
# Build
bun run build
# Usage examples
bun src/index.ts push "my secret"
bun src/index.ts pull <share-url>- Algorithm: AES-256-GCM (Web Crypto API)
- Key location: URL fragment only (
#key=...) - Server: Receives and stores only ciphertext
- Key derivation: Not exposed to server; derived client-side
- Algorithm: scrypt with salt
- Storage: Password hash stored in Redis/PostgreSQL
- Comparison: Timing-safe comparison to prevent timing attacks
- Implementation:
lib/password.tsusing Node.js crypto
- Provider 1: GitHub OAuth via NextAuth.js
- Provider 2: Credential-based (email + password)
- Session: HTTP-only cookies (NextAuth.js default)
- Type safety: Custom
next-auth.d.tstype extensions
- HTTPS: Required in production
- Rate limiting: Implemented in
lib/rate-limit.ts - CORS: Configured as needed
- Webhook timeout: 5 seconds (configurable)
| Method | Route | Purpose |
|---|---|---|
POST |
/api/secrets |
Create a secret |
GET |
/api/secrets/:token |
Retrieve a secret |
GET |
/api/test |
Health check |
| Method | Route | Purpose |
|---|---|---|
GET |
/api/audit |
List audit logs |
GET |
/api/versioned-secrets/groups |
List secret groups |
POST |
/api/versioned-secrets |
Create versioned secret |
GET |
/api/versioned-secrets/:id |
Get versioned secret |
| Method | Route | Purpose |
|---|---|---|
POST |
/api/webhooks/deliver |
Deliver webhook notifications |
SecretTunnel CLI β Node.js command-line tool for secret management without UI.
Features:
- Push secrets from command line or files
- Pull secrets with optional password
- Configure TTL and webhooks
- Custom API endpoints via environment variables
Commands:
# Push secret
bun src/index.ts push "content" [--ttl 24h] [--password pass] [--webhook url] [--file path]
# Pull secret
bun src/index.ts pull <url-or-token> [--key base64] [--password pass] [--output path|->]API endpoints used:
POST /api/secretsβ Create secretGET /api/secrets/:tokenβ Retrieve secret
SecretTunnel Web App β Next.js full-stack application with UI, authentication, and versioned secrets.
Key routes:
| Route | Page | Purpose |
|---|---|---|
/ |
Home | Landing page |
/signin |
Sign in | User login |
/signup |
Sign up | User registration |
/dashboard |
Dashboard | User's secret groups |
/s/:token |
Secret viewer | Public secret view |
/vs/:groupId |
Versioned secrets | Versioned secret group |
Key features:
- User authentication (GitHub + credentials)
- Create, view, and delete secrets
- Versioned secret management
- Audit logging
- Webhook integration
- Dark mode support (next-themes)
Shared encryption utilities for AES-256-GCM encryption and decryption.
Exports:
encrypt()β Encrypt plaintext to ciphertextdecrypt()β Decrypt ciphertext to plaintext- Type utilities for working with encrypted data
Used by:
- Web app (frontend + backend)
- CLI (encryption/decryption)
Shared ESLint configuration files:
base.jsβ Core ESLint rulesnext.jsβ Next.js-specific rulesreact-internal.jsβ React rules for internal use
Shared TypeScript configuration files:
base.jsonβ Base tsconfignextjs.jsonβ Next.js specificreact-library.jsonβ React library specific
- User creates a secret with a webhook URL
- Webhook URL stored in Redis with secret metadata
- When secret is viewed:
- Secret marked as "delivered"
- QStash queues webhook task
- QStash triggers
/api/webhooks/deliver:- Makes HTTP POST to webhook URL
- Sends:
{ token, viewedAt, viewerIp } - Timeout: 5 seconds
- Webhook status stored:
pendingβenqueuedβdelivered|failed
Webhook retry logic:
- Handled by QStash (configurable)
- Failed webhooks can be retried manually
bun run check-types # All apps
cd apps/web && bun run check-typesbun run lint # All apps with no warnings
cd apps/web && bun run lint- Access web app: http://localhost:3000
- CLI:
cd apps/cli && bun run dev - Prisma Studio:
cd apps/web && bun prisma studio
For production:
- Use strong
NEXTAUTH_SECRET(generate with:openssl rand -base64 32) - Set
NEXTAUTH_URLto your production domain - Configure GitHub OAuth for your domain
- Use Upstash Redis and QStash for prod instances
- Enable HTTPS only
# Build all apps
bun run build
# Build web app specifically
cd apps/web && bun run build
# Preview production build
cd apps/web && bun run startSupported:
- Vercel (Next.js optimized)
- Docker (containerization-ready)
- Self-hosted (Node.js β₯18)
Example Vercel deployment:
vercel deploy| Variable | Used By | Required | Purpose |
|---|---|---|---|
DATABASE_URL |
Web | β | PostgreSQL connection string |
NEXTAUTH_URL |
Web | β | NextAuth callback URL |
NEXTAUTH_SECRET |
Web | β | NextAuth session secret |
RESEND_API_KEY |
Web | β | Resend API key for credential email verification |
RESEND_FROM_EMAIL |
Web | β | Verified sender, for example SecretTunnel <noreply@example.com> |
GITHUB_ID |
Web | β | GitHub OAuth app ID |
GITHUB_SECRET |
Web | β | GitHub OAuth app secret |
UPSTASH_REDIS_REST_URL |
Web | β | Redis URL for TTL/caching |
UPSTASH_REDIS_REST_TOKEN |
Web | β | Redis auth token |
QSTASH_TOKEN |
Web | β | QStash API token |
QSTASH_CURRENT_SIGNING_KEY |
Web | β | QStash signing key |
QSTASH_NEXT_SIGNING_KEY |
Web | β | QStash next signing key |
SECRETTUNNEL_API_URL |
CLI | β | Web API URL (default: localhost:3000) |
API_URL |
CLI | β | Fallback API URL |
NODE_ENV |
Both | β | Environment (dev/production) |
- Create a feature branch:
git checkout -b feature/my-feature - Make changes and commit:
git commit -am "Add feature" - Push to branch:
git push origin feature/my-feature - Open a Pull Request
- Run type checking:
bun run check-types - Run linting:
bun run lint - Format code:
bun run format - All checks must pass before merging
This project is licensed under the MIT License β see LICENSE for details.
- Next.js β React framework
- Prisma β Database ORM
- shadcn/ui β Component library
- Turborepo β Monorepo management
- Upstash β Serverless Redis & QStash
- NextAuth.js β Authentication
For issues, questions, or feature requests, please open an issue on GitHub.
Last updated: April 2026 | Node.js: β₯18 | Package Manager: Bun β₯1.2.23