FadeKey: zero-knowledge, self-destructing secret sharing engine

Published: (June 6, 2026 at 05:57 PM EDT)
4 min read
Source: Dev.to

Source: Dev.to

Cover image for FadeKey: zero-knowledge, self-destructing secret sharing engine

              [![Julian Geiger Nunes](https://media2.dev.to/dynamic/image/width=50,height=50,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3962901%2Fae7f830c-cc54-4681-a780-2fa7e3c1e4ab.jpg)](https://dev.to/juliangn)
              
              
            
      

      
          

GitHub “Finish-Up-A-Thon” Challenge Submission

This is a submission for the GitHub Finish-Up-A-Thon Challenge

What I Built

FadeKey is a zero-knowledge, self-destructing secret sharing engine. Encrypted entirely in the browser using AES-GCM, the decryption key resides only in the URL hash fragment (#key=...). Since browsers do not send the hash fragment in HTTP requests, the server never sees the key or plaintext.

The project is divided into two distinct components:

  • Public Open-Source Core: A standalone, stateless Fastify API and SDK package for self-hosting and automation via pipelines/CLI.
  • Private SaaS Dashboard: A commercial-grade Nuxt 4 web app that adds user accounts, Postgres database sync, persistent audit logs, and Stripe subscription control.

Demo

Live Site (Private SaaS): https://fadekey.app

GitHub Repository (Open-Source Core): https://github.com/fadekey-app/fadekey.api

The Comeback Story

We resurrected an unfinished prototype that had major security flaws, incomplete features, and a leaking state. Here is our before-and-after journey:

  1. Active Revocation (SDK & API Core)
  • Before: Secrets could only expire via TTL or view limits. The backend lacked a deletion endpoint, and the @fadekey/sdk had an empty placeholder where revoke() should have been.

After: We built a secure DELETE /api/items/:id route in the Fastify API (with owner verification checks) and implemented the corresponding revoke(id) method in the SDK package.

2. Zero-Knowledge Compliance for QR Codes (UX/Security)

  • Before: The prototype suggested using external public APIs to generate QR codes. However, sending the full secret URL (containing the #key hash) to a third-party server violates zero-knowledge compliance.

After: We moved 100% of the QR code generation to the browser using local client-side rendering with the qrcode library, ensuring the decryption key never leaves the client.

3. Local-to-Cloud Preference Syncing

  • Before: Users lost their theme (dark/light) and locale (en/es/pt-BR) settings upon page reload, and there was no way to persist these preferences for registered users.

After: We built a dual-persistence system. Anonymous users store preferences in cookies/localStorage, while authenticated users sync their choices automatically to a PostgreSQL database via a new PATCH /api/auth/preferences endpoint.

4. Critical Nuxt SSR Session Leaks (Major Bugfix)

  • Before: The authentication state was stored in a global reactive singleton. During Server-Side Rendering (SSR), this leaked the session/token of one user to subsequent requests from completely different visitors, causing security risks and hydration errors.

After: We refactored the auth composable to store sessions in request-isolated Nuxt useState wrappers, guaranteeing sandboxed memory for every client.

5. Transition Polish & Redirection Guarding

  • Before: Logging out caused dashboard pages to immediately display blank values and zeroes before redirecting. Redirections also dropped the active language prefix (e.g. redirecting /pt-BR/app/dashboard to / instead of /pt-BR).
  • After: We deferred state destruction in signOut() until after the router navigation completes, backed by a nextTick + 150ms delay in router.afterEach to allow the DOM to mount. We wrapped all redirects in localePath() to ensure language consistency.

My Experience with GitHub Copilot

GitHub Copilot acted as a core partner during this sprint, particularly in:

  • Refactoring Auth for SSR Safety: Copilot recognized the risks of our initial module-level singleton state in Nuxt and drafted the migration to request-scoped useState hooks, pointing out how to avoid server-side data pollution.

  • Writing Vitest Suites with Testcontainers: It accelerated the creation of our backend integration tests, generating mock Postgres databases and Redis instances using Docker Testcontainers to test rate-limiting and quota rollback scenarios.

  • Client-side Encryption Pipelines: Copilot assisted in structuring the Web Crypto API calls in our SDK to correctly derive password hashes using PBKDF2 without introducing synchronous blocking.

0 views
Back to Blog

Related posts

Read more »

Mobile Midsommer Madness

!Cover image for Mobile Midsommer Madnesshttps://media2.dev.to/dynamic/image/width=1000,height=420,fit=cover,gravity=auto,format=auto/https%3A%2F%2Fdev-to-uploa...