Cryptgeon

Self-destructing encrypted notes and files that vanish after viewing — the server never sees your keys.

1.5Kstars
149forks
MIT License
Svelte

Cryptgeon is a self-hostable, zero-trust service for sharing encrypted notes and files that self-destruct after a set number of views or a time limit. Inspired by PrivNote, it was built with a strict privacy guarantee: all encryption and decryption happens in the browser or CLI client using AES-256-GCM, so the server receives only ciphertext and can never read your content.

The project ships as a single Docker image backed by Redis for in-memory storage. Data is never written to disk, meaning a server breach yields nothing readable. Notes are identified by a 256-bit ID and encrypted with a separate 256-bit key that never leaves the client — only the ID reaches the server; the key lives in the URL fragment.

Cryptgeon is available as a hosted demo at cryptgeon.org, as a self-hosted Docker deployment, and as a CLI tool installable via npx for scripting and terminal workflows. A Raycast extension brings one-click note creation to macOS power users.

What You Get

  • Client-side AES-256-GCM encryption - Notes and files are encrypted in the browser using the occulto library before transmission; the 256-bit key is embedded in the URL fragment and never sent to the server, making server-side decryption impossible by design.
  • Guaranteed view-count enforcement - The Rust backend uses a per-note async mutex to serialize concurrent retrieval requests, ensuring a note set to one view cannot be fetched more than once even under race conditions.
  • Ephemeral Redis-only storage - All data lives exclusively in Redis configured with --save "" --appendonly no and a tmpfs mount, so nothing is ever written to disk and notes vanish completely when they expire or the container restarts.
  • Dual expiry modes - Notes can be limited by view count (1–100 views) or by time (1–360 minutes), with the server enforcing both at the API layer and the frontend providing real-time feedback on expiry parameters.
  • CLI and scripting support - The npx cryptgeon CLI supports text notes, multi-file bundles, password protection, custom view/minute limits, and piping passwords from stdin, enabling secure note creation in shell scripts and CI pipelines.
  • Full theming and white-labeling - Logo, favicon, page title, footer text, and legal imprint are all configurable via environment variables without rebuilding the image, making it suitable for branded internal deployments.
  • File upload with client-side size enforcement - Files up to 512 MiB can be shared with the same zero-trust encryption as text notes; the frontend calculates and warns about the ~35% base64 overhead before submission.
  • Raycast extension and i18n support - An official Raycast extension enables one-click note creation from macOS, and the frontend ships with translations including English, Simplified Chinese, and Spanish.

Common Use Cases

  • Sharing one-time credentials - A developer sends a database password or API key to a teammate as a single-view Cryptgeon note; after the recipient opens it, the note is gone and cannot be accessed again, eliminating credential exposure in chat logs.
  • Secure document handoff between journalists and sources - A reporter shares an encrypted PDF over Cryptgeon’s file upload feature with a source, setting a one-view, one-hour expiry so the document cannot be accessed after the intended window.
  • Automated secret distribution in CI/CD pipelines - A DevOps engineer uses cryptgeon send text in a pipeline script to generate a one-time encrypted link for a deployment token, then passes the link to a Slack notification rather than embedding secrets in plaintext.
  • Internal team self-hosted deployment - A startup runs a self-hosted Cryptgeon instance behind their VPN so employees can share temporary notes and files with confidence that nothing is stored on shared infrastructure or readable by admins.
  • Ephemeral onboarding credentials - An IT admin generates individual one-time Cryptgeon notes containing new-hire WiFi passwords and initial account credentials, ensuring each note self-destructs after the employee reads it.

Under The Hood

Architecture Cryptgeon follows a strict separation-of-concerns monorepo design with three independent packages: a Rust Axum backend, a Svelte 5 SvelteKit frontend, and a TypeScript CLI. The backend exposes only three API routes — POST to create a note, GET to preview note metadata, and DELETE to retrieve and decrement a note — keeping the attack surface minimal. A per-note async mutex in the Rust layer serializes concurrent DELETE requests, providing an atomicity guarantee that prevents view-count races even under high concurrency. The frontend is compiled to fully static assets and served by the Rust binary itself, collapsing the entire application into a single Docker image with no external runtime dependencies beyond Redis.

Tech Stack The backend is written in Rust with Axum 0.8 and Tokio for async I/O, using the ring crate for cryptographically secure random ID generation and serde_json for serialization. Redis serves as the sole datastore, accessed synchronously per request with native Redis TTL for time-based expiry. The frontend uses Svelte 5 with rune-based reactivity ($state, $effect) compiled via SvelteKit’s static adapter and Vite. Client-side encryption is handled entirely by occulto, a zero-dependency AES-GCM library, keeping the cryptographic footprint minimal. The CLI is TypeScript with @commander-js/extra-typings for full type safety and shares a common cryptgeon workspace package with the frontend. Docker multi-stage builds produce a minimal Alpine runtime image that serves both the API and frontend static files.

Code Quality End-to-end test coverage using Playwright spans text notes, file sharing, view counts, time expiration, password protection, and cross-client CLI-to-web and web-to-CLI round trips. Tests use reusable helper abstractions with SHA-3 checksum verification for file integrity. The Rust backend uses explicit Result propagation throughout with no panics in request handlers. Svelte 5 runes replace the legacy store-based reactive model, reducing boilerplate and making data flow explicit. A CONTRIBUTING.md with setup instructions and a mise.toml for toolchain pinning lower the onboarding friction for contributors. The repository has no unit tests for the Rust layer, relying entirely on integration-level Playwright tests.

What Makes It Unique The defining technical choice is the URL-fragment key architecture: the 256-bit encryption key is embedded in the # hash portion of the share link, which browsers never send to the server in HTTP requests. This means the server is cryptographically incapable of reading note contents regardless of who controls it — a stronger guarantee than server-side encryption schemes where admins hold the keys. The occulto library was chosen specifically to minimize third-party cryptographic dependencies, reducing supply-chain risk. The Rust mutex-per-note locking pattern is a precise engineering response to a real concurrency problem: without it, two simultaneous consumers of a one-view note could both succeed. Most competing tools address this with database transactions; Cryptgeon solves it in application memory for lower latency.

Self-Hosting

Cryptgeon is released under the MIT License, which is one of the most permissive open-source licenses available. You are free to use, modify, distribute, and run it commercially without any licensing fees or restrictions. There is no copyleft requirement, so you can embed or adapt Cryptgeon in proprietary systems without being required to open-source your modifications. The only obligation is to preserve the copyright notice in any distribution of the software itself.

Running Cryptgeon yourself is operationally lightweight compared to most self-hosted tools. The entire application ships as a single Docker image that also serves the frontend, so the deployment surface is just the container plus a Redis instance. Redis must be configured for RAM-only mode (no persistence to disk) to preserve the security model — the provided docker-compose.yml handles this with --save "" --appendonly no and a tmpfs mount. You are responsible for HTTPS termination (the app requires it for browser cryptographic APIs), container restarts, Redis memory limits, and any backups of configuration. There is no application database to maintain or migrate. The project publishes Docker images on Docker Hub and has a health endpoint at /api/health/ for container orchestration.

There is no paid cloud tier or enterprise offering from the maintainer. The public hosted instance at cryptgeon.org is available as a convenience and a demo, but self-hosting is the intended path for teams with privacy requirements. What you give up compared to the hosted instance is mainly operational peace of mind: no SLA, no managed upgrades, no support contract, and no HA setup out of the box. Multi-instance deployments share a known limitation — concurrent view-count enforcement is only guaranteed within a single running instance; multiple replicas connected to the same Redis can still hit race conditions on view counts. For most self-hosting scenarios with reasonable load, a single instance is sufficient.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack

No spam. Unsubscribe anytime.

Join 750+ subscribers
No spam. Unsubscribe anytime.

Search