A zero-trust, burn-after-read secret sharing platform β passwords, API keys, and private notes that self-destruct the moment they're viewed.
- Overview
- Features
- Screenshots
- Architecture
- Tech Stack
- Installation
- Configuration
- Usage
- API Reference
- AI Sensitivity Detection
- Deployment
- Testing
- Roadmap
- Contributing
- FAQ
- License
- Contact
AshVault lets you create a link for sensitive content β a password, an API key, a private note β that destroys itself the instant it's opened. No lingering copies, no recoverable history, no second read.
Every secret gets:
- A cryptographically random UUID v4 link (2ΒΉΒ²Β² possible combinations β effectively unguessable)
- An optional password gate before the content is revealed
- A TTL (time-to-live) so unread secrets vanish automatically
- Soft-delete burn tracking (
isBurned/burnedAt) β the record persists for audit purposes, but the content is permanently wiped, never served twice
| Feature | Description | |
|---|---|---|
| π₯ | Burn-on-Read | Content is wiped from the database the moment it's viewed β not just hidden, permanently gone. |
| π | UUID Links | Unguessable, cryptographically random secret URLs. |
| β±οΈ | Auto-Expiry (TTL) | Set 1 hour / 24 hours / 7 days β unread secrets self-destruct on schedule. |
| π | Password Protection | Optional passphrase gate, hashed with bcrypt before storage. |
| π€ | AI Sensitivity Detection | LLM-powered classifier flags password/API-key/PII-type content and suggests a safer TTL β see details. |
| π | Dashboard | Logged-in users can track their secrets' status (active / burned / expired) without ever seeing burned content again. |
| πͺ | Secure Auth | JWT access + refresh tokens delivered via HttpOnly cookies. |
βββββββββββββββ HTTPS ββββββββββββββββ ββββββββββββββββββ
β Frontend β ββββββββββββββββΆ β Backend β βββββΆ β MongoDB Atlas β
β (Vercel) β ββββββββββββββββ β (Render/ β β (secrets, users)β
β HTML/JS/CSS β JSON + Cookies β Express) β ββββββββββββββββββ
βββββββββββββββ ββββββββ¬ββββββββ
β
βΌ
ββββββββββββββββ
β Groq API β
β (Llama 3.1 β β
β sensitivity β
β classification)β
ββββββββββββββββ
Request lifecycle for secret creation
- User submits secret content + optional password + TTL choice
- Backend generates a UUID v4
secretID, hashes the password (if any), computesexpiresAt - Secret document saved to MongoDB
- Content is passed in-memory only to the Groq sensitivity classifier (never persisted)
- Response returns
secretID+ AI hint; frontend renders the shareable link and hint badge
- Frontend: Vanilla HTML/CSS/JS (multi-page:
index,login,dashboard,secret-view,about) - Backend: Node.js, Express 5, Mongoose
- Database: MongoDB Atlas
- Auth: JWT (access + refresh tokens), HttpOnly cookies, bcrypt password hashing
- AI: Groq API (
llama-3.1-8b-instant) for real-time content sensitivity classification - Hosting: Vercel (frontend), Render (backend)
Prerequisites
- Node.js β₯ 18
- A MongoDB Atlas cluster (or local MongoDB instance)
- A free Groq API key
# 1. Clone the repository
git clone https://github.com/Saubhagya1621/AshVault---Burnt-on-Read.git
cd AshVault---Burnt-on-Read# 2. Install backend dependencies
cd backend
npm install# 3. Install frontend (no build step β static files)
cd ../frontend
# open with a static server, e.g.
npx serve .# 4. Set up environment variables (see Configuration below)
cd ../backend
cp .env.example .env
# then edit .env with your own values# 5. Run the backend
cd backend
npm run devThe frontend will call the backend via the API_BASE value in frontend/Config.js β update it to point at your local backend (http://127.0.0.1:8000) during development.
Backend .env variables
| Variable | Description |
|---|---|
PORT |
Port the Express server listens on |
MONGODB_URI |
MongoDB Atlas connection string |
CORS_ORIGIN |
Allowed origin(s) for CORS |
ACCESS_TOKEN_SECRET |
Secret for signing JWT access tokens |
ACCESS_TOKEN_EXPIRY |
Access token lifetime (e.g. 1d) |
REFRESH_TOKEN_SECRET |
Secret for signing JWT refresh tokens |
REFRESH_TOKEN_EXPIRY |
Refresh token lifetime (e.g. 10d) |
ENCRYPTION_KEY |
Key used for internal encryption utilities |
GROQ_API_KEY |
API key for the Groq sensitivity classifier β get one free |
β οΈ Never commit.envβ it's already covered by.gitignore. Rotate any key that's ever been exposed.
Frontend Config.js
const API_BASE =
window.location.hostname === "localhost" ||
window.location.hostname === "127.0.0.1"
? "http://127.0.0.1:8000"
: "https://ashvault-burnt-on-read.onrender.com";Update the production fallback URL if you deploy your own backend instance.
- Sign up / log in at
/login.html - Write your secret β paste a password, API key, or note (up to 10,000 characters)
- Configure security β choose expiry (1h / 24h / 7d) and optionally add a password
- Generate the link β copy and share it; the AI sensitivity hint will suggest whether your TTL choice makes sense
- Recipient opens the link once β content is shown, then permanently burned
POST /api/v1/secrets/create β create a new secret
Request body:
{
"content": "sk-live-example-key",
"password": null,
"expiresAt": "1h"
}Response:
{
"statusCode": 201,
"data": {
"secretID": "b3a1c9e0-...-uuid",
"sensitivityHint": {
"isSensitive": true,
"category": "api_key",
"suggestedTTL": "1h",
"reason": "matches API key format"
}
},
"message": "Link generated successfully!",
"success": true
}POST /api/v1/secrets/v/:secretID β view (and burn) a secret
Request body (if password-protected):
{ "password": "your-passphrase" }Response:
{
"statusCode": 200,
"data": { "content": "the secret content" },
"message": "Secret retrieved and burned forever.",
"success": true
}Calling this endpoint a second time on the same
secretIDreturns410 Gone.
DELETE /api/v1/secrets/burn/:secretID β manually destroy a secret (auth required)
Requires a valid JWT (owner only). Returns 200 with an empty payload on success.
GET /api/v1/secrets/my-secrets β list the logged-in user's secrets (auth required)
Returns secret metadata only β content and password fields are always excluded.
AshVault uses a lightweight LLM classifier (Groq / Llama 3.1) as a non-blocking safety layer during secret creation:
- Content is analyzed in-memory only at creation time β the classifier's input is never stored in the database
- Returns a structured hint:
isSensitive,category(password/api_key/pii/financial/personal_message/other), a shortreason, and asuggestedTTL - If classification fails for any reason (rate limit, network error), secret creation still succeeds β the hint is purely additive UX, never a blocker
This was a deliberate design choice: sensitivity detection should inform the user, never gate or delay their ability to protect a secret.
| Layer | Platform | Notes |
|---|---|---|
| Frontend | Vercel | Static hosting, auto-deploys on push to main |
| Backend | Render | Node web service, auto-deploys on push to main |
| Database | MongoDB Atlas | Free-tier cluster |
Deploying your own instance
- Fork this repo
- Create a Render web service pointing at
/backend, add all env variables from Configuration - Create a Vercel project pointing at
/frontend - Update
frontend/Config.jsproduction URL to your Render service URL - Push to
mainβ both platforms auto-deploy
Manual test checklist
- Create secret β link generates β visiting link shows content once β second visit returns
410 - Password-protected secret rejects wrong password, accepts correct one
- TTL expiry: secret becomes inaccessible after configured time
- AI hint appears for sensitive content, stays hidden for casual text
- Dashboard reflects burned/active status correctly without exposing content
- Automated test suite (Jest/Supertest)
- Rate limiting on secret view attempts
- Anomaly detection on access patterns (IP/geo heuristics)
- Optional end-to-end client-side encryption
- Multi-language UI
Contributions are welcome!
- Fork the repo
- Create a feature branch:
git checkout -b feat/your-feature - Commit with clear messages:
git commit -m "feat: add X" - Push and open a Pull Request
Please keep PRs focused and include a short description of what changed and why.
Can a burned secret ever be recovered?
No. On burn, content is overwritten to an empty string in the database. Only metadata (isBurned, burnedAt) persists for audit purposes.
Does the AI feature see my actual secret content permanently?
No. Content is sent to the Groq API only for the duration of that single classification request and is never written to AshVault's database.
What happens if the AI classifier is down?
Secret creation still succeeds β sensitivityHint is simply null and no badge is shown.
Distributed under the MIT License. See LICENSE for details.
Saubhagya Srivastava




