<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Tech — NT² Blog</title>
    <link>https://blog.nt2.me/categories/tech</link>
    <atom:link href="https://blog.nt2.me/categories/tech/feed.xml" rel="self" type="application/rss+xml" />
    <description>Engineering deep dives into the architecture and implementation behind NT² Vault.</description>
    <language>en</language>
    <lastBuildDate>Wed, 02 Sep 2026 00:00:00 GMT</lastBuildDate>
    <item>
      <title>Challenge–response, not bearer email</title>
      <link>https://blog.nt2.me/key-did-challenge-response-auth</link>
      <guid isPermaLink="true">https://blog.nt2.me/key-did-challenge-response-auth</guid>
      <pubDate>Wed, 02 Sep 2026 00:00:00 GMT</pubDate>
      <description>Cloud services often treat an email inbox as the root of an account. An encrypted vault needs a different proof: control of a signing key, shown by answering a one-time challenge.</description>
      <author>NT²</author>
      <category>authentication</category>
      <category>identity</category>
      <category>cryptography</category>
      <category>did</category>
      <category>security</category>
      <category>privacy</category>
      <category>cloud</category>
      <category>zero-knowledge</category>
    </item>
    <item>
      <title>One unlocked vault per tab — by design</title>
      <link>https://blog.nt2.me/single-writer-multi-tab-vault</link>
      <guid isPermaLink="true">https://blog.nt2.me/single-writer-multi-tab-vault</guid>
      <pubDate>Sat, 29 Aug 2026 00:00:00 GMT</pubDate>
      <description>Opening the same vault in two browser tabs is normal. Letting both tabs write the same on-device SQLite file is not. NT² Vault elects one Writer and keeps every other unlocked tab as a follower.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>multi-tab</category>
      <category>local-first</category>
      <category>pwa</category>
      <category>sqlite</category>
      <category>broadcastchannel</category>
      <category>web-locks</category>
      <category>concurrency</category>
    </item>
    <item>
      <title>Metadata in SQLite, ciphertext in BlobStore</title>
      <link>https://blog.nt2.me/attachment-ciphertext-outside-sqlite</link>
      <guid isPermaLink="true">https://blog.nt2.me/attachment-ciphertext-outside-sqlite</guid>
      <pubDate>Wed, 26 Aug 2026 00:00:00 GMT</pubDate>
      <description>A vault needs to know which files belong to which items, how large they are, and how to unwrap their keys. It does not need those encrypted bytes sitting inside the relational database that answers those questions.</description>
      <author>NT²</author>
      <category>attachments</category>
      <category>sqlite</category>
      <category>blobstore</category>
      <category>opfs</category>
      <category>envelope-encryption</category>
      <category>local-first</category>
      <category>aes-gcm</category>
      <category>chunking</category>
    </item>
    <item>
      <title>FTS5 for titles; table scan when filters win</title>
      <link>https://blog.nt2.me/fts5-vs-table-scan-in-the-vault</link>
      <guid isPermaLink="true">https://blog.nt2.me/fts5-vs-table-scan-in-the-vault</guid>
      <pubDate>Sat, 22 Aug 2026 00:00:00 GMT</pubDate>
      <description>Local search is not one query shape. Free-text wants a full-text index on titles and search text. Category, trash, archive, and similar filters want ordinary table predicates. The product switches strategy so the UI never has to ship the whole vault into memory to feel searchable.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>local-first</category>
      <category>sqlite</category>
      <category>fts5</category>
      <category>search</category>
      <category>performance</category>
      <category>pwa</category>
    </item>
    <item>
      <title>Never load the whole vault into Svelte state</title>
      <link>https://blog.nt2.me/paged-list-not-full-table-load</link>
      <guid isPermaLink="true">https://blog.nt2.me/paged-list-not-full-table-load</guid>
      <pubDate>Wed, 19 Aug 2026 00:00:00 GMT</pubDate>
      <description>A local vault can hold thousands of structured items without becoming a giant in-memory array. The durable store stays in SQLite. The UI holds only a paged window of lightweight list rows, rendered through a virtual list.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>local-first</category>
      <category>sqlite</category>
      <category>svelte</category>
      <category>performance</category>
      <category>virtual-list</category>
      <category>pagination</category>
      <category>pwa</category>
    </item>
    <item>
      <title>The account database must not become a password oracle</title>
      <link>https://blog.nt2.me/no-password-oracle-in-d1</link>
      <guid isPermaLink="true">https://blog.nt2.me/no-password-oracle-in-d1</guid>
      <pubDate>Sat, 15 Aug 2026 00:00:00 GMT</pubDate>
      <description>An account table can contain no plaintext vault items and still create a dangerous password-testing surface. We removed the columns that could turn a database copy into an offline guessing or recovery system.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>security</category>
      <category>privacy</category>
      <category>zero-knowledge</category>
      <category>edge</category>
      <category>cloudflare</category>
      <category>d1</category>
      <category>authentication</category>
    </item>
    <item>
      <title>One sync hub for one vault identity</title>
      <link>https://blog.nt2.me/vault-durable-object-per-key-did</link>
      <guid isPermaLink="true">https://blog.nt2.me/vault-durable-object-per-key-did</guid>
      <pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate>
      <description>A vault does not need to enter a shared plaintext mailbox to sync. Its public cryptographic identity can name a dedicated edge coordinator that notifies replicas and points them to encrypted frames it cannot open.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>sync</category>
      <category>privacy</category>
      <category>durable-objects</category>
      <category>key-did</category>
      <category>edge</category>
    </item>
    <item>
      <title>No password reset, by design</title>
      <link>https://blog.nt2.me/no-password-reset-by-design</link>
      <guid isPermaLink="true">https://blog.nt2.me/no-password-reset-by-design</guid>
      <pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate>
      <description>“Contact support to reset your password” sounds reassuring. For an encrypted vault, it also reveals who ultimately controls access. NT² chooses a harder promise: recovery material stays with you, not our help desk.</description>
      <author>NT²</author>
      <category>security</category>
      <category>recovery</category>
      <category>zero-knowledge</category>
      <category>trust</category>
      <category>local-first</category>
    </item>
    <item>
      <title>Blind replica sync on the edge</title>
      <link>https://blog.nt2.me/blind-replica-sync-on-the-edge</link>
      <guid isPermaLink="true">https://blog.nt2.me/blind-replica-sync-on-the-edge</guid>
      <pubDate>Wed, 05 Aug 2026 00:00:00 GMT</pubDate>
      <description>Sync does not have to turn a local vault into a cloud database. The edge can identify an account, store opaque replica frames, and deliver updates without learning what those updates contain.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>sync</category>
      <category>privacy</category>
      <category>local-first</category>
      <category>zero-knowledge</category>
      <category>edge</category>
    </item>
    <item>
      <title>Why our vault SQLite database lives in OPFS, not IndexedDB</title>
      <link>https://blog.nt2.me/opfs-not-indexeddb-for-vault-sqlite</link>
      <guid isPermaLink="true">https://blog.nt2.me/opfs-not-indexeddb-for-vault-sqlite</guid>
      <pubDate>Sat, 01 Aug 2026 00:00:00 GMT</pubDate>
      <description>SQLite wants a file. A privacy vault wants durable relational storage that stays fast as its item count, indexes, and encrypted attachments grow. Putting a SQLite virtual file system on IndexedDB can bridge those worlds, but it makes the bridge part of every database operation. For NT² Vault, the browser vault file belongs in the Origin Private File System.</description>
      <author>NT²</author>
      <category>opfs</category>
      <category>indexeddb</category>
      <category>sqlite</category>
      <category>wasm</category>
      <category>wa-sqlite</category>
      <category>local-first</category>
      <category>pwa</category>
      <category>browser-storage</category>
    </item>
    <item>
      <title>Unlocking a local vault is not logging in to the cloud</title>
      <link>https://blog.nt2.me/unlock-local-auth-cloud</link>
      <guid isPermaLink="true">https://blog.nt2.me/unlock-local-auth-cloud</guid>
      <pubDate>Wed, 29 Jul 2026 00:00:00 GMT</pubDate>
      <description>One screen can make two security events look like a single login. We keep them separate because opening encrypted data and proving an identity to a server are different jobs with different risks.</description>
      <author>NT²</author>
      <category>authentication</category>
      <category>local-first</category>
      <category>privacy</category>
      <category>security</category>
      <category>cryptography</category>
      <category>cloud</category>
    </item>
    <item>
      <title>One key per object: envelope encryption inside NT² Vault</title>
      <link>https://blog.nt2.me/envelope-encryption-cek-per-object</link>
      <guid isPermaLink="true">https://blog.nt2.me/envelope-encryption-cek-per-object</guid>
      <pubDate>Sat, 25 Jul 2026 00:00:00 GMT</pubDate>
      <description>A vault can encrypt everything with one key and still claim that its data is encrypted. We wanted a more useful boundary: each item and attachment gets its own content encryption key, while the vault key protects those keys.</description>
      <author>NT²</author>
      <category>envelope-encryption</category>
      <category>aes-gcm</category>
      <category>cryptography</category>
      <category>local-first</category>
      <category>attachments</category>
      <category>opfs</category>
      <category>security</category>
    </item>
    <item>
      <title>The KDF salt stays on your device</title>
      <link>https://blog.nt2.me/kdf-salt-stays-on-device</link>
      <guid isPermaLink="true">https://blog.nt2.me/kdf-salt-stays-on-device</guid>
      <pubDate>Thu, 23 Jul 2026 00:00:00 GMT</pubDate>
      <description>A salt is not a secret. Still, where it lives changes who can assemble a password-guessing system. NT² keeps the KDF salt and password verifier with the local vault, so unlocking begins and ends on the device.</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>crypto</category>
      <category>security</category>
      <category>local-first</category>
      <category>zero-knowledge</category>
      <category>web-crypto</category>
      <category>pbkdf2</category>
      <category>key-derivation</category>
    </item>
    <item>
      <title>How one person builds and operates NT² Vault with AI agents</title>
      <link>https://blog.nt2.me/one-person-ai-coding-agent-product-lifecycle</link>
      <guid isPermaLink="true">https://blog.nt2.me/one-person-ai-coding-agent-product-lifecycle</guid>
      <pubDate>Mon, 20 Jul 2026 00:00:00 GMT</pubDate>
      <description>The useful question is not whether an AI agent can write code. It is how to give agents enough context and autonomy to move quickly while keeping product decisions, security boundaries, releases, and customer-facing actions under explicit human control.</description>
      <author>NT²</author>
      <category>ai-agents</category>
      <category>human-in-the-loop</category>
      <category>spec-driven-development</category>
      <category>tdd</category>
      <category>devops</category>
      <category>security</category>
      <category>product-development</category>
    </item>
    <item>
      <title>Why host a heavy server when a PWA can do everything locally? Built a zero-server privacy vault.</title>
      <link>https://blog.nt2.me/why-pwa-local-first-zero-server-vault</link>
      <guid isPermaLink="true">https://blog.nt2.me/why-pwa-local-first-zero-server-vault</guid>
      <pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate>
      <description>In the era of massive cloud-first applications, we often overlook a powerful alternative: the Progressive Web App (PWA). Why maintain a heavy, expensive, and potentially vulnerable server infrastructure when the modern browser is capable of running a full-featured, secure, and high-performance application entirely on the user&apos;s device?</description>
      <author>NT²</author>
      <category>architecture</category>
      <category>pwa</category>
      <category>privacy</category>
      <category>security</category>
      <category>local-first</category>
      <category>zero-knowledge</category>
      <category>web-crypto</category>
      <category>sqlite</category>
      <category>wasm</category>
      <category>opfs</category>
    </item>
    <item>
      <title>Threshold Vault and Key DID: identity without handing over the keys</title>
      <link>https://blog.nt2.me/threshold-vault-key-did-self-sovereign-identity</link>
      <guid isPermaLink="true">https://blog.nt2.me/threshold-vault-key-did-self-sovereign-identity</guid>
      <pubDate>Tue, 30 Jun 2026 00:00:00 GMT</pubDate>
      <description>Self-sovereign identity sounds abstract. In NT², the practical version is simpler: your vault can prove itself, recover without a help desk, and share under your control while NT² stays blind.</description>
      <author>NT²</author>
      <category>trust</category>
      <category>identity</category>
    </item>
  </channel>
</rss>