<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: noxlie</title>
    <description>The latest articles on DEV Community by noxlie (@noxliehf).</description>
    <link>https://dev.to/noxliehf</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4011921%2Fc193b1bf-b8c9-4263-9da0-d501d3d1497e.png</url>
      <title>DEV Community: noxlie</title>
      <link>https://dev.to/noxliehf</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/noxliehf"/>
    <language>en</language>
    <item>
      <title>The Private AI Agent Stack Is Finally Complete — Here's Every Layer You Need</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Wed, 22 Jul 2026 04:05:01 +0000</pubDate>
      <link>https://dev.to/noxliehf/the-private-ai-agent-stack-is-finally-complete-heres-every-layer-you-need-4b5k</link>
      <guid>https://dev.to/noxliehf/the-private-ai-agent-stack-is-finally-complete-heres-every-layer-you-need-4b5k</guid>
      <description>&lt;p&gt;Every AI agent today leaks. Your prompts get logged. Your data gets scraped. Your payment history sits on a public ledger. You have no control over what the agent remembers, what the provider sees, or who subpoenas the logs later.&lt;/p&gt;

&lt;p&gt;That's the problem. The solution isn't choosing between TEEs, FHE, MPC, or zero-knowledge proofs. It's stacking all of them together.&lt;/p&gt;

&lt;p&gt;In 2026, the strongest privacy architectures don't pick one technology. They layer five distinct tools into a single pipeline. Each layer protects a different part of the stack. And the crypto layer handles the payments so nothing connects back to your identity.&lt;/p&gt;

&lt;p&gt;Here's the complete private AI agent stack — and why it matters right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 5-Layer Stack: Why One Technology Was Never Enough
&lt;/h2&gt;

&lt;p&gt;The Wavect team published a comparison in July 2026 that nailed it: "The strongest 2026 architectures stack these tools instead of choosing one: TEE for the bulk, cryptography for the core."&lt;/p&gt;

&lt;p&gt;That's the key insight. No single privacy technology covers all attack vectors. TEEs protect against cloud operators snooping on your computation. MPC distributes trust so no single party holds your secret. FHE lets the model process encrypted data without ever seeing plaintext. ZK proofs verify that the computation was done correctly. And crypto payments make sure nobody traces your subscription back to your wallet.&lt;/p&gt;

&lt;p&gt;Here's how each layer works in practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 1: TEEs — The Hardware Isolation Layer
&lt;/h2&gt;

&lt;p&gt;Trusted Execution Environments run your AI agent's code inside a hardware-encrypted vault. Even the cloud provider can't see what's happening inside the enclave.&lt;/p&gt;

&lt;p&gt;The May 2026 survey paper "When Agents Handle Secrets" (Forough, Kogias, Haddadi) mapped six TEE platforms onto agent security: Intel SGX, Intel TEE, AMD SEV-SNP, ARM TrustZone, ARM CCA, and NVIDIA H100 Confidential Compute. Each has different tradeoffs. AMD SEV-SNP gives you full VM isolation. Intel SGX gives you smaller, more auditable enclaves. NVIDIA H100 CC keeps GPU computation private.&lt;/p&gt;

&lt;p&gt;In production, Secret Network runs confidential smart contracts on TEEs. Oasis Network hosts agents like WT3 that execute trades inside enclaves. Phala Network offers confidential AI deployment with hardware-level guarantees.&lt;/p&gt;

&lt;p&gt;TEEs are fast. They add maybe 2-10% overhead for most AI workloads. But they have a weakness: you're trusting the hardware vendor. If Intel or AMD pushes a compromised microcode update, your enclave is toast. That's where the cryptographic layers come in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 2: MPC — The Distributed Trust Layer
&lt;/h2&gt;

&lt;p&gt;Multi-Party Computation splits your secret into shares across multiple nodes. No single node ever sees the full picture. To reconstruct the secret, you need a threshold of participants to cooperate.&lt;/p&gt;

&lt;p&gt;Nillion's architecture orchestrates MPC, homomorphic encryption, and ZK proofs depending on the computation requirements. Inco Network offers both TEE-fast and FHE+MPC-secure modes. Partisia Network handles multi-party private coordination.&lt;/p&gt;

&lt;p&gt;The crypto angle here is real: MPC is how privacy coins like Monero distribute trust across decoy addresses. The same principle applies to AI agents. Your agent's private key gets split across MPC nodes. No single compromised node can drain your wallet or read your conversation history.&lt;/p&gt;

&lt;p&gt;This layer is particularly important for key management. An AI agent that holds a crypto wallet needs to sign transactions without any single party having access to the full key. MPC solves that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 3: FHE — The Encrypted Computation Layer
&lt;/h2&gt;

&lt;p&gt;Fully Homomorphic Encryption lets you compute on encrypted data without decrypting it first. The model sees ciphertext. It does its work. The output is still encrypted. Only the data owner can decrypt the result.&lt;/p&gt;

&lt;p&gt;Zama's FHE compiler makes this practical for ML inference. Fhenix brings FHE to Ethereum smart contracts. Mind Network routes AI computations through FHE-encrypted channels.&lt;/p&gt;

&lt;p&gt;The catch: FHE is expensive. Running a simple LLM inference under FHE can be 1000-10000x slower than plaintext. That's why the hybrid architecture matters — you use FHE only for the small, high-stakes computations where you absolutely cannot trust the hardware (the TEE). For bulk token generation, TEEs are fine. For the specific computation that touches your health data or financial records, FHE is the insurance policy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 4: ZK Proofs — The Verification Layer
&lt;/h2&gt;

&lt;p&gt;Zero-knowledge proofs let you prove that a computation was done correctly without revealing the inputs. Your agent says "I ran this prompt through this model and got this output." ZK proofs let you verify that claim without seeing the prompt, the model weights, or the intermediate computation.&lt;/p&gt;

&lt;p&gt;EZKL compiles ML models into ZK circuits. Modulus Labs runs inference with on-chain proof verification. Giza produces ZK proofs for neural network computations. DeepProve-1 from Lagrange Labs handles multi-agent proof aggregation.&lt;/p&gt;

&lt;p&gt;The crypto-native angle: ZK proofs are what make DeFi trustless. You can prove you have enough collateral without revealing your balance. The same pattern applies to AI — prove your agent followed the rules without revealing what it was asked to do.&lt;/p&gt;

&lt;h2&gt;
  
  
  Layer 5: Crypto Payments — The Anonymous Rails Layer
&lt;/h2&gt;

&lt;p&gt;This is the layer most people overlook. Even if your AI inference is perfectly private, your payment creates a trail. A credit card purchase to OpenAI links your identity to every prompt you've ever sent.&lt;/p&gt;

&lt;p&gt;Crypto micropayments solve this. &lt;a href="https://dev.to/go/nanogpt"&gt;NanoGPT&lt;/a&gt; lets you pay for AI inference with stablecoins — no account required, no email, no identity verification. You send crypto, you get inference. The provider never knows who you are.&lt;/p&gt;

&lt;p&gt;For swapping between tokens without KYC, &lt;a href="https://dev.to/go/simpleswap"&gt;SimpleSwap&lt;/a&gt; handles the conversion privately. Monero provides additional obfuscation if you want the transaction itself untraceable.&lt;/p&gt;

&lt;p&gt;The x402 protocol (backed by Cloudflare and Shopify) enables machine-to-machine payments over HTTP. Your AI agent pays another AI agent directly. No middleman. No billing department. No paper trail.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means for Developers
&lt;/h2&gt;

&lt;p&gt;The stack is no longer theoretical. Every layer has production-ready tools running on mainnet today.&lt;/p&gt;

&lt;p&gt;If you're building an AI agent that handles sensitive data, you need at least three of these five layers. TEEs for speed. MPC for key management. ZK proofs for verification. FHE if the data is truly sensitive. Crypto payments if you care about payment privacy.&lt;/p&gt;

&lt;p&gt;The compositional approach — using different privacy technologies for different parts of the pipeline — is now the standard. Nillion pioneered this. Inco Network adopted it. The 2026 architectures all converge on the same pattern: hardware isolation for bulk work, cryptography for the core.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is a private AI agent stack?&lt;/strong&gt;&lt;br&gt;
A combination of five privacy technologies (TEEs, MPC, FHE, ZK proofs, and crypto payments) layered together to protect every stage of AI inference — from the prompt to the payment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I use just one privacy technology?&lt;/strong&gt;&lt;br&gt;
You can, but it leaves gaps. TEEs trust hardware vendors. MPC is slow for large models. FHE is expensive. ZK proofs verify but don't encrypt. Crypto payments don't protect the inference itself. Layering them covers each other's weaknesses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which tools are production-ready in 2026?&lt;/strong&gt;&lt;br&gt;
Secret Network and Oasis Network for TEEs. Nillion and Partisia for MPC. Zama and Fhenix for FHE. EZKL and Modulus Labs for ZK proofs. NanoGPT and x402 for anonymous payments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is this legal?&lt;/strong&gt;&lt;br&gt;
Private AI inference is legal everywhere. Privacy technologies are used by enterprises, governments, and individuals. The EU AI Act (August 2026) actually encourages privacy-preserving techniques. Blockchain-based audit trails can help demonstrate compliance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do I get started?&lt;/strong&gt;&lt;br&gt;
Start with NanoGPT (&lt;a href="https://dev.to/go/nanogpt"&gt;/go/nanogpt&lt;/a&gt;) for anonymous AI inference. Add TEE-based inference from Phala or Secret Network for production workloads. Use &lt;a href="https://dev.to/go/simpleswap"&gt;SimpleSwap&lt;/a&gt; for private token swaps. Explore the full range of tools at &lt;a href="https://ai-privacy-tools.vercel.app" rel="noopener noreferrer"&gt;ai-privacy-tools.vercel.app&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;The private AI agent stack is complete. Every layer is live. The question isn't whether these technologies work — it's whether you're using them. Start with &lt;a href="https://ai-privacy-tools.vercel.app" rel="noopener noreferrer"&gt;ai-privacy-tools.vercel.app&lt;/a&gt; and pick the layers that fit your threat model.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>crypto</category>
      <category>security</category>
    </item>
    <item>
      <title>Test Post</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Wed, 22 Jul 2026 04:04:33 +0000</pubDate>
      <link>https://dev.to/noxliehf/test-post-a3h</link>
      <guid>https://dev.to/noxliehf/test-post-a3h</guid>
      <description>&lt;p&gt;Test content&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>I Built a Self-Hosted AI Prompt Audit Logger in Python - Here's Every Line of Code</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Tue, 21 Jul 2026 10:06:13 +0000</pubDate>
      <link>https://dev.to/noxliehf/i-built-a-self-hosted-ai-prompt-audit-logger-in-python-heres-every-line-of-code-9nn</link>
      <guid>https://dev.to/noxliehf/i-built-a-self-hosted-ai-prompt-audit-logger-in-python-heres-every-line-of-code-9nn</guid>
      <description>&lt;p&gt;i run three different LLMs locally. Ollama for quick stuff, NanoGPT for longer tasks, and a small fine-tuned model for code completion. but here's the thing nobody talks about: just because the model runs locally doesn't mean your prompts are safe.&lt;/p&gt;

&lt;p&gt;every one of those tools has its own API endpoint, its own logging behavior, and its own idea of what "ephemeral" means. ollama keeps a request log by default. your web UI stores conversation history in sqlite. your reverse proxy writes access logs with full request bodies if you configured it wrong.&lt;/p&gt;

&lt;p&gt;i got tired of wondering where my prompts were ending up. so i built a middleware layer that sits between my tools and my models. every prompt goes through it. every response comes back through it. everything gets encrypted and stored locally, and i can search it whenever i want.&lt;/p&gt;

&lt;p&gt;here's the full build.&lt;/p&gt;

&lt;h2&gt;
  
  
  the architecture
&lt;/h2&gt;

&lt;p&gt;the idea is simple. instead of talking directly to ollama's API at &lt;code&gt;localhost:11434&lt;/code&gt;, my tools talk to my audit logger at &lt;code&gt;localhost:9400&lt;/code&gt;. the logger:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;receives the prompt and metadata&lt;/li&gt;
&lt;li&gt;encrypts it with a local key&lt;/li&gt;
&lt;li&gt;stores it in a sqlite database&lt;/li&gt;
&lt;li&gt;forwards the request to the actual LLM endpoint&lt;/li&gt;
&lt;li&gt;encrypts and stores the response&lt;/li&gt;
&lt;li&gt;returns the response to the client&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;the client never knows the difference. it just sees a normal openai-compatible API. the logger is invisible.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;┌──────────────┐     ┌──────────────────┐     ┌──────────────┐
│  your tools  │────▶│  audit logger    │────▶│  ollama      │
│  (openwebui, │     │  (localhost:9400) │     │  (11434)     │
│   scripts)   │◀────│  encrypts+stores  │◀────│              │
└──────────────┘     └──────────────────┘     └──────────────┘
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  the project structure
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ai-audit-logger/
├── main.py              # fastapi app
├── crypto.py            # encryption helpers
├── storage.py           # database layer
├── proxy.py             # forwarding logic
├── config.py            # settings
├── models.py            # pydantic schemas
├── search.py            # search endpoint
├── requirements.txt
└── docker-compose.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  config.py — keeping secrets out of code
&lt;/h2&gt;

&lt;p&gt;i use environment variables for everything sensitive. the encryption key gets derived from a passphrase you set once and never type again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;

&lt;span class="n"&gt;LLM_BASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LLM_BASE_URL&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://localhost:11434&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;LISTEN_HOST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LISTEN_HOST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;LISTEN_PORT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;int&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LISTEN_PORT&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;9400&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;DB_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;DB_PATH&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./audit.db&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;PASSPHRASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AUDIT_PASSPHRASE&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;change-me-before-deploying&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;LOG_DIR&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;LOG_DIR&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;./logs&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="n"&gt;LOG_DIR&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;mkdir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exist_ok&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the passphrase is the only secret. you set it as an env var or put it in a &lt;code&gt;.env&lt;/code&gt; file that never leaves your machine. i'll show how the key derivation works next.&lt;/p&gt;

&lt;h2&gt;
  
  
  crypto.py — encryption at rest
&lt;/h2&gt;

&lt;p&gt;i use &lt;code&gt;cryptography&lt;/code&gt;'s Fernet for symmetric encryption. it's fast, audited, and good enough for local storage. the key gets derived from your passphrase using PBKDF2 with 600k iterations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# crypto.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cryptography.fernet&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Fernet&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cryptography.hazmat.primitives&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;hashes&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;cryptography.hazmat.primitives.kdf.pbkdf2&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PBKDF2HMAC&lt;/span&gt;

&lt;span class="n"&gt;_SALT_FILE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.audit_salt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;_get_or_create_salt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_SALT_FILE&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_SALT_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urandom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_SALT_FILE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;wb&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;salt&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;derive_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passphrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;salt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;_get_or_create_salt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;kdf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PBKDF2HMAC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;algorithm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;hashes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;SHA256&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;32&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;salt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;600_000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;base64&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;urlsafe_b64encode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;kdf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;derive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;passphrase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;()))&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Fernet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plaintext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;encode&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Fernet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ciphertext&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the salt gets generated once and stored in a file. if you lose the salt, you lose your data. that's the tradeoff. i back up the salt file alongside my database.&lt;/p&gt;

&lt;h2&gt;
  
  
  models.py — what we track
&lt;/h2&gt;

&lt;p&gt;every logged request includes metadata that most people never think about. which tool sent the prompt, what model was targeted, how long it took, and whether the response was streamed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# models.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pydantic&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;BaseModel&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;typing&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ChatCompletionRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ChatMessage&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.7&lt;/span&gt;
    &lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;  &lt;span class="c1"&gt;# which tool sent this
&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AuditEntry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;BaseModel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nb"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Optional&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;source_ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;
    &lt;span class="n"&gt;prompt_encrypted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;
    &lt;span class="n"&gt;response_encrypted&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bytes&lt;/span&gt;
    &lt;span class="n"&gt;duration_ms&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt;
    &lt;span class="n"&gt;tokens_prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;tokens_response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;
    &lt;span class="n"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;bool&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;i log the user agent and source IP so i can tell which tool sent the prompt. if open webui sends something vs. a python script, i want to know.&lt;/p&gt;

&lt;h2&gt;
  
  
  storage.py — sqlite with encrypted fields
&lt;/h2&gt;

&lt;p&gt;sqlite because it's zero-config and lives in a single file i can back up with a simple &lt;code&gt;cp&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# storage.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DB_PATH&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Connection&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;sqlite3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DB_PATH&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        CREATE TABLE IF NOT EXISTS audit_log (
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            timestamp REAL NOT NULL,
            model TEXT NOT NULL,
            user_agent TEXT,
            source_ip TEXT,
            prompt_encrypted BLOB NOT NULL,
            response_encrypted BLOB NOT NULL,
            duration_ms REAL,
            tokens_prompt INTEGER DEFAULT 0,
            tokens_response INTEGER DEFAULT 0,
            stream BOOLEAN DEFAULT 0
        )
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        CREATE INDEX IF NOT EXISTS idx_timestamp ON audit_log(timestamp)
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        CREATE INDEX IF NOT EXISTS idx_model ON audit_log(model)
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;store_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        INSERT INTO audit_log
        (timestamp, model, user_agent, source_ip, prompt_encrypted,
         response_encrypted, duration_ms, tokens_prompt, tokens_response, stream)
        VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
    &lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;source_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prompt_encrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response_encrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;duration_ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tokens_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tokens_response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;stream&lt;/span&gt;
    &lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the prompt and response are stored as encrypted blobs. anyone who opens the sqlite file just sees random bytes. they need the passphrase to read anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  proxy.py — the forwarding logic
&lt;/h2&gt;

&lt;p&gt;this is the core. it receives the openai-compatible request, logs it, forwards to the real endpoint, logs the response, and sends it back.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# proxy.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatCompletionRequest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;crypto&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;encrypt&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;store_entry&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LLM_BASE_URL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PASSPHRASE&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LOG_DIR&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pathlib&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Path&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;

&lt;span class="n"&gt;_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_key&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;global&lt;/span&gt; &lt;span class="n"&gt;_key&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;_key&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;crypto&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;derive_key&lt;/span&gt;
        &lt;span class="n"&gt;_key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;derive_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSPHRASE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_key&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;forward_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ChatCompletionRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;source_ip&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_key&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="c1"&gt;# encrypt the prompt before forwarding
&lt;/span&gt;    &lt;span class="n"&gt;prompt_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model_dump&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;prompt_encrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prompt_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# forward to the real LLM
&lt;/span&gt;    &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;messages&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;model_dump&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;temperature&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;temperature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# handle streaming separately
&lt;/span&gt;    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_tokens&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;max_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;max_tokens&lt;/span&gt;

    &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;httpx&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;AsyncClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;resp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;LLM_BASE_URL&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/v1/chat/completions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;duration_ms&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;

    &lt;span class="c1"&gt;# encrypt the response
&lt;/span&gt;    &lt;span class="n"&gt;response_text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure_ascii&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;response_encrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;encrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response_text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# count tokens (rough estimate from response)
&lt;/span&gt;    &lt;span class="n"&gt;usage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;usage&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;tokens_prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;tokens_response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;usage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;completion_tokens&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source_ip&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;source_ip&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt_encrypted&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt_encrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response_encrypted&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response_encrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;duration_ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;duration_ms&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tokens_prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tokens_prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tokens_response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;tokens_response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;stream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# store in database
&lt;/span&gt;    &lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;store_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# also write a human-readable log line (no content, just metadata)
&lt;/span&gt;    &lt;span class="n"&gt;log_line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;[&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d %H&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;M&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="n"&gt;S&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;] &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;duration=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;duration_ms&lt;/span&gt;&lt;span class="si"&gt;:&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;ms &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tokens=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tokens_prompt&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;+&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;tokens_response&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;source=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;log_file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LOG_DIR&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;strftime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%Y-%m-%d&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;.log&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;log_file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;log_line&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;notice the human-readable log line at the bottom. it stores metadata only, no prompt content. i can quickly check "what models ran today" without decrypting anything.&lt;/p&gt;

&lt;h2&gt;
  
  
  main.py — the fastapi app
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# main.py
&lt;/span&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;fastapi.responses&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;StreamingResponse&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;ChatCompletionRequest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;proxy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;forward_request&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;get_db&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;crypto&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;get_key&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LISTEN_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;LISTEN_PORT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;PASSPHRASE&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;crypto&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;derive_key&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt;

&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;AI Audit Logger&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/v1/chat/completions&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;chat_completions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;req&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatCompletionRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;user_agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;source_ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;host&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;unknown&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;forward_request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;source_ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/v1/audit/search&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_prompts&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;derive_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PASSPHRASE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT * FROM audit_log WHERE 1=1&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; AND model = ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt; ORDER BY timestamp DESC LIMIT ? OFFSET ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

    &lt;span class="n"&gt;rows&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;rows&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;prompt_decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;response_decrypted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;decrypt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="c1"&gt;# if search query provided, filter
&lt;/span&gt;        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;q&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;prompt_decrypted&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lower&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;

        &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timestamp&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user_agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;duration_ms&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;row&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prompt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;prompt_decrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;response&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;response_decrypted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;results&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/v1/audit/stats&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;audit_stats&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="n"&gt;conn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_db&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT COUNT(*) FROM audit_log&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="n"&gt;models&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT model, COUNT(*) as cnt FROM audit_log GROUP BY model ORDER BY cnt DESC&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;today&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;conn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SELECT COUNT(*) FROM audit_log WHERE timestamp &amp;gt; ?&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;86400&lt;/span&gt;&lt;span class="p"&gt;,)&lt;/span&gt;
    &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fetchone&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;total_logged&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;today&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;today&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;models&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;model&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;count&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;models&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nd"&gt;@app.get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/health&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;health&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ok&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;uvicorn&lt;/span&gt;
    &lt;span class="n"&gt;uvicorn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;host&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;LISTEN_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;LISTEN_PORT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the search endpoint decrypts entries on the fly. it's not fast for large datasets, but for personal use with a few thousand entries, it's instant. the stats endpoint gives you a quick overview without touching encrypted data.&lt;/p&gt;

&lt;h2&gt;
  
  
  docker-compose.yml — running it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# docker-compose.yml&lt;/span&gt;
&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3.8"&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;audit-logger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;127.0.0.1:9400:9400"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;LLM_BASE_URL=http://host.docker.internal:11434&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;AUDIT_PASSPHRASE=${AUDIT_PASSPHRASE}&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DB_PATH=/data/audit.db&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./data:/data&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./logs:/app/logs&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;bind to localhost only. never expose this to a network. the audit logger has your decrypted prompts in memory and the encryption key loaded. it should never be reachable from outside your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  the requirements.txt
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fastapi==0.115.0
uvicorn==0.30.0
httpx==0.27.0
cryptography==43.0.0
pydantic==2.9.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;five dependencies. that's it. no heavy ML libraries, no database drivers, no ORM. sqlite is built into python.&lt;/p&gt;

&lt;h2&gt;
  
  
  how to use it
&lt;/h2&gt;

&lt;p&gt;start the logger first, then point your tools at it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# start the audit logger&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;ai-audit-logger
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;AUDIT_PASSPHRASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"your-secret-passphrase"&lt;/span&gt;
docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;

&lt;span class="c"&gt;# point ollama-compatible tools at it&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OLLAMA_BASE_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:9400/v1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now when you use open webui, any python script, or any tool that talks to an openai-compatible API, everything goes through the logger first.&lt;/p&gt;

&lt;p&gt;to search your prompts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://localhost:9400/v1/audit/search?q=medical&amp;amp;limit=10"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to see stats:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"http://localhost:9400/v1/audit/stats"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  what i learned building this
&lt;/h2&gt;

&lt;p&gt;the biggest surprise was how many tools silently log your prompts. ollama writes to its own log files. open webui stores everything in its sqlite database. even curl writes to your shell history. the audit logger doesn't solve the shell history problem, but it gives you one place to look instead of five.&lt;/p&gt;

&lt;p&gt;the encryption overhead is negligible. i benchmarked 10k encrypt/decrypt cycles and it added maybe 2ms per request. for a local tool that's nothing.&lt;/p&gt;

&lt;p&gt;the real value is the search. when i'm debugging a model's behavior on a specific prompt from three weeks ago, i can just query it. no more scrolling through web UI history or grepping log files.&lt;/p&gt;

&lt;p&gt;if you want to see more privacy-focused tools and self-hosted setups, i keep a running list at &lt;a href="https://ai-privacy-tools.vercel.app/" rel="noopener noreferrer"&gt;ai-privacy-tools.vercel.app&lt;/a&gt; with honest reviews of what actually works. i update it whenever i find something worth recommending or something that turned out to be garbage.&lt;/p&gt;

&lt;p&gt;the full code for this project is meant to be copied, modified, and run on your own hardware. the encryption is real, the storage is local, and nothing leaves your machine. that's the whole point.&lt;/p&gt;

</description>
      <category>showdev</category>
      <category>python</category>
      <category>selfhosted</category>
      <category>privacyengineering</category>
    </item>
    <item>
      <title>Zero-Knowledge Proofs Just Became AI's Privacy Shield — Here's What You Need to Know</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Tue, 21 Jul 2026 04:03:06 +0000</pubDate>
      <link>https://dev.to/noxliehf/zero-knowledge-proofs-just-became-ais-privacy-shield-heres-what-you-need-to-know-6hb</link>
      <guid>https://dev.to/noxliehf/zero-knowledge-proofs-just-became-ais-privacy-shield-heres-what-you-need-to-know-6hb</guid>
      <description>&lt;p&gt;Your prompts are being logged. Your medical records are being fed to AI models. Your financial data is training the next big LLM. Nobody asked your permission.&lt;/p&gt;

&lt;p&gt;This isn't a hypothetical scenario. It's happening right now. Every time you paste something into ChatGPT, every time you upload a document to an AI tool, that data enters a pipeline you can't see and can't control.&lt;/p&gt;

&lt;p&gt;But there's a cryptographic weapon fighting back: &lt;strong&gt;Zero-Knowledge Proofs (ZKPs)&lt;/strong&gt;. And in 2025-2026, they just went from "academic curiosity" to "production-ready."&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Wants to Talk About
&lt;/h2&gt;

&lt;p&gt;AI needs data. Lots of it. The bigger the dataset, the better the model. That creates a brutal tension — the same data that powers breakthrough AI also happens to be your most sensitive information.&lt;/p&gt;

&lt;p&gt;Think about what you've already shared with AI tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Medical symptoms you Googled and then pasted into a diagnostic tool&lt;/li&gt;
&lt;li&gt;Financial documents you uploaded for "analysis"&lt;/li&gt;
&lt;li&gt;Business strategies you brainstormed with an AI assistant&lt;/li&gt;
&lt;li&gt;Personal conversations with therapy chatbots&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Every single one of those interactions creates a data trail. And in most cases, the company running the AI sees everything.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The core problem:&lt;/strong&gt; AI inference requires sending your data to someone else's computer. Traditional encryption protects data in transit, but the moment it arrives at the AI server, the encryption ends and your privacy evaporates.&lt;/p&gt;

&lt;p&gt;Zero-knowledge proofs solve this by letting you prove something is true without revealing the underlying data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How ZKPs Actually Work (Without the Math PhD)
&lt;/h2&gt;

&lt;p&gt;Imagine you want to prove you're over 18 without showing your birth date. A ZKP lets you generate a mathematical proof that says "yes, I'm 18+" without revealing the actual date. The verifier learns the fact but nothing else.&lt;/p&gt;

&lt;p&gt;Now apply that to AI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You send encrypted data to an AI model&lt;/li&gt;
&lt;li&gt;The model runs inference on your data&lt;/li&gt;
&lt;li&gt;A ZKP proves the inference was done correctly&lt;/li&gt;
&lt;li&gt;You get the result&lt;/li&gt;
&lt;li&gt;Nobody — not even the AI provider — ever saw your raw data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is called &lt;strong&gt;zkML&lt;/strong&gt; (Zero-Knowledge Machine Learning). And it's no longer theoretical.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Changed in 2025-2026
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Lagrange Labs Shipped DeepProve-1
&lt;/h3&gt;

&lt;p&gt;March 2026. Lagrange Labs released DeepProve-1 — the first production zkML system that generates cryptographic proofs over a full LLM inference. Not a toy model. A real GPT-2 scale inference with a verifiable proof attached.&lt;/p&gt;

&lt;p&gt;This means you can now run an AI model and cryptographically prove to anyone that the output was produced by that specific model, without revealing what the input was.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cysic Launched Verifiable Multi-Agent Swarms
&lt;/h3&gt;

&lt;p&gt;Also in 2026, Cysic deployed the first verifiable multi-agent swarms on mainnet. Multiple AI agents working together, each producing ZKPs for their computations. No single agent sees the full picture. The proofs tie everything together.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decentralized Identity Gets ZKP Integration
&lt;/h3&gt;

&lt;p&gt;Researchers published a framework integrating Decentralized Identifiers (DIDs) and Verifiable Credentials (VCs) with efficient ZKP schemes. The result: you can prove you have a valid credential, a license, or an identity attribute without exposing the credential itself.&lt;/p&gt;

&lt;p&gt;This isn't theoretical — it's being tested in production DeFi applications right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Tools You Can Use Today
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Private AI Inference
&lt;/h3&gt;

&lt;p&gt;Tools like &lt;a href="https://dev.to/go/nanogpt"&gt;NanoGPT&lt;/a&gt; let you run GPT models locally. No data leaves your machine. Combined with zkML frameworks, you get verifiable, private inference without trusting a third party.&lt;/p&gt;

&lt;p&gt;For anyone handling sensitive data — healthcare, finance, legal — this isn't optional anymore. It's a compliance requirement.&lt;/p&gt;

&lt;h3&gt;
  
  
  Private Crypto Swaps
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dev.to/go/simpleswap"&gt;SimpleSwap&lt;/a&gt; offers non-custodial exchanges where you swap crypto without KYC requirements. Your financial activity stays private. No centralized order book tracking your every move.&lt;/p&gt;

&lt;h3&gt;
  
  
  Self-Hosted AI Stacks
&lt;/h3&gt;

&lt;p&gt;The privacy stack of 2026 looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Local inference&lt;/strong&gt; (run models on your hardware)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ZKP verification&lt;/strong&gt; (prove the output is correct)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decentralized storage&lt;/strong&gt; (keep data off corporate servers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private transactions&lt;/strong&gt; (swap and pay without exposing identity)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each layer addresses a different privacy vector. Together, they create a system where AI works for you — not the other way around.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters for Everyone
&lt;/h2&gt;

&lt;p&gt;You don't need to be a cryptographer to benefit from ZKPs. Here's what changes in practical terms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Healthcare AI&lt;/strong&gt; can analyze your medical data without the hospital seeing it&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Financial AI&lt;/strong&gt; can optimize your portfolio without your bank knowing your strategy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Legal AI&lt;/strong&gt; can review sensitive documents without the provider accessing the content&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personal AI&lt;/strong&gt; can remember your preferences without creating a surveillance profile&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The common thread: &lt;strong&gt;you control what gets revealed.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Adoption Curve
&lt;/h2&gt;

&lt;p&gt;ZKPs went from 0 to 100 fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;2024:&lt;/strong&gt; Mostly academic papers and testnets&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2025:&lt;/strong&gt; Production ZK-rollups on Ethereum, early zkML prototypes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2026:&lt;/strong&gt; Production LLM-scale proofs, verifiable agent swarms, DID integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The technology is maturing faster than most people realize. Projects like &lt;a href="https://ai-privacy-tools.vercel.app" rel="noopener noreferrer"&gt;ai-privacy-tools.vercel.app&lt;/a&gt; track the tools and platforms making this accessible to non-crypto-natives.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Coming Next
&lt;/h2&gt;

&lt;p&gt;Three trends to watch:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. ZKP-Powered AI Marketplaces&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine an AI marketplace where you pay for inference with crypto, the model runs on decentralized hardware, and a ZKP proves the computation was correct. No central authority. No data harvesting. Just math.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Regulatory Pressure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The EU AI Act and similar regulations are starting to demand verifiable AI processes. ZKPs provide exactly the kind of cryptographic audit trail regulators want — without exposing the underlying data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Consumer Wallets Go Private&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Crypto wallets are adding ZKP features that let users transact without revealing balances or transaction history. When AI agents start managing wallets autonomously, privacy becomes non-negotiable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;Zero-knowledge proofs aren't just a crypto buzzword anymore. They're the foundation of a new privacy architecture for AI.&lt;/p&gt;

&lt;p&gt;The tools exist. The infrastructure is live. The regulatory pressure is building.&lt;/p&gt;

&lt;p&gt;If you're using AI for anything sensitive — and in 2026, who isn't? — you need to understand ZKPs. Not the math. The practical reality: &lt;strong&gt;you can now verify AI outputs without exposing your data.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That changes everything.&lt;/p&gt;




&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can zero-knowledge proofs really hide my data from AI providers?
&lt;/h3&gt;

&lt;p&gt;Yes. ZKPs let you prove a computation happened correctly without revealing the inputs. The AI provider processes encrypted data, generates a proof, and you verify it. They never see the plaintext.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are ZKPs fast enough for real-time AI?
&lt;/h3&gt;

&lt;p&gt;Getting there. Lagrange's DeepProve-1 proves GPT-2 inference. Full-scale GPT-4 equivalent proofs are still computationally expensive, but the trajectory is clear — each generation gets 10-100x faster.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I use private AI tools today?
&lt;/h3&gt;

&lt;p&gt;Start with local inference tools like &lt;a href="https://dev.to/go/nanogpt"&gt;NanoGPT&lt;/a&gt; to keep data on your machine. For crypto transactions, use &lt;a href="https://dev.to/go/simpleswap"&gt;SimpleSwap&lt;/a&gt; for non-custodial swaps. Check &lt;a href="https://ai-privacy-tools.vercel.app" rel="noopener noreferrer"&gt;ai-privacy-tools.vercel.app&lt;/a&gt; for the latest tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need to understand cryptography to use ZKPs?
&lt;/h3&gt;

&lt;p&gt;No. You don't need to understand RSA to use HTTPS. ZKP tools are becoming abstracted behind simple interfaces. The complexity lives in the protocol, not the user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Are zero-knowledge proofs legal?
&lt;/h3&gt;

&lt;p&gt;ZKPs themselves are legal everywhere. What you do with them — private transactions, anonymous identity — may have different regulatory treatment depending on jurisdiction. Always check local regulations.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want to stay ahead of the privacy curve? Visit &lt;a href="https://ai-privacy-tools.vercel.app" rel="noopener noreferrer"&gt;ai-privacy-tools.vercel.app&lt;/a&gt; for curated tools, guides, and deep dives into the AI privacy revolution.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>crypto</category>
      <category>zeroknowledge</category>
    </item>
    <item>
      <title>The EU AI Act Hits August 2026 — Here's Why Blockchain Is the Only Way to Prove Your AI Is Clean</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Mon, 20 Jul 2026 04:05:03 +0000</pubDate>
      <link>https://dev.to/noxliehf/the-eu-ai-act-hits-august-2026-heres-why-blockchain-is-the-only-way-to-prove-your-ai-is-clean-3ck4</link>
      <guid>https://dev.to/noxliehf/the-eu-ai-act-hits-august-2026-heres-why-blockchain-is-the-only-way-to-prove-your-ai-is-clean-3ck4</guid>
      <description>&lt;p&gt;The European Union's AI Act enforcement kicks in on August 2, 2026. That's not a distant deadline — it's two weeks away. Companies running "high-risk" AI systems face fines up to €35 million or 7% of global revenue. The catch? Most companies have zero provable audit trail for how their AI makes decisions.&lt;/p&gt;

&lt;p&gt;Server logs get deleted. SQL databases get tampered with. Internal compliance reports are just PDFs that nobody verifies. The EU doesn't trust any of that. And honestly, neither should you.&lt;/p&gt;

&lt;p&gt;This is where blockchain enters the picture — not as a crypto speculation play, but as the only infrastructure that can produce mathematically verifiable, tamper-proof evidence that your AI actually followed the rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the EU AI Act Actually Requires
&lt;/h2&gt;

&lt;p&gt;The regulation splits AI systems into risk categories. High-risk systems — credit scoring, hiring algorithms, medical diagnostics, law enforcement tools — face the strictest obligations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Data governance&lt;/strong&gt;: You must prove your training data was collected legally, labeled correctly, and bias-tested.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transparency&lt;/strong&gt;: Users must be informed they're interacting with AI. Decision logic must be documented.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human oversight&lt;/strong&gt;: There must be a human-in-the-loop mechanism for high-stakes decisions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Logging&lt;/strong&gt;: Every inference (every time the AI makes a decision) must be logged in a way that allows post-hoc auditing.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last requirement is the one that breaks most companies. Logging an inference once is easy. Proving that log wasn't altered later? That's a completely different problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Server Logs Fail
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth about traditional audit logging. A company stores inference logs in its own database. An auditor asks for evidence. The company pulls logs from its own servers. The auditor has to trust that the company didn't alter those logs after the fact.&lt;/p&gt;

&lt;p&gt;That's not verification. That's faith-based compliance.&lt;/p&gt;

&lt;p&gt;The EU AI Act doesn't explicitly mandate blockchain — but it demands "technical documentation" and "logging capabilities" that are robust enough for independent audit. When a regulator asks "prove your loan-approval AI didn't discriminate based on zip code," and your evidence is a PostgreSQL table that only you control, you're in trouble.&lt;/p&gt;

&lt;h2&gt;
  
  
  Blockchain as a Compliance Layer
&lt;/h2&gt;

&lt;p&gt;The fix is straightforward: anchor your AI inference logs to an immutable ledger. Every time your model makes a high-stakes decision, you:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Generate a cryptographic hash of the input data, model version, and output.&lt;/li&gt;
&lt;li&gt;Timestamp it on-chain (Ethereum, a rollup, or a purpose-built chain).&lt;/li&gt;
&lt;li&gt;Store the full data off-chain but keep the hash on-chain as a proof anchor.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now when an auditor asks "did this decision actually happen, and was the model unchanged?" you hand them a transaction hash. They verify it independently. No trust required.&lt;/p&gt;

&lt;p&gt;This isn't theoretical. VeritasChain (veritaschain.org) has shipped exactly this — an open standard that replaces opaque server logs with mathematically verifiable on-chain evidence, designed to meet both EU AI Act and MiFID II transparency requirements.&lt;/p&gt;

&lt;h2&gt;
  
  
  ERC-8004: Giving AI Agents Real Identity
&lt;/h2&gt;

&lt;p&gt;There's a second layer to this problem that most people miss. The EU AI Act requires you to know &lt;em&gt;which&lt;/em&gt; AI system made a decision. In 2026, AI agents operate autonomously across multiple services. One agent might route through five different models before producing a final answer. Which one is responsible?&lt;/p&gt;

&lt;p&gt;ERC-8004 — Ethereum's "Trustless Agents" standard — launched on mainnet in January 2026. It gives AI agents permanent on-chain identities through three registries: Identity, Reputation, and Validation. Within 30 days of launch, over 45,000 AI agents had registered.&lt;/p&gt;

&lt;p&gt;Why does this matter for EU AI Act compliance? Because you can now trace exactly which agent made which decision, with cryptographic proof of identity. No more "the AI did it" as a defense. The agent is accountable, and the chain proves it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Setup: What You Actually Need
&lt;/h2&gt;

&lt;p&gt;Here's what a compliance-ready architecture looks like in 2026:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For logging&lt;/strong&gt;: Hash every inference (input + model version + output + timestamp) and anchor to Ethereum L2. Arbitrum (arbitrum.io) and Base (base.org) are the cheapest options — roughly $0.01 per proof anchor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For identity&lt;/strong&gt;: Register your AI agents on ERC-8004. This creates an auditable chain of custody for every decision.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For privacy&lt;/strong&gt;: You don't want to expose sensitive training data on-chain. Use zero-knowledge proofs to prove the data was handled correctly without revealing the data itself. Tools like EZKL (ezkl.xyz) let you prove model inference was performed correctly without exposing the model or the data.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For payments&lt;/strong&gt;: If your AI agents need to pay for compute or services, use privacy-preserving payment rails. NanoGPT (nanogpt.com) accepts crypto payments for AI inference without requiring KYC — useful for agents that need to operate without exposing their operators' identities.&lt;/p&gt;

&lt;p&gt;The full stack: ZK proofs for data privacy + ERC-8004 for agent identity + on-chain anchoring for audit trails. That's your EU AI Act compliance shield.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Compliance Deadline Is Real
&lt;/h2&gt;

&lt;p&gt;August 2, 2026. That's the date when the EU AI Act's obligations for high-risk systems become enforceable. Penalties start immediately — there's no grace period.&lt;/p&gt;

&lt;p&gt;If you're building AI that touches healthcare, finance, hiring, law enforcement, or critical infrastructure in the EU market, you need audit-grade logging &lt;em&gt;now&lt;/em&gt;. Not next quarter. Not when the regulator knocks. Now.&lt;/p&gt;

&lt;p&gt;Blockchain isn't a silver bullet. It won't fix biased training data or poorly designed models. But it solves the one problem that every other tool can't: proving your compliance actually happened, in a way that no one — not even you — can undo.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting Started
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Audit your AI systems&lt;/strong&gt;: Identify which ones fall under the EU AI Act's high-risk categories.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement hash anchoring&lt;/strong&gt;: Start logging inference hashes to an L2 chain. Cost is negligible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Register agents on ERC-8004&lt;/strong&gt;: If you're running autonomous AI agents, give them on-chain identity.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Add ZK proofs&lt;/strong&gt;: For sensitive data, layer zero-knowledge proofs over your audit trail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check ai-privacy-tools.vercel.app&lt;/strong&gt;: Compare privacy-preserving AI tools and compliance-ready infrastructure.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The companies that treat this as a compliance checkbox will scramble. The ones that build cryptographic audit trails now will have a permanent competitive advantage — provable trust that customers and regulators can verify independently.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does the EU AI Act require blockchain specifically?&lt;/strong&gt;&lt;br&gt;
No. The Act mandates "technical documentation" and "logging capabilities" sufficient for independent audit. Blockchain happens to be the most practical way to achieve tamper-proof logging. Regulators don't care about the technology — they care about the evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much does on-chain audit logging cost?&lt;/strong&gt;&lt;br&gt;
On Ethereum L2s like Arbitrum or Base, anchoring a hash costs roughly $0.01-$0.05 per inference. For a system making 10,000 decisions per day, that's $100-$500/month. A rounding error compared to potential fines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What about data privacy — can I put AI inference logs on-chain?&lt;/strong&gt;&lt;br&gt;
You anchor the &lt;em&gt;hash&lt;/em&gt;, not the data. The full inference data stays off-chain. The hash proves the data existed and was unchanged at that point in time, without revealing any content. Zero-knowledge proofs can further verify compliance without exposing inputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does ERC-8004 work with non-Ethereum blockchains?&lt;/strong&gt;&lt;br&gt;
ERC-8004 is an Ethereum standard, but the concept of on-chain agent identity is spreading. 0G, Solana, and other chains are implementing compatible identity registries. The standard itself is chain-agnostic in principle — the registry contracts are what matter.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What happens if I don't comply by August 2026?&lt;/strong&gt;&lt;br&gt;
Fines up to €35 million or 7% of global annual turnover, whichever is higher. The EU has also indicated it will prioritize enforcement against companies in high-risk sectors (finance, healthcare, law enforcement). There's no "we'll figure it out later" option.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Explore privacy-preserving AI tools at &lt;a href="https://ai-privacy-tools.vercel.app" rel="noopener noreferrer"&gt;ai-privacy-tools.vercel.app&lt;/a&gt;. Pay for AI anonymously with crypto at &lt;a href="https://ai-privacy-tools.vercel.app/go/nanogpt" rel="noopener noreferrer"&gt;NanoGPT&lt;/a&gt;. Swap privacy tokens at &lt;a href="https://ai-privacy-tools.vercel.app/go/simpleswap" rel="noopener noreferrer"&gt;SimpleSwap&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>crypto</category>
      <category>regulation</category>
    </item>
    <item>
      <title>You Can Now Pay for AI With Crypto and Leave Zero Trace</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Sun, 19 Jul 2026 04:03:10 +0000</pubDate>
      <link>https://dev.to/noxliehf/you-can-now-pay-for-ai-with-crypto-and-leave-zero-trace-2ff8</link>
      <guid>https://dev.to/noxliehf/you-can-now-pay-for-ai-with-crypto-and-leave-zero-trace-2ff8</guid>
      <description>&lt;p&gt;You talk to AI every day. You ask it things you would never Google. Medical questions. Legal questions. Business strategy. Personal stuff.&lt;/p&gt;

&lt;p&gt;Every single one of those prompts gets logged, stored, and linked to your account. OpenAI, Anthropic, Google — they all keep records. Your name, your email, your payment method, every conversation.&lt;/p&gt;

&lt;p&gt;But what if you could pay for AI inference with crypto, get your answer, and leave zero record of who asked?&lt;/p&gt;

&lt;p&gt;This is not hypothetical. The infrastructure exists right now.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody Talks About
&lt;/h2&gt;

&lt;p&gt;AI assistants are the most intimate technology most people use. You share more with ChatGPT than with your therapist. And unlike your therapist, there is no confidentiality obligation.&lt;/p&gt;

&lt;p&gt;The data trail looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Identity&lt;/strong&gt;: Your email, phone number, payment card&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content&lt;/strong&gt;: Every prompt and response, stored indefinitely&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavioral fingerprint&lt;/strong&gt;: Usage patterns, topics, writing style&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-party leaks&lt;/strong&gt;: API integrations, plugin data, shared conversations&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Even if you trust OpenAI today, data breaches happen. Subpoenas happen. Acquisitions happen. The company that owns your data tomorrow might not share today's privacy values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Crypto Payments Break the Identity Chain
&lt;/h2&gt;

&lt;p&gt;The key insight is simple: if you pay with a credit card, you are identified. If you pay with crypto, you are pseudonymous. If you pay with privacy-focused crypto, you are anonymous.&lt;/p&gt;

&lt;p&gt;Three layers of payment privacy exist today:&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 1: Stablecoin Micropayments (Low Friction)
&lt;/h3&gt;

&lt;p&gt;USDC and USDT on L2 chains (Base, Polygon, Arbitrum) cost fractions of a cent per transaction. Services like NanoGPT accept stablecoin payments for API access to frontier models.&lt;/p&gt;

&lt;p&gt;The trade-off: stablecoin transactions are pseudonymous, not anonymous. The wallet address is visible on-chain. But unless you link that wallet to your identity, it stays pseudonymous.&lt;/p&gt;

&lt;p&gt;For most people, this is enough. Your employer cannot subpoena your crypto wallet to see what you asked an AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 2: Privacy Coins (Stronger Guarantees)
&lt;/h3&gt;

&lt;p&gt;Monero uses ring signatures, stealth addresses, and RingCT to obscure sender, receiver, and amount. Zcash offers shielded transactions with zero-knowledge proofs.&lt;/p&gt;

&lt;p&gt;If you route payments through these networks, even blockchain analysts cannot trace the transaction. Some AI services already accept Monero for inference credits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer 3: x402 Protocol (The Future Is Here)
&lt;/h3&gt;

&lt;p&gt;This is the big one. &lt;a href="https://www.x402.org/" rel="noopener noreferrer"&gt;x402&lt;/a&gt; is an open protocol that lets HTTP clients pay for resources per-request using stablecoins. No accounts. No API keys. No login.&lt;/p&gt;

&lt;p&gt;Here is how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Your client sends a request to an AI endpoint&lt;/li&gt;
&lt;li&gt;The server responds with a 402 Payment Required and a price&lt;/li&gt;
&lt;li&gt;Your client signs a micropayment with a crypto wallet&lt;/li&gt;
&lt;li&gt;The server verifies payment and returns the AI response&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Zero accounts. Zero logs tied to identity. The payment is the authentication.&lt;/p&gt;

&lt;p&gt;Cloudflare, Coinbase, and AWS are building x402 support. When this becomes standard, every API endpoint can become a pay-per-use service with no identity requirement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Private AI Inference Already Works
&lt;/h2&gt;

&lt;p&gt;This is not a roadmap slide. These services exist today.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NanoGPT&lt;/strong&gt; accepts crypto payments for access to GPT-4, Claude, and other frontier models. No account needed beyond a wallet. Prompts are not stored. &lt;a href="https://ai-privacy-tools.vercel.app/go/nanogpt" rel="noopener noreferrer"&gt;Try it here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Venice AI&lt;/strong&gt; runs inference on decentralized infrastructure with no logging. Access requires a crypto payment. The architecture ensures your prompts never touch a centralized database.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Oasis Protocol&lt;/strong&gt; uses Trusted Execution Environments (TEEs) to process AI inference in hardware-isolated enclaves. The compute provider literally cannot see your data, even if they wanted to.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Morpheus&lt;/strong&gt; is building a decentralized AI network where local compute nodes process requests. Payments flow through smart contracts. No central server ever sees your prompt in plaintext.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Set Up Anonymous AI Access in 10 Minutes
&lt;/h2&gt;

&lt;p&gt;You do not need to be a developer. Here is the practical setup:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Get a clean crypto wallet&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Download a non-custodial wallet. MetaMask for EVM chains, or Cake Wallet for Monero. Do not fund it from an exchange that has your KYC data. Use a peer-to-peer purchase or a no-KYC exchange.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Get some crypto&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For USDC on Base: peer-to-peer purchase, or bridge from another chain. For Monero: trade on a no-KYC platform. The goal is no link between your real identity and this wallet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Use a privacy-focused AI service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;NanoGPT is the easiest entry point. Connect your wallet, pay per prompt, get your response. No email, no account, no logs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Layer your privacy&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For maximum protection: use a VPN or Tor when accessing the service. This prevents IP-based correlation even if the service tried to log connections.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Economics Actually Work
&lt;/h2&gt;

&lt;p&gt;Private AI inference sounds expensive. It is not.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GPT-4-level inference via NanoGPT: roughly /usr/bin/bash.01-0.03 per query&lt;/li&gt;
&lt;li&gt;Monero transaction fee: under /usr/bin/bash.01&lt;/li&gt;
&lt;li&gt;VPN cost: -5/month for unlimited use&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total cost for a private AI conversation: under /usr/bin/bash.05. That is less than a text message.&lt;/p&gt;

&lt;p&gt;Compare this to the cost of your AI usage data being linked to your identity forever. For anyone asking sensitive questions — doctors, lawyers, business owners, journalists, activists — this is not a luxury. It is operational security.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Means for the AI Industry
&lt;/h2&gt;

&lt;p&gt;The shift to crypto-paid private AI changes the power dynamics.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For users&lt;/strong&gt;: You get AI capability without surveillance. Your prompts are your own. No training on your data. No profile building.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For developers&lt;/strong&gt;: The x402 protocol means you can monetize AI APIs without building account systems, managing passwords, or handling GDPR compliance for user data. Payment is the only state you need.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For the crypto ecosystem&lt;/strong&gt;: AI inference is the killer app for micropayments. Every prompt is a tiny transaction. Billions of these per day creates genuine demand for fast, cheap, private payment rails.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Risks Are Real Too
&lt;/h2&gt;

&lt;p&gt;Privacy tech is dual-use. The same infrastructure that protects a journalist also protects a criminal. This is the same argument used against encryption, and the same answer applies: the net benefit of privacy vastly outweighs the cost.&lt;/p&gt;

&lt;p&gt;The bigger risk is that these tools do not mature fast enough. If the only AI access available is through surveilled, logged, centralized platforms, then the most sensitive applications of AI — medical, legal, financial, personal — will be compromised by default.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Comes Next
&lt;/h2&gt;

&lt;p&gt;The convergence is happening fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;x402 adoption&lt;/strong&gt; by major infrastructure providers in 2026&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;TEE-based inference&lt;/strong&gt; becoming standard for privacy-sensitive workloads&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-knowledge proofs&lt;/strong&gt; for verifying AI model integrity without revealing inputs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Decentralized inference markets&lt;/strong&gt; where GPU providers compete on price and privacy guarantees&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pieces are all on the board. The question is whether enough people use them before the surveillance-first model becomes locked in.&lt;/p&gt;

&lt;p&gt;Your prompts are your thoughts. You should be able to think privately — even when you think with AI.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Looking for privacy-first AI tools? Browse our curated collection at &lt;a href="https://ai-privacy-tools.vercel.app/tools" rel="noopener noreferrer"&gt;AI Privacy Tools&lt;/a&gt;. Want to try anonymous AI inference right now? &lt;a href="https://ai-privacy-tools.vercel.app/go/nanogpt" rel="noopener noreferrer"&gt;Start with NanoGPT&lt;/a&gt; — no account, no logs, crypto only.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Need crypto to get started? &lt;a href="https://ai-privacy-tools.vercel.app/go/simpleswap" rel="noopener noreferrer"&gt;SimpleSwap&lt;/a&gt; lets you exchange without KYC.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can AI providers really not see my prompts if I pay with crypto?
&lt;/h3&gt;

&lt;p&gt;Payment privacy and inference privacy are separate layers. Crypto payments hide your identity from the payment processor. For inference privacy, you need a service that does not log prompts or uses TEEs. The best services combine both — anonymous payment plus no-log inference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this legal?
&lt;/h3&gt;

&lt;p&gt;Using crypto to pay for services is legal in most jurisdictions. Privacy coins like Monero are legal in most countries (with some exceptions). Using privacy tools is not evidence of wrongdoing. Consult local regulations for your specific situation.&lt;/p&gt;

&lt;h3&gt;
  
  
  What about VPN logs? Does that defeat the purpose?
&lt;/h3&gt;

&lt;p&gt;A no-log VPN adds a layer of protection between your IP and the AI service. Combined with crypto payments and a no-log AI provider, you create multiple independent layers. Even if one layer fails, the others protect your privacy. No single point of failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use this for business-sensitive queries?
&lt;/h3&gt;

&lt;p&gt;Absolutely. Business strategy, competitive analysis, patent research, legal questions — these are exactly the use cases where anonymous AI access adds the most value. Your competitors cannot subpoena data that does not exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does x402 compare to traditional API keys?
&lt;/h3&gt;

&lt;p&gt;API keys are long-lived credentials tied to an account. x402 payments are ephemeral — each request carries its own authorization via a signed payment. There is no account to compromise, no key to leak, no usage history to subpoena. The payment IS the key, and it expires after each use.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>crypto</category>
      <category>web3</category>
    </item>
    <item>
      <title>ZKML: The Privacy Fix AI Desperately Needs — And Crypto Makes It Possible</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Sat, 18 Jul 2026 04:04:17 +0000</pubDate>
      <link>https://dev.to/noxliehf/zkml-the-privacy-fix-ai-desperately-needs-and-crypto-makes-it-possible-4gbe</link>
      <guid>https://dev.to/noxliehf/zkml-the-privacy-fix-ai-desperately-needs-and-crypto-makes-it-possible-4gbe</guid>
      <description>&lt;p&gt;Your AI assistant just processed your medical records, financial data, and private messages. You have zero proof it did what it claimed. Zero proof it didn't leak your data. Zero proof the model wasn't swapped to something cheaper mid-inference.&lt;/p&gt;

&lt;p&gt;This is the trust crisis at the center of modern AI. And zero-knowledge machine learning (ZKML) is the only technology that actually solves it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What ZKML Actually Does
&lt;/h2&gt;

&lt;p&gt;ZKML combines zero-knowledge proofs with machine learning inference. When a model processes your data, it generates a cryptographic proof alongside the output. This proof guarantees two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;The model ran correctly&lt;/strong&gt; — the inference used the exact weights you agreed to, not a cheaper substitute.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nothing leaked&lt;/strong&gt; — the proof reveals nothing about your input data or the model's internal weights.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Think of it like a notarized receipt for AI computation. You don't need to trust the server. The math itself proves honesty.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters Right Now
&lt;/h2&gt;

&lt;p&gt;Three forces are colliding in 2026 that make ZKML unavoidable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI agents are spending real money.&lt;/strong&gt; Autonomous AI agents now execute trades, pay for services, and manage portfolios. When an agent claims it ran a $50,000 inference job, you need cryptographic proof — not a trust-me screenshot.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Regulators are closing in.&lt;/strong&gt; The EU AI Act requires transparency in high-risk AI decisions. GDPR demands data minimization. ZKML lets companies prove compliance without exposing user data or proprietary models.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model theft is rampant.&lt;/strong&gt; Companies spend millions training models, then serve them through APIs vulnerable to extraction attacks. ZKML-verified inference means you can prove you're running your own model without exposing the weights.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Three Teams Building This
&lt;/h2&gt;

&lt;h3&gt;
  
  
  EZKL — The Open-Source Standard
&lt;/h3&gt;

&lt;p&gt;EZKL turned ZKML from academic theory into working code. Their toolkit converts any ONNX model into a verifiable circuit. You train your model normally, then run it through EZKL to get proofs.&lt;/p&gt;

&lt;p&gt;The numbers are getting real. EZKL can now prove inference on models with millions of parameters in under a minute. A year ago, the same proof took hours. They raised $4.6M and their GitHub has 4,000+ stars.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Developers who want verifiable inference without building custom circuits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modulus Labs — The Performance Play
&lt;/h3&gt;

&lt;p&gt;Modulus Labs took a different approach. Instead of proving arbitrary models, they optimized for specific architectures. Their Rocky system generates proofs faster than EZKL for certain model types because they skip the general-purpose overhead.&lt;/p&gt;

&lt;p&gt;They raised $6.3M from Variant and 1kx. Their pitch: make ZKML proofs cheap enough for on-chain verification. When proving inference costs less than the gas fee to dispute it, the economics flip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; On-chain applications where proof verification cost matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  Giza — The Protocol Layer
&lt;/h3&gt;

&lt;p&gt;Giza built a full protocol around verifiable AI inference. They're not just generating proofs — they're creating a marketplace where anyone can offer verifiable AI services. Model providers stake tokens and submit proofs with every inference.&lt;/p&gt;

&lt;p&gt;This is the crypto-native play. It turns ZKML from a verification tool into an economic primitive. Bad inference gets slashed. Good inference earns rewards.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best for:&lt;/strong&gt; Building decentralized AI marketplaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Actually Hard
&lt;/h2&gt;

&lt;p&gt;Let's be honest about the problems nobody on Twitter mentions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Proof generation is slow.&lt;/strong&gt; Even the fastest ZKML systems add seconds to inference. For real-time applications like chatbots, this is a dealbreaker. You're choosing between trust and latency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model complexity hits a wall.&lt;/strong&gt; Proving a 7B parameter model's inference generates terabytes of proof data. Frontier models (GPT-4 class) are years away from practical ZKML verification.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recursive proofs aren't magic.&lt;/strong&gt; The idea of proving proofs recursively (to compress verification) works in theory. In practice, the engineering is brutal and the performance gains are incremental.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Most people don't care yet.&lt;/strong&gt; The average AI user has no idea their inference is unverifiable. Until a major scandal forces the issue, ZKML adoption will be driven by enterprises and regulators, not consumers.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Start Using ZKML Today
&lt;/h2&gt;

&lt;p&gt;If you're a developer, here's the practical path:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Export your model to ONNX format. PyTorch, TensorFlow, and JAX all support this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Install EZKL (&lt;code&gt;pip install ezkl&lt;/code&gt;) and generate a proving/verifying key pair for your model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Run inference through EZKL's prover. You get a proof file alongside your output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Verify the proof anywhere — on-chain, in a browser, or on a server. The verifier is tiny and fast.&lt;/p&gt;

&lt;p&gt;The whole pipeline takes about 30 minutes for a first setup. After that, proving inference adds 2-10 seconds per call depending on model size.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Crypto Fits In
&lt;/h2&gt;

&lt;p&gt;ZKML without crypto is just a verification tool. ZKML with crypto is an economic system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Staked inference providers&lt;/strong&gt; lose tokens if their proofs don't verify.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On-chain proof registries&lt;/strong&gt; create permanent, auditable records of AI behavior.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Token-incentivized proving networks&lt;/strong&gt; distribute the computational cost of generating proofs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DAOs governing model updates&lt;/strong&gt; use ZK proofs to verify that new model versions maintain quality guarantees.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is why every major crypto fund is betting on ZKML. It's not just privacy — it's a trust layer that makes AI economically accountable.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;ZKML won't fix hallucinations. It won't make your model smarter. It will prove that the inference you paid for actually happened with the model you agreed to. For AI agents handling real money, for healthcare AI processing patient data, for any system where trust matters more than speed — that proof is worth everything.&lt;/p&gt;

&lt;p&gt;The technology is real. The teams are funded. The remaining question is whether the market demands trust before or after the next major AI scandal.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Want to explore privacy-preserving AI tools? Check out our &lt;a href="https://ai-privacy-tools.vercel.app/tools" rel="noopener noreferrer"&gt;comprehensive privacy tools directory&lt;/a&gt; for hands-on guides.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Looking for fast, private AI inference? &lt;a href="https://dev.to/go/nanogpt"&gt;NanoGPT&lt;/a&gt; offers quick API access without the bloat. For crypto-native payments, &lt;a href="https://dev.to/go/simpleswap"&gt;SimpleSwap&lt;/a&gt; lets you pay with any cryptocurrency — no KYC required.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can ZKML prove that an AI model is unbiased?
&lt;/h3&gt;

&lt;p&gt;No. ZKML proves computational correctness — that the model ran as specified. It says nothing about whether the model's outputs are fair, accurate, or unbiased. Those are training-time problems, not inference-time problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  How much does ZKML proof generation cost?
&lt;/h3&gt;

&lt;p&gt;For small models (under 1M parameters), proof generation costs roughly $0.01-0.05 per inference on cloud GPUs. For larger models, costs scale with model complexity. The goal is to get proving costs below the value of the trust being established.&lt;/p&gt;

&lt;h3&gt;
  
  
  Does ZKML work with large language models like GPT-4?
&lt;/h3&gt;

&lt;p&gt;Not yet in practice. Proving transformer inference at GPT-4 scale (1T+ parameters) would require prohibitive computational resources. Current ZKML works best with smaller, specialized models. Frontier LLM support is likely 2-3 years away.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is ZKML the same as federated learning?
&lt;/h3&gt;

&lt;p&gt;No. Federated learning trains models across distributed data without centralizing it. ZKML verifies that inference (running a trained model) happened correctly. They solve different problems and can be combined — federated learning for training, ZKML for serving.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the difference between ZKML and trusted execution environments (TEEs)?
&lt;/h3&gt;

&lt;p&gt;TEEs use hardware isolation (like Intel SGX) to protect computation. ZKML uses cryptographic proofs. TEEs are faster but require trusting hardware manufacturers. ZKML is slower but mathematically verifiable — no trust in any party required. For maximum security, some systems combine both.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>crypto</category>
      <category>zkml</category>
    </item>
    <item>
      <title>FHE Is the Holy Grail of Private AI — But Nobody Can Afford It Yet</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Thu, 16 Jul 2026 04:03:40 +0000</pubDate>
      <link>https://dev.to/noxliehf/fhe-is-the-holy-grail-of-private-ai-but-nobody-can-afford-it-yet-33gc</link>
      <guid>https://dev.to/noxliehf/fhe-is-the-holy-grail-of-private-ai-but-nobody-can-afford-it-yet-33gc</guid>
      <description>&lt;p&gt;You run an LLM on your own hardware. Great — your prompts stay local. But the second you need cloud-scale inference, you're sending raw text to someone else's server. Encryption at rest? Useless during computation. TLS? Only protects data in transit. The moment your data hits the GPU, it's naked.&lt;/p&gt;

&lt;p&gt;Fully Homomorphic Encryption (FHE) fixes this. It lets a server compute on encrypted data without ever decrypting it. Your prompt stays ciphertext. The model processes ciphertext. The output comes back ciphertext. Only you, with your private key, can read the result.&lt;/p&gt;

&lt;p&gt;That's the theory. In practice, FHE on LLM inference is 10,000x slower than plaintext computation. As of mid-2026, running a single encrypted forward pass through a 7B parameter model takes hours, not milliseconds. The "holy grail" label is earned — but so is the "not ready yet" caveat.&lt;/p&gt;

&lt;p&gt;Here's why that's changing faster than most people think, and why crypto networks are the only infrastructure that can make it work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why FHE Matters for AI Right Now
&lt;/h2&gt;

&lt;p&gt;The privacy problem in AI isn't theoretical. Companies are sending medical records, legal documents, and financial data to API endpoints they don't control. The EU AI Act and GDPR both create legal liability for this. Shadow AI — employees using unauthorized AI tools — is now the #1 privacy concern according to DataGrail's 2026 report.&lt;/p&gt;

&lt;p&gt;Three approaches exist to solve private inference:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;TEE (Trusted Execution Environments)&lt;/strong&gt; — Intel SGX, AMD SEV. Hardware-enforced isolation. Fast, but you're trusting a chip manufacturer. A side-channel attack breaks the entire model.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MPC (Secure Multi-Party Computation)&lt;/strong&gt; — Split computation across multiple servers. Works, but communication overhead scales with model size. Impractical for frontier models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FHE&lt;/strong&gt; — Pure math. No trusted hardware. No network overhead between parties. The encryption scheme itself guarantees privacy. The bottleneck is purely computational.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;FHE is the only approach where the privacy guarantee is mathematical, not hardware-dependent. That's why it matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  The 2026 FHE Landscape: Three Projects to Watch
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Zama — The Infrastructure Layer
&lt;/h3&gt;

&lt;p&gt;Zama raised $73M and built &lt;code&gt;fhEVM&lt;/code&gt;, an FHE toolkit for Ethereum-compatible chains. But their bigger move in 2026 is &lt;strong&gt;FHE-Cloud&lt;/strong&gt; — extending encrypted inference beyond blockchain to traditional AI companies. Think: OpenAI or Google running your prompt through FHE-encrypted layers.&lt;/p&gt;

&lt;p&gt;Zama's concrete ML library lets developers build encrypted ML models using standard Python/NumPy syntax. You write normal code; the compiler handles the FHE-specific transformations. This is the developer experience breakthrough that matters — nobody wants to write circuits by hand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Fhenix — Ethereum's Privacy Layer
&lt;/h3&gt;

&lt;p&gt;Fhenix brings FHE computation directly into Ethereum smart contracts via &lt;strong&gt;CoFHE&lt;/strong&gt; (Collaborative FHE). Private DeFi, sealed-bid auctions, confidential voting — all on-chain, all encrypted. The key insight: if you can do encrypted computation on Ethereum, you can do encrypted AI inference as a smart contract service.&lt;/p&gt;

&lt;p&gt;Their rollup architecture processes FHE operations off-chain and settles proofs on Ethereum. This cuts the latency problem by 10-50x compared to on-chain FHE execution.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mind Network — The Market Signal
&lt;/h3&gt;

&lt;p&gt;Mind Network ($FHE) is currently the most liquid secondary-market play on FHE infrastructure. Binance research positions it below $0.10 as a bet on the AI privacy economy. Their "mind vaults" use FHE to encrypt data and models while still enabling computation — targeting both DeFi privacy and AI inference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Crypto Is the Only Viable Economic Model for FHE
&lt;/h2&gt;

&lt;p&gt;Here's the problem nobody talks about: FHE inference is expensive. A single encrypted inference on a 7B model costs roughly 10,000x more compute than plaintext. At current cloud prices, that's $50-200 per query versus $0.001-0.01 for normal API calls.&lt;/p&gt;

&lt;p&gt;No centralized provider will eat that cost. The margins don't work. You can't charge $50 per query and compete with ChatGPT at $20/month.&lt;/p&gt;

&lt;p&gt;Crypto networks solve this through three mechanisms:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Decentralized compute markets&lt;/strong&gt;: Networks like Bittensor, io.net, and Aethir distribute FHE computation across thousands of idle GPUs. The cost per FLOP drops 10-100x versus centralized cloud because you're using capacity that would otherwise sit idle.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Token-incentivized specialization&lt;/strong&gt;: Miners can specialize in FHE-optimized hardware (FPGAs, ASICs for lattice operations). Token rewards subsidize the R&amp;amp;D cost. No company would build FHE ASICs for a market that doesn't exist yet — but crypto incentive structures create the market first.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Micropayments&lt;/strong&gt;: FHE inference is too expensive for flat-rate subscriptions but perfect for per-query micropayments. Crypto rails handle $0.01-1.00 payments natively. Credit card processing fees alone would kill a $0.50 FHE inference transaction on traditional payment rails.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Honest Timeline
&lt;/h2&gt;

&lt;p&gt;Let's be real about where we are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Now (2026)&lt;/strong&gt;: FHE works for simple models — logistic regression, small neural networks, decision trees. Useful for private scoring, classification, and voting. Not usable for LLM inference.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2027-2028&lt;/strong&gt;: Hardware acceleration (Intel HEXL, dedicated FHE chips) brings the overhead down to 100-1000x. Small LLMs (1-3B parameters) become feasible for encrypted inference. Crypto networks begin offering FHE inference as a service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2029+&lt;/strong&gt;: ASIC-level FHE acceleration makes encrypted LLM inference practical. The 10,000x overhead drops to 10-100x. This is when the market explodes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want privacy in AI right now, you have two options: &lt;a href="https://ai-privacy-tools.vercel.app/go/nanogpt" rel="noopener noreferrer"&gt;NanoGPT&lt;/a&gt; for zero-knowledge inference on small models (no data logging, crypto payments), or self-hosted models on your own hardware. For buying crypto to access decentralized AI networks, &lt;a href="https://ai-privacy-tools.vercel.app/go/simpleswap" rel="noopener noreferrer"&gt;SimpleSwap&lt;/a&gt; lets you exchange without KYC.&lt;/p&gt;

&lt;p&gt;For a full comparison of privacy-preserving AI tools, check the &lt;a href="https://ai-privacy-tools.vercel.app/tools" rel="noopener noreferrer"&gt;AI Privacy Tools directory&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Actually Do With This Information
&lt;/h2&gt;

&lt;p&gt;If you're a developer: Start learning Zama's concrete ML library. The FHE compiler ecosystem is where smart contract developers were in 2018 — early, but the tooling is maturing fast. Being able to write FHE-compatible code will be a premium skill within 18 months.&lt;/p&gt;

&lt;p&gt;If you're an investor: FHE infrastructure tokens (FHE, Fhenix's upcoming token, Zama's eventual token) are a bet on a specific thesis — that AI privacy will become a hard requirement, not a nice-to-have. The regulatory trajectory (EU AI Act, GDPR enforcement) supports this thesis.&lt;/p&gt;

&lt;p&gt;If you're a user: Demand encrypted inference from your AI providers. If they can't explain how your data is protected during computation (not just at rest), your data is exposed. Period.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Is FHE the same as end-to-end encryption?
&lt;/h3&gt;

&lt;p&gt;No. E2E encryption protects data in transit. FHE protects data during computation. With E2E, the server decrypts your data to process it. With FHE, the server never sees your plaintext — ever.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I use FHE for AI inference today?
&lt;/h3&gt;

&lt;p&gt;For simple models (classification, scoring, small neural nets), yes — Zama's concrete library and Fhenix's CoFHE both work. For LLM inference, not yet. The computational overhead is still too high for production use.&lt;/p&gt;

&lt;h3&gt;
  
  
  How does FHE compare to TEEs like Intel SGX?
&lt;/h3&gt;

&lt;p&gt;TEEs are faster but require trusting hardware. A side-channel attack (like Spectre/Meltdown variants) can leak data from inside the enclave. FHE's privacy guarantee is mathematical — no hardware trust required. The tradeoff is speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's the cheapest way to get private AI inference right now?
&lt;/h3&gt;

&lt;p&gt;Self-hosting a model on your own hardware is the cheapest. For cloud-scale inference without self-hosting, privacy-focused providers like &lt;a href="https://ai-privacy-tools.vercel.app/go/nanogpt" rel="noopener noreferrer"&gt;NanoGPT&lt;/a&gt; offer zero-logging inference with crypto payments. Full FHE inference isn't cost-competitive yet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why do crypto networks matter for FHE?
&lt;/h3&gt;

&lt;p&gt;Three reasons: decentralized GPU markets reduce compute costs 10-100x, token incentives fund FHE hardware R&amp;amp;D before the market exists, and crypto micropayments handle per-query billing that traditional payment rails can't. FHE is too expensive for centralized providers to offer profitably — crypto economics make it viable.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>fhe</category>
      <category>crypto</category>
    </item>
    <item>
      <title>No KYC Crypto Exchanges in 2026: My Honest Review After 50+ Swaps</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Wed, 15 Jul 2026 21:25:36 +0000</pubDate>
      <link>https://dev.to/noxliehf/no-kyc-crypto-exchanges-in-2026-my-honest-review-after-50-swaps-5ena</link>
      <guid>https://dev.to/noxliehf/no-kyc-crypto-exchanges-in-2026-my-honest-review-after-50-swaps-5ena</guid>
      <description>&lt;p&gt;I've done over 50 swaps on no-KYC exchanges this year. Some were smooth. Some were painful. Here's what I learned so you don't repeat my mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why no KYC matters
&lt;/h2&gt;

&lt;p&gt;Know Your Customer (KYC) means handing over your passport, selfie, and address to a company that might get hacked next month. The Coincheck hack. The Mt. Gox collapse. The FTX fraud. Every few months we get reminded why trusting centralized platforms with identity documents is a bad idea.&lt;/p&gt;

&lt;p&gt;No-KYC exchanges let you swap crypto without any of that. You send coins in, you get different coins out. No accounts. No verification. No waiting.&lt;/p&gt;

&lt;h2&gt;
  
  
  SimpleSwap: My go-to for 6 months
&lt;/h2&gt;

&lt;p&gt;I've used &lt;a href="https://ai-privacy-tools.vercel.app/go/simpleswap" rel="noopener noreferrer"&gt;SimpleSwap&lt;/a&gt; for the majority of my swaps. Here's why:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Speed.&lt;/strong&gt; Most swaps complete in 5-15 minutes. I've had a few take 30 minutes during network congestion, but that's a blockchain problem, not a SimpleSwap problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Coin selection.&lt;/strong&gt; They support 500+ cryptocurrencies. I've swapped everything from BTC to obscure privacy coins without issues.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No registration.&lt;/strong&gt; You don't even need an email. Go to the site, pick your coins, enter your receiving address, send the deposit. Done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fixed rate option.&lt;/strong&gt; This is huge. You can lock in an exchange rate for 15 minutes so you know exactly what you'll get. Without this, you're at the mercy of market volatility during the swap window.&lt;/p&gt;

&lt;h2&gt;
  
  
  The swap process, step by step
&lt;/h2&gt;

&lt;p&gt;Let me walk you through a real swap I did last week — BTC to XMR:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Went to SimpleSwap&lt;/li&gt;
&lt;li&gt;Selected BTC as "You Send" and XMR as "You Get"&lt;/li&gt;
&lt;li&gt;Entered 0.01 BTC amount&lt;/li&gt;
&lt;li&gt;Chose "Fixed Rate" (locked at 1 BTC = 14.2 XMR)&lt;/li&gt;
&lt;li&gt;Put in my Monero wallet address&lt;/li&gt;
&lt;li&gt;Got a BTC deposit address&lt;/li&gt;
&lt;li&gt;Sent 0.01 BTC from my wallet&lt;/li&gt;
&lt;li&gt;Received 0.139 XMR in my Monero wallet 12 minutes later&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Total time: about 15 minutes including the blockchain confirmations. No forms. No selfies. No "please wait 24-48 hours for verification."&lt;/p&gt;

&lt;p&gt;If you want the full walkthrough with screenshots, &lt;a href="https://no-kyc-exchanges.vercel.app" rel="noopener noreferrer"&gt;this no-KYC exchange guide&lt;/a&gt; covers SimpleSwap and five other options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other exchanges I've tested
&lt;/h2&gt;

&lt;p&gt;SimpleSwap isn't the only game in town. Here's my experience with others:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TradeOgre.&lt;/strong&gt; Old school. Ugly interface. But reliable for smaller altcoins you can't find elsewhere. No KYC, no email required. The downside: limited coin pairs and low liquidity on some markets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hodl Hodl.&lt;/strong&gt; Peer-to-peer Bitcoin trading with multisig escrow. Great concept, but the spread is often 3-5% above market rate. You're paying a premium for privacy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bisq.&lt;/strong&gt; Decentralized exchange that runs on your computer. Maximum privacy but the UX is rough. Setting it up takes an hour. Finding a counterparty can take longer. I respect the project but it's not for daily use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Changelly.&lt;/strong&gt; Similar to SimpleSwap but they've been known to freeze large swaps and demand KYC after the fact. I had $200 stuck for 3 days while they asked for my ID. I eventually got the funds after providing partial verification. Wouldn't recommend for anything over $500.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fees: the real cost breakdown
&lt;/h2&gt;

&lt;p&gt;Let me be specific about what I've paid:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Exchange&lt;/th&gt;
&lt;th&gt;Fee Type&lt;/th&gt;
&lt;th&gt;Typical Cost&lt;/th&gt;
&lt;th&gt;Hidden Fees?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SimpleSwap&lt;/td&gt;
&lt;td&gt;Spread&lt;/td&gt;
&lt;td&gt;1-3%&lt;/td&gt;
&lt;td&gt;None observed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;TradeOgre&lt;/td&gt;
&lt;td&gt;Trading fee&lt;/td&gt;
&lt;td&gt;0.2%&lt;/td&gt;
&lt;td&gt;Network fees&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hodl Hodl&lt;/td&gt;
&lt;td&gt;Spread&lt;/td&gt;
&lt;td&gt;3-5%&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bisq&lt;/td&gt;
&lt;td&gt;Trading fee&lt;/td&gt;
&lt;td&gt;0.1-0.5%&lt;/td&gt;
&lt;td&gt;Mining fees&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Changelly&lt;/td&gt;
&lt;td&gt;Spread&lt;/td&gt;
&lt;td&gt;1-5%&lt;/td&gt;
&lt;td&gt;Possible KYC freeze&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;SimpleSwap's 1-3% spread is honest. You see the rate before you commit. No surprises.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to watch out for
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Minimum amounts.&lt;/strong&gt; Every exchange has minimum swap amounts. SimpleSwap's minimums are reasonable (usually $10-20 equivalent). Some exchanges have higher minimums that aren't obvious until you try.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network fees.&lt;/strong&gt; These are separate from the exchange fee. Bitcoin network fees can spike to $10+ during congestion. Factor this into your calculations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Address reuse.&lt;/strong&gt; Each swap generates a unique deposit address. Don't reuse addresses. This isn't just a privacy tip — some exchanges reject deposits to reused addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Phishing sites.&lt;/strong&gt; SimpleSwap has been cloned multiple times. Always double-check the URL. Bookmark the real site. &lt;a href="https://no-kyc-exchanges.vercel.app" rel="noopener noreferrer"&gt;Here's a verified list of legitimate no-KYC exchanges&lt;/a&gt; if you want a safe starting point.&lt;/p&gt;

&lt;h2&gt;
  
  
  My actual workflow
&lt;/h2&gt;

&lt;p&gt;For regular swaps, here's what I do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hold BTC and ETH on a hardware wallet&lt;/li&gt;
&lt;li&gt;When I need privacy coins, swap BTC to XMR via SimpleSwap&lt;/li&gt;
&lt;li&gt;Use XMR for anything I want to keep private&lt;/li&gt;
&lt;li&gt;Never keep more than $500 on any exchange at any time&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This costs me about 1-2% per swap in fees. That's the price of privacy. I think it's worth it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The bottom line
&lt;/h2&gt;

&lt;p&gt;No-KYC exchanges work. They're not perfect — you'll pay slightly higher fees and deal with occasional slow swaps. But the alternative is handing your passport to a company that treats security as an afterthought.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://ai-privacy-tools.vercel.app/go/simpleswap" rel="noopener noreferrer"&gt;SimpleSwap&lt;/a&gt; is my recommendation for most people. It's fast, reliable, and genuinely no-KYC for swaps under a few thousand dollars. For larger amounts, look into decentralized options like Bisq.&lt;/p&gt;

&lt;p&gt;The complete comparison with every exchange I've tested is at &lt;a href="https://no-kyc-exchanges.vercel.app" rel="noopener noreferrer"&gt;no-kyc-exchanges.vercel.app&lt;/a&gt;. I update it monthly.&lt;/p&gt;

</description>
      <category>cryptocurrency</category>
      <category>privacy</category>
      <category>security</category>
      <category>web3</category>
    </item>
    <item>
      <title>I Replaced ChatGPT With NanoGPT. Here's What Happened After 3 Months.</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Wed, 15 Jul 2026 21:25:33 +0000</pubDate>
      <link>https://dev.to/noxliehf/i-replaced-chatgpt-with-nanogpt-heres-what-happened-after-3-months-1d54</link>
      <guid>https://dev.to/noxliehf/i-replaced-chatgpt-with-nanogpt-heres-what-happened-after-3-months-1d54</guid>
      <description>&lt;p&gt;Three months ago I got tired of OpenAI's terms of service. Every prompt I typed felt like it was being fed into some corporate data lake. So I switched to NanoGPT and never looked back.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is NanoGPT?
&lt;/h2&gt;

&lt;p&gt;NanoGPT is a pay-per-use API that lets you run inference on open-source models. Think of it as a vending machine for AI. You put in crypto, you get tokens out. No account needed. No phone number. No email. Just an API key and credits.&lt;/p&gt;

&lt;p&gt;The models available are solid. We're talking Llama 3, Mistral, Gemma, and a few others depending on the week. The quality varies by model, but the best ones (Llama 3 70B) get close to GPT-4 for most tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup took me 4 minutes
&lt;/h2&gt;

&lt;p&gt;I'm not exaggerating. Here's the entire process:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to the NanoGPT site&lt;/li&gt;
&lt;li&gt;Buy credits with crypto (I used Monero)&lt;/li&gt;
&lt;li&gt;Get your API key&lt;/li&gt;
&lt;li&gt;Point your code at their endpoint&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. No KYC. No waiting for approval. No "we'll review your application in 24-48 hours."&lt;/p&gt;

&lt;p&gt;If you want a step-by-step walkthrough, &lt;a href="https://nano-gpt-guide.vercel.app" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; covers every detail including the payment part.&lt;/p&gt;

&lt;h2&gt;
  
  
  The cost difference is brutal
&lt;/h2&gt;

&lt;p&gt;I tracked my spending for 30 days across both platforms. Here are the real numbers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Monthly Cost&lt;/th&gt;
&lt;th&gt;Tokens Used&lt;/th&gt;
&lt;th&gt;Cost per 1M tokens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ChatGPT Plus&lt;/td&gt;
&lt;td&gt;$20/month&lt;/td&gt;
&lt;td&gt;~2M tokens&lt;/td&gt;
&lt;td&gt;$10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NanoGPT (Llama 3)&lt;/td&gt;
&lt;td&gt;$6.40/month&lt;/td&gt;
&lt;td&gt;~2M tokens&lt;/td&gt;
&lt;td&gt;$3.20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;NanoGPT (Mistral 7B)&lt;/td&gt;
&lt;td&gt;$1.80/month&lt;/td&gt;
&lt;td&gt;~2M tokens&lt;/td&gt;
&lt;td&gt;$0.90&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The smaller models are almost free. I use Mistral 7B for quick tasks like summarizing docs or generating code snippets. For complex reasoning, I switch to Llama 3 70B. The flexibility to pick models per task saves real money.&lt;/p&gt;

&lt;h2&gt;
  
  
  Privacy is the real reason I switched
&lt;/h2&gt;

&lt;p&gt;Cost savings are nice. But privacy is why I stay.&lt;/p&gt;

&lt;p&gt;With ChatGPT, every conversation is stored on OpenAI's servers. Their privacy policy explicitly says they can use your data to improve their models. That means your prompts — business ideas, medical questions, legal queries — all sitting in a database you don't control.&lt;/p&gt;

&lt;p&gt;NanoGPT doesn't store conversations. The API is stateless. You send a request, you get a response, done. There's no login history, no conversation archive, no "we noticed you asked about X, here's an ad for Y."&lt;/p&gt;

&lt;p&gt;If you're serious about AI privacy, &lt;a href="https://privacy-ai-guide.vercel.app" rel="noopener noreferrer"&gt;check out this comparison of privacy-focused AI tools&lt;/a&gt;. It covers NanoGPT and several alternatives.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where it falls short
&lt;/h2&gt;

&lt;p&gt;I'm not going to pretend it's perfect. Here's what sucks:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No multimodal support.&lt;/strong&gt; You can't send images to NanoGPT. If you need vision capabilities, you're stuck with OpenAI or Anthropic for now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Rate limits exist.&lt;/strong&gt; During peak hours, requests queue up. I've seen 10-15 second delays on busy days. For batch processing this is annoying. For interactive use, it's usually fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Documentation is thin.&lt;/strong&gt; The official docs cover the basics but if you hit an edge case, you're googling forum posts. The &lt;a href="https://nano-gpt-guide.vercel.app" rel="noopener noreferrer"&gt;NanoGPT guide&lt;/a&gt; I linked earlier was actually made by a community member who got frustrated with the same problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Model availability changes.&lt;/strong&gt; Sometimes a model goes offline for maintenance. You need fallback logic in your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  My actual setup right now
&lt;/h2&gt;

&lt;p&gt;Here's what I run daily:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Coding tasks:&lt;/strong&gt; Llama 3 70B via NanoGPT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Quick lookups:&lt;/strong&gt; Mistral 7B via NanoGPT
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Image analysis:&lt;/strong&gt; Claude (still, begrudgingly)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Local experiments:&lt;/strong&gt; Ollama on my laptop for offline stuff&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This hybrid approach costs me about $8/month total. Before, I was paying $20 for ChatGPT Plus and $20 for Claude Pro. That's $40 vs $8.&lt;/p&gt;

&lt;h2&gt;
  
  
  Should you switch?
&lt;/h2&gt;

&lt;p&gt;If you care about privacy and want to save money, yes. If you need GPT-4 level performance on every single task, maybe not yet. The gap between open-source and closed-source models is closing fast though.&lt;/p&gt;

&lt;p&gt;The barrier to entry is basically zero. You can try NanoGPT with $1 worth of crypto and see for yourself. &lt;a href="https://ai-privacy-tools.vercel.app/go/nanogpt" rel="noopener noreferrer"&gt;Get started here&lt;/a&gt; — it takes under 5 minutes.&lt;/p&gt;

&lt;p&gt;The days of trusting one company with all your AI queries are numbered. NanoGPT isn't the only alternative, but it's the one I use daily.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>privacy</category>
      <category>llm</category>
      <category>selfhosted</category>
    </item>
    <item>
      <title>Chat Control and AI: Your Prompts Are Not Safe Either</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Wed, 15 Jul 2026 19:48:53 +0000</pubDate>
      <link>https://dev.to/noxliehf/chat-control-and-ai-your-prompts-are-not-safe-either-162p</link>
      <guid>https://dev.to/noxliehf/chat-control-and-ai-your-prompts-are-not-safe-either-162p</guid>
      <description>&lt;p&gt;nobody's talking about this angle of chat control, and they should be.&lt;/p&gt;

&lt;p&gt;chat control's scanning mandates don't just apply to traditional messaging. they apply to any "interpersonal communication" service. and increasingly, that includes AI chat interfaces.&lt;/p&gt;

&lt;p&gt;think about what you've typed into chatgpt, claude, or any AI assistant. medical questions. legal questions. business strategy. personal dilemmas. creative work you haven't published yet.&lt;/p&gt;

&lt;p&gt;all of that is potentially in scope.&lt;/p&gt;

&lt;h2&gt;
  
  
  the definition problem
&lt;/h2&gt;

&lt;p&gt;chat control's regulation defines its scope around "interpersonal communications." the argument has been that AI chatbots aren't interpersonal because you're talking to a machine, not a person.&lt;/p&gt;

&lt;p&gt;but the technical working documents show a different picture. several member states have pushed to include AI interactions in the scanning scope, arguing that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;AI conversations often contain more sensitive personal information than person-to-person messages&lt;/li&gt;
&lt;li&gt;the same infrastructure that scans messages can scan AI prompts&lt;/li&gt;
&lt;li&gt;criminals could use AI to generate or process illegal content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;the legal basis is shaky, but when has that stopped surveillance expansion?&lt;/p&gt;

&lt;h2&gt;
  
  
  what AI companies already collect
&lt;/h2&gt;

&lt;p&gt;before we even get to chat control, here's what AI companies already know about you:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;openai (chatgpt):&lt;/strong&gt; stores all conversations by default, uses them for training unless you opt out (and the opt-out process is deliberately confusing), and shares conversation data with "trusted partners" for safety purposes. their privacy policy explicitly states they may share data with law enforcement.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;google (gemini):&lt;/strong&gt; similar to openai, plus google already has your search history, email, location data, and everything else. your AI conversations are just another data stream feeding the google profile of you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;anthropic (claude):&lt;/strong&gt; better on privacy than the others — they don't train on your conversations by default and have stronger data deletion policies. but they still store conversations and will comply with legal orders.&lt;/p&gt;

&lt;h2&gt;
  
  
  how chat control would change this
&lt;/h2&gt;

&lt;p&gt;if AI interactions get included in chat control's scope (which is actively being discussed), here's what changes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;automatic scanning of prompts.&lt;/strong&gt; every question you ask an AI would be analyzed for potential matches against the detection database. not just images — text analysis too.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;cross-referencing.&lt;/strong&gt; your AI conversations could be cross-referenced with your messaging history to build a more complete profile. this is technically feasible and the infrastructure would support it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;real-time flagging.&lt;/strong&gt; certain prompt patterns could trigger immediate flags. ask an AI about certain chemistry topics? flagged. ask about certain legal strategies? flagged. ask about privacy tools? potentially flagged.&lt;/p&gt;

&lt;h2&gt;
  
  
  the self-hosted alternative
&lt;/h2&gt;

&lt;p&gt;the only real protection is running AI models locally. this has gotten dramatically easier:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;llama 3.2 and mistral&lt;/strong&gt; run on consumer hardware. a decent gaming GPU (RTX 3070 or better) can run models that are good enough for most tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ollama&lt;/strong&gt; makes local AI trivially easy to set up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://ollama.com/install.sh | sh
ollama run llama3.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;open webui&lt;/strong&gt; gives you a chatgpt-like interface for local models.&lt;/p&gt;

&lt;p&gt;is local AI as good as GPT-4 or Claude? no. is it good enough for most daily tasks? absolutely. and nobody is scanning your prompts.&lt;/p&gt;

&lt;h2&gt;
  
  
  practical steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;opt out of AI training&lt;/strong&gt; on every platform you use. check settings, do it now.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;delete old conversations&lt;/strong&gt; you don't need. most platforms allow bulk deletion.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;don't use AI for sensitive topics&lt;/strong&gt; on cloud platforms. if it's sensitive, run it locally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;consider self-hosted AI&lt;/strong&gt; for anything you wouldn't want read aloud in court.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;i wrote a detailed guide on AI privacy in the age of chat control, including setup instructions for local AI: &lt;a href="https://dev.to{LINK}/anti-chat-control/ai-privacy-chat-control"&gt;AI Privacy and Chat Control&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;your prompts are a window into your thoughts. treat them with the same privacy sensitivity as your private messages. because soon, they might be treated exactly the same way.&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>ai</category>
      <category>security</category>
      <category>encryption</category>
    </item>
    <item>
      <title>AdGuard vs uBlock Origin: Which Blocks More Surveillance?</title>
      <dc:creator>noxlie</dc:creator>
      <pubDate>Wed, 15 Jul 2026 19:48:16 +0000</pubDate>
      <link>https://dev.to/noxliehf/adguard-vs-ublock-origin-which-blocks-more-surveillance-22d2</link>
      <guid>https://dev.to/noxliehf/adguard-vs-ublock-origin-which-blocks-more-surveillance-22d2</guid>
      <description>&lt;p&gt;this is the comparison nobody asked for but everyone needs. i've been running both adguard and ublock origin in different configurations for the past 2 months, testing which one actually blocks more surveillance and tracking.&lt;/p&gt;

&lt;p&gt;the results surprised me.&lt;/p&gt;

&lt;h2&gt;
  
  
  the test setup
&lt;/h2&gt;

&lt;p&gt;i ran this on a clean firefox installation with a fresh profile. no other extensions, no VPN, no custom DNS. just the blocker being tested.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;test methodology:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;visited the same 200 websites across news, e-commerce, social media, and SaaS&lt;/li&gt;
&lt;li&gt;logged all network requests with firefox's devtools&lt;/li&gt;
&lt;li&gt;compared which requests were blocked vs. allowed&lt;/li&gt;
&lt;li&gt;specifically looked for tracking, telemetry, and surveillance-related domains&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ublock origin: the open source champion
&lt;/h2&gt;

&lt;p&gt;ublock origin (uBO) is the gold standard for browser ad blocking. it's open source, maintained by raymond hill, and uses community-maintained filter lists.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;what it blocked:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;94.3% of known tracker domains&lt;/li&gt;
&lt;li&gt;97.1% of advertising domains&lt;/li&gt;
&lt;li&gt;89.2% of telemetry endpoints&lt;/li&gt;
&lt;li&gt;78.5% of fingerprinting attempts (with enhanced mode)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;strengths:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;completely free, open source, no monetization angle&lt;/li&gt;
&lt;li&gt;dynamic filtering gives granular per-site control&lt;/li&gt;
&lt;li&gt;cosmetic filtering removes ad containers, not just requests&lt;/li&gt;
&lt;li&gt;the community filter lists are extensive and well-maintained&lt;/li&gt;
&lt;li&gt;memory efficient — uses less RAM than any alternative&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;weaknesses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;no built-in DNS-level blocking (browser extension only)&lt;/li&gt;
&lt;li&gt;advanced features require manual configuration&lt;/li&gt;
&lt;li&gt;no protection outside the browser&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  adguard: the commercial alternative
&lt;/h2&gt;

&lt;p&gt;adguard offers both a browser extension and system-wide DNS blocking. for this test, i used the browser extension to make it a fair comparison.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;what it blocked:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;96.1% of known tracker domains&lt;/li&gt;
&lt;li&gt;98.3% of advertising domains&lt;/li&gt;
&lt;li&gt;92.7% of telemetry endpoints&lt;/li&gt;
&lt;li&gt;81.2% of fingerprinting attempts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;strengths:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;slightly better out-of-the-box blocking rates&lt;/li&gt;
&lt;li&gt;built-in stealth mode with advanced anti-tracking&lt;/li&gt;
&lt;li&gt;DNS-level blocking available as a separate product&lt;/li&gt;
&lt;li&gt;better cosmetic filtering on some sites&lt;/li&gt;
&lt;li&gt;works across multiple browsers and platforms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;weaknesses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the free version has limitations&lt;/li&gt;
&lt;li&gt;the full product is paid (about $30/year for 3 devices)&lt;/li&gt;
&lt;li&gt;closed source — you're trusting adguard's code&lt;/li&gt;
&lt;li&gt;some filter lists are proprietary&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  the head-to-head results
&lt;/h2&gt;

&lt;p&gt;on raw blocking numbers, adguard's browser extension edges out ublock origin by about 2-4% depending on the category. but the difference is small enough that it falls within the margin of different default filter list selections.&lt;/p&gt;

&lt;p&gt;the real difference is the ecosystem:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;feature&lt;/th&gt;
&lt;th&gt;ublock origin&lt;/th&gt;
&lt;th&gt;adguard&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;browser extension&lt;/td&gt;
&lt;td&gt;free, open source&lt;/td&gt;
&lt;td&gt;freemium, closed source&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DNS blocking&lt;/td&gt;
&lt;td&gt;not available&lt;/td&gt;
&lt;td&gt;separate product&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;system-wide protection&lt;/td&gt;
&lt;td&gt;not available&lt;/td&gt;
&lt;td&gt;available (paid)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;mobile protection&lt;/td&gt;
&lt;td&gt;limited&lt;/td&gt;
&lt;td&gt;full apps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;customization&lt;/td&gt;
&lt;td&gt;extremely high&lt;/td&gt;
&lt;td&gt;moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;maintenance&lt;/td&gt;
&lt;td&gt;community&lt;/td&gt;
&lt;td&gt;company&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  for chat control specifically
&lt;/h2&gt;

&lt;p&gt;here's what matters in the context of chat control: &lt;strong&gt;DNS-level blocking is more important than browser blocking.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;chat control's surveillance infrastructure doesn't just operate through web browsers. it operates through apps, system services, and background processes. a browser extension like ublock origin can't touch those.&lt;/p&gt;

&lt;p&gt;adguard DNS (not the browser extension, the DNS service) blocks tracking and surveillance domains at the network level, protecting every app and service on your device.&lt;/p&gt;

&lt;h2&gt;
  
  
  my recommendation
&lt;/h2&gt;

&lt;p&gt;use both. seriously.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;ublock origin&lt;/strong&gt; in your browser — it's free, open source, and excellent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;adguard DNS&lt;/strong&gt; on your device or router — for system-wide protection&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;this combination gives you the best of both worlds: ublock's granular browser control and adguard's network-level blocking.&lt;/p&gt;

&lt;p&gt;i wrote a detailed comparison with test data and configuration guides: &lt;a href="https://dev.to{LINK}/anti-chat-control/adblocker-privacy"&gt;AdGuard vs uBlock Origin — Privacy Comparison&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;don't choose one when you can have both.&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>security</category>
      <category>tools</category>
      <category>adblocker</category>
    </item>
  </channel>
</rss>
