Skip to content

Latest commit

Β 

History

97 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Obsidian

πŸ” What is Obsidian

A zero-knowledge pastebin where the server never sees what you write. Built on Next.js 16 and evolved from PrivateBin's battle-tested security model, extended with asymmetric RSA key wrapping, Shamir's Secret Sharing for multi-party quorum control, and end-to-end encrypted real-time collaboration. (obsidian blocks are maaad tough to break in minecraft 😝)


Features

  • πŸ†• Modernised Legacy Features β€” next-gen tech stack (Next.js 16, React 19, Tailwind v4, Web Crypto API) for legacy features
  • πŸ’» Developer CLI Tool (obsidian) β€” terminal client for encrypted pastes, RSA key management, whole-repo sharing, and Shamir quorum operations
  • πŸ‘οΈ Zero-Knowledge Trust Visualizer β€” animated encryption explainer UI
  • πŸ’₯ N-View Self-Destruct β€” atomic burn-after-reading with configurable view limits
  • ⏳ Time-Locked Notes β€” Time Capsule mode for delayed message access
  • πŸ” Asymmetric RSA-OAEP Key Wrapping β€” public-key mode for 1-to-1 recipient delivery
  • πŸ”‘ Shamir's Secret Sharing β€” k-of-n key splitting for multi-party threshold quorum
  • πŸ”΄ Real-Time E2EE Collaboration β€” Pusher + BroadcastChannel for instant encrypted updates
  • ⌨️ Command Palette β€” Cmd+K shortcuts for power-user workflows
  • πŸ“‹ Paste Starter Templates β€” pre-built content templates
  • πŸ—„οΈ Encrypted Paste Vault β€” searchable collection of saved pastes
  • 🧾 Cryptographic Destruction Receipts β€” JWT-signed proof of paste deletion
  • βœ… Comprehensive Test Suite β€” 85/85 unit tests + 7/7 E2E tests passing

πŸ› οΈ Stack

Layer Tech
πŸš€ Framework Next.js 16, React 19, Tailwind v4
πŸ”’ Crypto Web Crypto API β€” AES-256-GCM, PBKDF2, RSA-OAEP, custom GF(2⁸) Shamir SSS
πŸ’» CLI Node.js (ESM), Commander, Chalk, Ora, Tar, TSX
πŸ—„οΈ Storage PostgreSQL (Neon) via Prisma
⚑ Real-time Pusher WebSockets + BroadcastChannel
🚦 Rate limiting Upstash Redis, HMAC-SHA256 IP hashing

πŸš€ Quickstart

Web Application

cd obsidian
npm install

.env.local:

DATABASE_URL="postgresql://USER:PASSWORD@HOST/DATABASE?sslmode=require"
IP_HMAC_SECRET=<32_byte_secret> # openssl rand -hex 32

# optional β€” enables remote real-time collaboration
PUSHER_APP_ID=
PUSHER_KEY=
PUSHER_SECRET=
PUSHER_CLUSTER=

NEXT_PUBLIC_PUSHER_KEY=
NEXT_PUBLIC_PUSHER_CLUSTER=
npm run db:generate && npm run db:push
npm run dev        # http://localhost:3000
Check Command
Lint npm run lint
Unit tests npm test
Production build npm run build && npm start

πŸ’» Developer CLI Tool (obsidian)

Obsidian includes a full-featured terminal CLI for scripting, CI/CD pipelines, and terminal-first workflows. Encrypt, decrypt, manage RSA identity keys, split secrets with Shamir quorum, or share entire codebases directly from your shell.

πŸ“¦ Installation & Setup

cd obsidian/cli
npm install

# Link globally to use the `obsidian` command anywhere
npm link

# Or run directly via tsx:
npm run dev -- <command>

Configure target server (defaults to http://localhost:3000):

obsidian config set-url https://your-obsidian-instance.com

⚑ Command Reference

Command Description Example
obsidian send Encrypt & upload text or a file obsidian send "my secret API key" --burn
obsidian read Decrypt & read a paste from a URL obsidian read "https://...#key"
obsidian key Manage RSA-2048 identity keypair obsidian key generate && obsidian key show --public
obsidian repo send Tar, encrypt & upload entire folder obsidian repo send ./my-project --exclude dist
obsidian repo get Download, decrypt & extract repo obsidian repo get "<url>#key" --output ./restored
obsidian shamir split Offline mathematical secret splitting obsidian shamir split "root-token" -n 5 -k 3
obsidian shamir combine Offline secret reconstruction obsidian shamir combine "<shard1>" "<shard2>"
obsidian config Inspect or update CLI settings obsidian config set-url https://app.example.com

πŸ› οΈ Common CLI Workflows

1️⃣ Send a Secret or File (Burn-on-Read)

# Encrypt text with automatic self-destruction upon reading (default)
obsidian send "sk_live_998822334455"

# Encrypt a file (.env, config, certificate) without burning
obsidian send --file .env.production --no-burn

# Pipe raw decrypted content in CI/CD scripts
obsidian read "https://obsidian.app/pasteId#key" --raw > .env

2️⃣ Asymmetric RSA-OAEP Targeted Secret Delivery

# 1. Recipient generates and shares their public key
obsidian key generate
obsidian key show --public

# 2. Sender encrypts with recipient's public key (link is useless without recipient's private key)
obsidian send "confidential deployment keys" --recipient "<RECIPIENT_PUBKEY_BASE64>"

# 3. Recipient decrypts automatically using their local keystore (~/.obsidian/identity.json)
obsidian read "https://obsidian.app/pasteId#asym"

3️⃣ Multi-Party Quorum (Shamir's Secret Sharing)

# Create a 2-of-3 threshold paste (outputs 3 individual shard links)
obsidian send "Production Root Access" --shares 3 --threshold 2

# Combine any 2 shard links to reconstruct the key and decrypt
obsidian read "<shard1_url>" --shards "<shard2_url>"

4️⃣ Entire Repository & Folder Sharing

# Compresses (tar.gz), encrypts, and uploads directory (supports --recipient for 1-to-1 secure delivery)
obsidian repo send ./backend-service --exclude node_modules dist .git

# Download, decrypt, and unpack directly to an output directory
obsidian repo get "https://obsidian.app/pasteId#key" --output ./restored-backend

4️⃣ Four ways to share a secret

1️⃣ Plain β€” the PrivateBin baseline

Key in URL fragment: encrypt locally, share link with embedded key β€” one-click decrypt for recipient, server learns nothing.

sequenceDiagram
    autonumber
    actor Creator
    participant Worker as Web Worker
    participant API
    actor Recipient

    Creator->>Worker: Plaintext + options
    Worker->>Worker: Compress β†’ derive key (PBKDF2) β†’ AES-256-GCM encrypt
    Worker-->>Creator: ciphertext, adata, key
    Creator->>API: POST /api/v1/paste
    API-->>Creator: pasteId β†’ URL#keyBase58
    Creator->>Recipient: Share URL
    Recipient->>API: GET /api/v1/paste/:id
    Recipient->>Recipient: Decrypt using #fragment key
Loading

2️⃣ Asymmetric β€” RSA-OAEP key wrapping

Recipient's public key wraps the AES key: link is useless without their private key β€” safe for untrusted channels (Slack, email, logs).

sequenceDiagram
    autonumber
    actor Recipient
    actor Creator
    participant API
    participant IDB as IndexedDB

    Recipient->>IDB: Generate & store RSA-2048 keypair
    Recipient->>Creator: Public key (SPKI base64)
    Creator->>Creator: Encrypt with random AES key
    Creator->>Creator: Wrap AES key with recipient's public key
    Creator->>API: POST { ct, adata[4] = wrapped key }
    API-->>Creator: pasteId β†’ URL#asym
    Recipient->>API: GET /api/v1/paste/:id
    Recipient->>IDB: Load private key
    Recipient->>Recipient: Unwrap AES key β†’ decrypt
Loading

3️⃣ Shamir β€” k-of-n quorum control

Split the AES key into N shards, require K to unlock: multi-party threshold control via Lagrange interpolation over GF(2⁸).

sequenceDiagram
    autonumber
    actor Creator
    participant API
    actor Holder1 as Keyholder 1
    actor Holder2 as Keyholder 2

    Creator->>Creator: Encrypt with AES key
    Creator->>Creator: Split key β†’ 3 shards, threshold 2
    Creator->>API: POST { ct, adata, shardTotal: 3 }
    API-->>Creator: pasteId
    Creator->>Holder1: URL#shard-2-1-3-...
    Creator->>Holder2: URL#shard-2-2-3-...
    Holder1->>API: GET /api/v1/paste/:id
    Holder2->>Holder1: Shard #2
    Holder1->>Holder1: Combine shards β†’ Lagrange interpolation β†’ key
    Holder1->>Holder1: Decrypt
Loading

4️⃣ Collab β€” live E2EE editing

Real-time collaborative editing: encrypted deltas streamed via Pusher as a blind relayβ€”server never holds keys or plaintext.

sequenceDiagram
    autonumber
    actor PeerA
    participant Pusher as Pusher (blind relay)
    actor PeerB

    PeerA->>Pusher: Subscribe presence-collab-:id
    PeerB->>Pusher: Subscribe presence-collab-:id
    PeerA->>PeerA: Encrypt keystroke delta
    PeerA->>Pusher: trigger('client-delta', ct)
    Pusher-->>PeerB: Relay ct only
    PeerB->>PeerB: Decrypt β†’ render live update
Loading

πŸ“ Project structure

obsidian/
β”œβ”€β”€ app/              API routes Β· pages Β· vault Β· interactive docs
β”‚   β”œβ”€β”€ api/v1/paste/           create Β· read Β· delete Β· comment
β”‚   β”œβ”€β”€ api/v1/collab/          presence-channel auth
β”‚   β”œβ”€β”€ api/docs/               interactive API & CLI portal
β”‚   β”œβ”€β”€ pad/                    paste editor UI
β”‚   └── vault/                  user vault
β”œβ”€β”€ cli/              Developer CLI tool (`obsidian-cli`)
β”‚   β”œβ”€β”€ bin/                    CLI executable wrapper (`obsidian.js`)
β”‚   β”œβ”€β”€ src/commands/           send Β· read Β· key Β· repo Β· shamir Β· config
β”‚   β”œβ”€β”€ src/lib/                crypto Β· shamir Β· keystore Β· API clients
β”‚   └── src/utils/              archive tar/gzip Β· display formatters
β”œβ”€β”€ components/       UI components
β”‚   β”œβ”€β”€ editor/                 paste creation UI
β”‚   β”œβ”€β”€ viewer/                 decryption Β· quorum panel Β· comments
β”‚   β”œβ”€β”€ crypto/                 crypto helpers
β”‚   β”œβ”€β”€ collab/                 real-time collaboration
β”‚   β”œβ”€β”€ sharing/                share UI
β”‚   β”œβ”€β”€ qr/                     QR code generator
β”‚   β”œβ”€β”€ ui/                     generic UI primitives
β”‚   └── header/ Β· layout/       layout components & CLI modal
β”œβ”€β”€ lib/              core libraries
β”‚   β”œβ”€β”€ crypto/                 cipher Β· kdf Β· asymmetric Β· shamir Β· compress
β”‚   β”œβ”€β”€ api/                    API clients
β”‚   └── db                      database helpers
β”œβ”€β”€ workers/          off-main-thread PBKDF2 worker
β”œβ”€β”€ hooks/            custom React hooks
β”‚   └── usePasteEncryption Β· usePasteDecryption Β· useCollab
β”œβ”€β”€ prisma/           Prisma schema β†’ Paste Β· Comment Β· AccessLog
β”œβ”€β”€ tests/            unit Β· e2e tests
└── public/           static assets

About

Modern zero-knowledge pastebin (PrivateBin revamped). Client-side AES-256-GCM encryption, RSA-OAEP key wrapping, Shamir's Secret Sharing, burn-after-reading, and real-time E2EE collaboration built on Next.js 16.

Topics

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages