>_ INITIALIZING DATABANKS...
>_ LOADING UI MODULES...
>_ DECRYPTING ASSETS...
>_ SECURING CONNECTION...
>_ SYSTEM READY.

Blog Site

Astro React Python Tailwind CSS AES-256 GitHub Actions
USER: SYS_ADMIN | DATE: 2026-03-22 | PID: Blog-Site
Cover for Blog Site

Building Serverless Mind-Palace

A Blog and a Notion Alternative

I started working on this site after my resume/portfolio site. I realized it would be great to have a centralized place where someone could see the actual implementation of my projects or learn more about my work. For this site, I wanted to have a cool, distinct interface. I really liked the sleek color scheme that Claude uses, and I’m a big fan of turquoise. That’s why I ended up creating a design system that brings the two together.

Usually, I use Notion as a second brain to store information I need to come back to anything ranging from work notes, future plans, surveys over a new tech/tool, or just quick cheatsheets (which I call “Resources”). However, I started reading about potential data privacy concerns with hosted workspaces, and data security is something I have been leaning into recently. I wanted full ownership of my data without paying a subscription. This led to the idea of baking a secure “Vault” feature directly into this site.

Since I was building a secure vault and wanted to stick to this color palette, I went with a cyberpunk-inspired terminal theme that seamlessly transitions into a sleek, SaaS-like reader interface. It’s a quick, snappy website to showcase my public posts, but with a hidden, private backend serving as a personal, free alternative to Notion.

How It Works (The Architecture)

To give an overview of the implementation, the site avoids traditional backend servers (like Node.js or PostgreSQL) entirely. Instead, it relies on a hybrid architecture that splits the workload between the build step and the browser. Here are the layers making it happen:

  • The Public Layer: I can just write standard Markdown files via Decap CMS or during the build process, Astro takes these files and compiles them into ultra-fast, static HTML pages. No database queries! No loading spinners, just raw static speed :D
  • The Private Layer: This is where things get interesting. Before Astro even touches the code, a Python script (encrypt_vault.py) runs in my GitHub Actions pipeline. It scans a specific /vault directory containing my private Markdown files. Instead of turning these into HTML, it takes the raw text, generates a random cryptographic salt, and encrypts everything using AES-256-GCM and a PBKDF2 key derivation function. It then bundles all these encrypted files along with their hierarchical parent-child relationships into a single encrypted.json file.

Deep Dive Log: Read exactly how the cryptographic trapdoor works and why it mathematically prevents reverse-engineering.

  • GhostTerminal & The Amnesia Protocol: To actually read my vault, I don’t go to a separate login page. I built hidden triggers directly into the UI. Regardless of the device, I can tap a specific invisible sector on the screen three times (or hit Shift + Alt + V), and a sleek authentication modal elegantly blurs the background and prompts me for access.
// GhostTerminal.jsx - The Secret Trigger
const handleSecretTrigger = (e) => {
  e.preventDefault();
  if (terminalState === 'unlocked') return; // Do nothing if already in
  
  const newCount = clickCount + 1;
  setClickCount(newCount);
  
  // Reset the counter if a second passes between clicks
  if (clickTimeout.current) clearTimeout(clickTimeout.current);
  clickTimeout.current = setTimeout(() => setClickCount(0), 1000);
  
  // If 3 rapid clicks are detected, trigger the modal for master key
  if (newCount >= 3) {
    setClickCount(0);
    setTerminalState('prompting');
  }
};

Once the modal prompts me, I enter my master password. The browser uses the native WebCrypto API to hash my input against the salt stored in the JSON file. If it matches, the vault unlocks and I am dropped into the “Datapad”.

The Datapad is a custom React interface that features a hierarchical Explorer sidebar (grouping logs and resources under their parent projects) and a dynamic, floating Table of Contents that tracks my reading progress.

The coolest part is what I call the Amnesia Protocol. The decrypted markdown files are never saved to the hard drive or localStorage. They exist purely in the browser’s volatile sessionStorage.

// A snippet of the decryption routine
const decryptedBuffer = await window.crypto.subtle.decrypt(
  { name: "AES-GCM", iv }, 
  key, 
  ciphertext
);
const decoded = new TextDecoder().decode(decryptedBuffer);

// Save strictly to volatile RAM. 
sessionStorage.setItem('volatileRamLogs', decoded);

The moment I close the browser tab, the memory is wiped clean. The data ceases to exist in a readable format until I trigger the terminal and enter the password again.

Deep Dive Log: Check out the UI implementation and how React handles state management without leaking decrypted data

Miscellanies updates

The site after creation went through a UI update. this stemmed from the need to have a separate place for holding the resources. I wanted to store lookup information that I tend to usually search every once in a while.

While I was doing this I ended up having an update to the site which allows a datapad like configuration which has a much more cleaner UI/UX for traversing the content

Deep Dive Log: Nuances about how the optimization was done and what were the new updates

Engineering Trade-offs

No system is perfect, and building a serverless vault requires accepting a few specific architectural trade-offs:

  1. The Payload Size (JSON Bloat): Because the database is just a flat JSON file, the Python script bundles every single vault log into one payload. Right now, downloading a few megabytes of encrypted text takes milliseconds. But if this vault scales to 10,000 entries, then the browser would have to download a massive file just to read a single note. For a personal site, this limit is acceptable, but it wouldn’t work for a large-scale SaaS app.
  2. Client-Side Vulnerabilities: The cryptography sitting on the GitHub repository is practically bulletproof. However, because the decryption happens inside the browser’s DOM, the text is theoretically vulnerable to malicious browser extensions installed on my local machine. It relies on the local environment being secure.

Conclusion

What started as a simple portfolio site evolved into a fully autonomous, serverless mind-palace. By combining Astro’s static generation speeds with React’s dynamic client-side rendering and wrapping it all in a Python-powered cryptographic build step, I ended up with a system that gives me the best of both worlds. All of this while looking cool :D

As for anyone on the internet? They can browse my projects, resources, and standard blog posts instantly, while I retain a mathematically secure, entirely free workspace hidden just beneath the surface. No databases to manage, no monthly server costs, and total ownership over my data.

0%