<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://benwoodall.eth.limo/feed.xml" rel="self" type="application/atom+xml" /><link href="https://benwoodall.eth.limo/" rel="alternate" type="text/html" /><updated>2026-08-07T20:02:04-05:00</updated><id>https://benwoodall.eth.limo/feed.xml</id><title type="html">Ben Woodall</title><subtitle>Last of the freelance hackers - Greatest sword fighter in the world</subtitle><entry><title type="html">Putting Sigil Down</title><link href="https://benwoodall.eth.limo/blog/putting-sigil-down/" rel="alternate" type="text/html" title="Putting Sigil Down" /><published>2026-05-20T17:11:00-05:00</published><updated>2026-05-20T17:11:00-05:00</updated><id>https://benwoodall.eth.limo/blog/putting-sigil-down</id><content type="html" xml:base="https://benwoodall.eth.limo/blog/putting-sigil-down/"><![CDATA[<p align="center">
  <img src="/images/sigil-logo.svg" alt="Sigil logo (Thurin fingerprint mark with the verified checkmark replaced by a copper X)" width="240" />
</p>

<p>The thing that pushed Sigil off the road came out of Germany, in a sentence I read twice to make sure I had it right. Their mobile driver’s license, the country’s official state-issued mDL, would <strong>REQUIRE</strong> Apple or Google’s wallet to function. Not as a recommended client. As a <em>requirement</em>.</p>

<p>I closed the tab and didn’t open it again for a while.</p>

<p>This is an honest accounting of why Thurin Labs has quietly shelved its first product, why the math being right wasn’t enough (zero-knowledge math, mind you), and what I think people building privacy-preserving identity systems should be paying attention to in 2026.</p>

<h3 id="what-sigil-was-supposed-to-be">What Sigil Was Supposed to Be</h3>

<p>Sigil’s pitch was small and clean: prove you’re a unique human being, without revealing who you are. Connect a wallet. Share your mobile driver’s license. Choose what gets revealed. A zero-knowledge circuit, written in Noir and verified via UltraHonk (always fun to say and write), generates a proof of personhood with a nullifier. A one-time, unlinkable claim that <em>yes, this is a real person, and no, this isn’t the same person twice.</em> The proof mints a soulbound token. No KYC database. No PII stored. The state-issued credential never leaves the device.</p>

<p>It was meant to slot into a fourth category that Vitalik’s <a href="https://vitalik.eth.limo/general/2023/07/24/biometric.html" target="_blank">proof-of-personhood taxonomy</a> didn’t quite cover. Not biometric. Not social-graph. <em>Document-backed</em>. A real credential, signed by a real DMV, proven without ever being shown. It was the version of the system I would have wanted as a user. Use the credential I already carry. Throw away everything else.</p>

<p>I built it. The circuits compiled. The contract verified. The flow worked. You can prove <em>YOU</em>.</p>

<p>And then the world began re-arranging the input pipeline underneath it.</p>

<h3 id="the-first-crack">The First Crack</h3>

<p>The first sign was Apple. To read an mDL from an iOS device, you have to go through Apple’s “Verify with Wallet” API. It is closed. It is proprietary. It is mediated entirely by a company whose business model has shifted, year by year, toward becoming the identity arbiter of the consumer internet.</p>

<p>So we pivoted. The Android path, via the W3C <a href="https://www.w3.org/TR/digital-credentials/" target="_blank">Digital Credentials API</a> and OID4VP, used open web standards instead of vendor APIs. I told myself this was actually <em>more</em> aligned with what Thurin was for. The cypherpunk path over the locked one. Not a workaround. The principled implementation.</p>

<p>I still believe that’s true, in the narrow technical sense.</p>

<p>But then I started reading the implementation guidance more carefully. The announcements out of various states. The eIDAS 2.0 timelines. The fine print of Germany’s mDL rollout.</p>

<p>And what is now plainly visible, if you read the documents instead of the press releases, is that the credential root is being captured at the operating system level. <em>Not by accident.</em> Not as a transitional detail. By design. The phone vendors are becoming the holders of state-issued identity, and the states are signing off on it because it solves their distribution problem in one move.</p>

<h3 id="the-input-is-the-problem">The Input Is the Problem</h3>

<p>Here is the sentence I kept writing in my own notes:</p>

<blockquote>
  <p><em>Sigil’s ZKP layer is sound. The input to that layer is the problem.</em></p>
</blockquote>

<p>You can write the most rigorous zero-knowledge circuit ever published. You can prove personhood, age, residency, anything you like, without revealing a single bit beyond what’s asked. And if the credential you’re proving over arrives at your device through Apple’s or Google’s wallet, gated by their attestation, signed under their key, presentable only when their software allows it, then your privacy guarantee is <em>downstream of two surveillance companies.</em></p>

<p><strong>That isn’t privacy. It’s compliance dressed in privacy-preserving aesthetics</strong>.</p>

<p>A ZKP on top of a captured input pipeline doesn’t fix the capture.</p>

<p><strong>It launders it.</strong></p>

<p>It makes the resulting credential <em>look</em> sovereign (auditable, math-backed, on-chain) while the actual moment of holding and presenting identity remains the property of someone else. The user is back inside the walled garden, just with a nicer view from the window.</p>

<p>I am not willing to ship that and call it Thurin.</p>

<h3 id="what-forced-digital-identity-actually-looks-like-in-2026">What Forced Digital Identity Actually Looks Like in 2026</h3>

<p><img src="/images/forced-identity.jpg" alt="Mugatu meme: &quot;Forced identity verification is so hot right now&quot;" /></p>

<p>This is the part I’d ask people in the privacy space to internalize, because I think it’s still being discussed as something that <em>might happen</em> rather than something that <em>is shipping right now.</em> And it isn’t just Germany. It is shipping in the United States, with very little visible resistance.</p>

<p>The architecture is already built. Not “coming.” Built.</p>

<p>Federally, <a href="https://www.tsa.gov/realid" target="_blank">REAL ID enforcement</a> went live in May 2025. Non-compliant state IDs are no longer accepted at airport checkpoints. Starting February 2026, the TSA introduced <a href="https://www.tsa.gov/news/press/releases/2025/12/01/tsa-introduces-new-45-fee-option-for-travelers-without-real-id" target="_blank">ConfirmID</a>, a $45 fee for travelers without acceptable physical identification, with explicit acceptance of Apple Digital ID, Google ID pass, and Clear ID as alternatives. The federal government has, in practice, onboarded the consumer identity duopoly into air travel itself.</p>

<p>At the state level the rollout is faster than the public conversation. Thirteen states and Puerto Rico already have a <a href="https://www.tsa.gov/digital-id/participating-states" target="_blank">mobile driver’s license available in Apple Wallet</a>, with seven more committed. The TSA accepts these mDLs at over 250 airports. Georgia’s HB296 went a step further. It mandates that law enforcement accept the mDL at traffic stops, and that every officer carry a reader by mid-2027. The mDL is becoming, by statute, the way the state recognizes you.</p>

<p>The website side of this is moving faster still. Twenty-five U.S. states, half the country, now require a government-issued ID, a credit card, or a facial scan to access whole categories of legal websites. After the Supreme Court’s 2025 ruling in <em><a href="https://www.npr.org/2025/06/27/nx-s1-5422424/scotus-texas-porn-law" target="_blank">Free Speech Coalition v. Paxton</a></em>, those laws survive on intermediate scrutiny, the lowest constitutional bar that still permits a law to stand. Nebraska’s age-verification statute takes effect July 1, 2026. California’s SB 976 takes full effect December 31, 2026. More are in flight in more states.</p>

<p>Internationally, eIDAS 2.0 is deploying its digital wallet framework across the EU. Germany’s mDL rollout will not function without Apple or Google.</p>

<p>The two viable mobile holders, for the vast majority of citizens of the vast majority of countries that are rolling any of this out, are Apple Wallet and Google Wallet. The “Verify with Wallet” and Digital Credentials APIs that downstream applications use to read these credentials route through, and can be revoked by, those same vendors.</p>

<p>There is no version of this stack where the user is in control of their own credential root. There is only the version where Apple and Google are. The cryptography downstream of that point is decoration. Beautiful decoration, in some cases. But decoration.</p>

<p>This isn’t a slippery slope argument. The slope already ended. We’re standing in the place the slope was supposed to lead.</p>

<h3 id="why-thurin-keeps-going-without-sigil-at-the-front">Why Thurin Keeps Going Without Sigil at the Front</h3>

<p>Putting Sigil down was hard. It was the showcase project, the one that demonstrated the most. It was also the one downstream of architecture I do not control and cannot reform from where I sit.</p>

<p>What I do control are the <em>other</em> two pieces of the Thurin stack. And they are, I think, more interesting precisely because they refuse the mDL pipeline entirely.</p>

<p><a href="https://signet.thurin.id" target="_blank"><strong>Signet</strong></a> doesn’t ask permission from any wallet vendor. It links a PGP key (one you generated, on a machine you control) to an Ethereum address you also control, with a mutual on-chain attestation. The credential root is <em>you.</em> Not a DMV. Not a phone OS. Not a corporate signer. The cryptography you publish is the cryptography you made.</p>

<p><a href="https://scry.thurin.id" target="_blank"><strong>Scry</strong></a> is the explorer that makes those self-issued identities discoverable and verifiable, client-side, without a server. It surfaces the PGP web of trust, on-chain attestations, social proofs, and the EFP social graph. Everything you’ve voluntarily made public, none of what you haven’t.</p>

<p>Together they describe a different architecture: identity that starts at the user and builds outward, instead of starting at a state-or-corporate root and trickling down. PGP is old. Bottom-up identity is old. The new piece is that on-chain attestation finally gives PGP a global, censorship-resistant verifiability layer it never had. Exactly the layer Vitalik gestured at in <a href="https://vitalik.eth.limo/general/2023/12/28/cypherpunk.html" target="_blank">Make Ethereum Cypherpunk Again</a> when he noted that cryptocurrency was the first thing to give PGP keys mass adoption.</p>

<p>It is slower. It is less shiny than a soulbound proof-of-personhood NFT. There is no government signature anywhere in the chain. That is the point.</p>

<h3 id="on-putting-it-down-rather-than-shipping-it-compromised">On Putting It Down Rather Than Shipping It Compromised</h3>

<p>I want to be honest about this last part, because I think it matters.</p>

<p>There was a version of Sigil I could have shipped. iOS first, Apple Wallet API, slick onboarding, growth chart. There would have been users. There would have been writeups. The math really is sound, the demo really does work, and nobody pulling out their phone to mint a soulbound token would have been thinking about credential root architecture while they did it.</p>

<p>I don’t want to be the person who ships well-encrypted compliance and calls it sovereignty. <em>Cypherpunk</em> is not an aesthetic. <em>Build tools, not empires</em> is not a brand tagline. If the credential root for the entire identity layer is being annexed by the two largest empires the consumer internet has ever produced, then the right answer is not to build a beautiful ZK frontend for that annexation. It is to refuse, and to build elsewhere.</p>

<p>Sigil is private now. The code still exists. The circuits still verify. If the credential root ever gets free of OS vendor capture (and this is a real <em>if</em>), I will pick it back up. Until then, it sits.</p>

<p>In the meantime, the work continues. Just not from the captured end of the pipeline.</p>

<p><em>If you want to see the bottom-up version of this, <a href="https://signet.thurin.id" target="_blank">Signet</a> is where you start. Generate a PGP key, link it to your wallet, publish the attestation. Or look around in <a href="https://scry.thurin.id" target="_blank">Scry</a> to see what an identity graph that doesn’t pass through Apple looks like. Questions, pushback, corrections: <code class="language-plaintext highlighter-rouge">bendoubleu.eth</code>, or via my <a href="https://scry.thurin.id/ens/bendoubleu.eth" target="_blank">Scry profile</a>.</em></p>]]></content><author><name></name></author><category term="thurin" /><category term="sigil" /><category term="identity" /><category term="mdl" /><category term="zero-knowledge" /><category term="privacy" /><category term="cypherpunk" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Your Key, Your Domain: Setting Up WKD for PGP Discovery</title><link href="https://benwoodall.eth.limo/blog/your-key-your-domain-setting-up-wkd-for-pgp-discovery/" rel="alternate" type="text/html" title="Your Key, Your Domain: Setting Up WKD for PGP Discovery" /><published>2026-03-09T21:17:00-05:00</published><updated>2026-03-09T21:17:00-05:00</updated><id>https://benwoodall.eth.limo/blog/your-key-your-domain-setting-up-wkd-for-pgp-discovery</id><content type="html" xml:base="https://benwoodall.eth.limo/blog/your-key-your-domain-setting-up-wkd-for-pgp-discovery/"><![CDATA[<p>I’ve been building <a href="https://signet.thurin.id" target="_blank">Signet</a>, a mutual attestation protocol that cryptographically links a PGP key to an Ethereum address. The whole thesis is self-sovereign identity: you prove who you are, on infrastructure you control, without asking anyone’s permission.</p>

<p>While building it I looked at my own PGP setup and felt like a hypocrite.</p>

<p>My public key lived on <code class="language-plaintext highlighter-rouge">keys.openpgp.org</code>. A keyserver I don’t run, don’t control, and can’t guarantee will exist tomorrow. Anyone wanting to verify my signatures had to trust a third party to serve them the right key. That’s not self-sovereign. That’s just outsourcing the problem.</p>

<p>Web Key Directory (WKD) fixes this. It’s a simple protocol that lets email clients and other tools fetch your public key directly from your domain. No keyserver. No third party. Just an HTTP request to a path you control, answered by a file you put there.</p>

<p>Here’s how it works and how to set it up.</p>

<hr />

<h2 id="what-wkd-actually-is">What WKD Actually Is</h2>

<p>The spec is simple. When someone wants your key for <code class="language-plaintext highlighter-rouge">you@yourdomain.com</code>, their client:</p>

<ol>
  <li>Hashes your local part (<code class="language-plaintext highlighter-rouge">you</code>) using a specific Z-Base-32 encoding</li>
  <li>Makes an HTTPS request to one of two places:
    <ul>
      <li><strong>Advanced method</strong>: <code class="language-plaintext highlighter-rouge">https://openpgpkey.yourdomain.com/.well-known/openpgpkey/yourdomain.com/hu/{hash}</code></li>
      <li><strong>Direct method</strong>: <code class="language-plaintext highlighter-rouge">https://yourdomain.com/.well-known/openpgpkey/hu/{hash}</code></li>
    </ul>
  </li>
</ol>

<p>The advanced method is preferred. It uses a dedicated subdomain, which is cleaner and sidesteps potential conflicts with existing web server config. The direct method is the fallback. Implement both.</p>

<p>The file at that path is just your exported public key, in binary (not ASCII-armored).</p>

<p>That’s it. The protocol is not complicated. The implementation is mostly NGINX config and a <code class="language-plaintext highlighter-rouge">gpg --export</code> command.</p>

<hr />

<h2 id="step-1-generate-your-hash">Step 1: Generate Your Hash</h2>

<p>GnuPG can compute the WKD hash for you:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gpg <span class="nt">--with-wkd-hash</span> <span class="nt">--fingerprint</span> you@yourdomain.com
</code></pre></div></div>

<p>Look for the line that says <code class="language-plaintext highlighter-rouge">uid</code>. The hash appears in brackets after your email address, something like <code class="language-plaintext highlighter-rouge">dizb37aqa5h4skgu7jf1xjr4q71w4paq</code>. That’s the filename you need.</p>

<hr />

<h2 id="step-2-export-your-key">Step 2: Export Your Key</h2>

<p>Export in binary with the minimal flag. Stripping third-party certifications avoids a false-positive revocation warning that some WKD checkers will flag:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gpg <span class="nt">--export</span> <span class="nt">--export-options</span> export-minimal you@yourdomain.com <span class="o">&gt;</span> <span class="o">{</span><span class="nb">hash</span><span class="o">}</span>
</code></pre></div></div>

<p>No <code class="language-plaintext highlighter-rouge">--armor</code>. Binary only. The file has no extension.</p>

<hr />

<h2 id="step-3-set-up-the-directory-structure">Step 3: Set Up the Directory Structure</h2>

<p>On your server, create the following. I’m using <code class="language-plaintext highlighter-rouge">/var/www/yourdomain.com</code> as the web root but adjust for your setup:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/var/www/yourdomain.com/.well-known/openpgpkey/
  policy                          ← empty file, required by spec
  hu/{hash}                       ← direct method key file

/var/www/yourdomain.com/.well-known/openpgpkey/yourdomain.com/
  policy                          ← empty file
  hu/{hash}                       ← advanced method key file
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">policy</code> files are empty. Their presence is required by the spec even though they carry no content.</p>

<p>Copy your exported key file to both <code class="language-plaintext highlighter-rouge">hu/</code> directories.</p>

<hr />

<h2 id="step-4-dns">Step 4: DNS</h2>

<p>For the advanced method, you need an A record pointing <code class="language-plaintext highlighter-rouge">openpgpkey.yourdomain.com</code> at your server. Add that wherever you manage DNS.</p>

<hr />

<h2 id="step-5-nginx-config">Step 5: NGINX Config</h2>

<p>Two pieces. First, add a location block to your existing <code class="language-plaintext highlighter-rouge">yourdomain.com</code> server block for the direct method:</p>

<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">location</span> <span class="n">/.well-known/openpgpkey/</span> <span class="p">{</span>
    <span class="kn">root</span> <span class="n">/var/www/yourdomain.com</span><span class="p">;</span>
    <span class="kn">default_type</span> <span class="nc">application/octet-stream</span><span class="p">;</span>
    <span class="kn">add_header</span> <span class="s">Access-Control-Allow-Origin</span> <span class="s">"*"</span><span class="p">;</span>
    <span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="p">=</span><span class="mi">404</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Put this before any catch-all redirect rules or you’ll redirect the WKD requests away.</p>

<p>Second, create a new server block for the <code class="language-plaintext highlighter-rouge">openpgpkey</code> subdomain:</p>

<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
    <span class="kn">listen</span> <span class="mi">443</span> <span class="s">ssl</span><span class="p">;</span>
    <span class="kn">server_name</span> <span class="s">openpgpkey.yourdomain.com</span><span class="p">;</span>

    <span class="kn">ssl_certificate</span> <span class="n">/etc/letsencrypt/live/openpgpkey.yourdomain.com/fullchain.pem</span><span class="p">;</span>
    <span class="kn">ssl_certificate_key</span> <span class="n">/etc/letsencrypt/live/openpgpkey.yourdomain.com/privkey.pem</span><span class="p">;</span>

    <span class="kn">root</span> <span class="n">/var/www/yourdomain.com</span><span class="p">;</span>

    <span class="kn">location</span> <span class="n">/.well-known/openpgpkey/</span> <span class="p">{</span>
        <span class="kn">default_type</span> <span class="nc">application/octet-stream</span><span class="p">;</span>
        <span class="kn">add_header</span> <span class="s">Access-Control-Allow-Origin</span> <span class="s">"*"</span><span class="p">;</span>
        <span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="p">=</span><span class="mi">404</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<hr />

<h2 id="step-6-tls-for-the-subdomain">Step 6: TLS for the Subdomain</h2>

<p>WKD requires HTTPS. Get a cert for the subdomain:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>certbot <span class="nt">--nginx</span> <span class="nt">-d</span> openpgpkey.yourdomain.com
</code></pre></div></div>

<p>Test your NGINX config before reloading:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>nginx <span class="nt">-t</span> <span class="o">&amp;&amp;</span> systemctl reload nginx
</code></pre></div></div>

<hr />

<h2 id="step-7-verify">Step 7: Verify</h2>

<p><a href="https://wkd.dp42.dev/" target="_blank">wkd.dp42.dev</a> will check both methods and tell you exactly what’s passing and what isn’t. You want green on both advanced and direct. If you get a false revocation warning, double-check that you used <code class="language-plaintext highlighter-rouge">--export-options export-minimal</code> on your key export.</p>

<hr />

<h2 id="why-this-matters">Why This Matters</h2>

<p>Keyservers are not the enemy. <code class="language-plaintext highlighter-rouge">keys.openpgp.org</code> is a good service run by good people. But it’s still someone else’s server, someone else’s uptime, someone else’s decision about what to serve.</p>

<p>When you set up WKD, key discovery for your address becomes a function of your domain. If you control your domain, you control your key. Your personal site is yours, not a profile on someone else’s platform. Your key should be yours too, not a record in someone else’s database.</p>

<p>This is a small piece of a larger thing I’ve been thinking about: what does genuinely self-sovereign identity look like? Not a product someone sells you. Not a profile you rent. Cryptographic identity anchored to infrastructure you own, verifiable by anyone, dependent on no one.</p>

<p><a href="https://signet.thurin.id" target="_blank">Signet</a> is one piece of that. It’s a mutual attestation between a PGP key and an Ethereum address, each signing a commitment to the other. <a href="https://scry.thurin.id" target="_blank">Scry</a> lets you explore the resulting identity graph. WKD is a quieter piece: just making sure that when someone looks for your key, they find it from you.</p>

<p>That’s worth spending a little extra time in your NGINX configs.</p>

<hr />

<p><em>Have questions or ran into something weird with your setup? Find me at <code class="language-plaintext highlighter-rouge">bendoubleu.eth</code> or via my <a href="https://scry.thurin.id/ens/bendoubleu.eth" target="_blank">Scry Profile</a>.</em></p>]]></content><author><name></name></author><category term="pgp" /><category term="wkd" /><category term="nginx" /><category term="self-hosting" /><category term="signet" /><category term="thurin" /><category term="identity" /><summary type="html"><![CDATA[I’ve been building Signet, a mutual attestation protocol that cryptographically links a PGP key to an Ethereum address. The whole thesis is self-sovereign identity: you prove who you are, on infrastructure you control, without asking anyone’s permission.]]></summary></entry><entry><title type="html">Publishing to the Permanent Web</title><link href="https://benwoodall.eth.limo/blog/publishing-to-the-permanent-web/" rel="alternate" type="text/html" title="Publishing to the Permanent Web" /><published>2025-12-17T19:09:00-06:00</published><updated>2025-12-17T19:09:00-06:00</updated><id>https://benwoodall.eth.limo/blog/publishing-to-the-permanent-web</id><content type="html" xml:base="https://benwoodall.eth.limo/blog/publishing-to-the-permanent-web/"><![CDATA[<p>When I hit publish on this blog, something unusual happens. The words you’re reading don’t live on a server somewhere—at least, not in the traditional sense. They exist as content-addressed data scattered across a distributed network, pinned to nodes around the world, accessible through pathways that no single entity controls. This is IPFS, and it’s how I publish everything.</p>

<p>The honest answer is that I didn’t need to do this. A VPS running nginx works fine for a personal blog. Nobody’s trying to take down my posts about amateur radio and Solidity contracts. But there’s something philosophically satisfying about publishing to infrastructure that doesn’t require permission. My content exists because the math says it does, not because I’m paying someone to keep a server running. The same post you’re reading at <code class="language-plaintext highlighter-rouge">benwoodall.com</code> is also available at <code class="language-plaintext highlighter-rouge">benwoodall.eth.limo</code>—two completely different infrastructures, same content, same hash. That’s the magic of content addressing. The data is the address.</p>

<h2 id="the-pipeline">The Pipeline</h2>

<p>When I’m ready to publish, I run a deploy script. Here’s what happens:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>┌──────────┐    ┌────────┐    ┌───────────────┐
│  Jekyll  │───▶│ Pinata │───▶│  VPS (nginx)  │
│  build   │    │  pin   │    │   IPFS node   │
└──────────┘    └────────┘    └───────────────┘
                    │                  │
                    ▼                  ▼
              ┌──────────┐      ┌─────────────┐
              │   IPFS   │      │ benwoodall  │
              │ network  │      │    .com     │
              └──────────┘      └─────────────┘
                    │
                    ▼
              ┌──────────┐
              │   ENS    │──▶ benwoodall.eth.limo
              └──────────┘
</code></pre></div></div>

<p>Jekyll builds static HTML, which gets uploaded to Pinata. Pinata returns a CID—a cryptographic fingerprint of everything in that folder. Same content always produces the same CID. Change a single character and you get an entirely different hash. That CID then gets pinned to my own IPFS node on a VPS for redundancy, and nginx gets updated to proxy requests to it. When you visit <code class="language-plaintext highlighter-rouge">benwoodall.com</code>, nginx fetches from the local IPFS node and serves it like any normal website. You’d never know the difference unless you looked under the hood.</p>

<p>Here’s something I learned the hard way: deploying to IPFS is immutable, but your nginx config isn’t. If something goes wrong mid-deploy, you can end up with your domain pointing at a broken CID. So the script captures the current working CID before doing anything else. If any step fails, it rolls back automatically. The broken content still exists on IPFS—that’s the immutability—but nobody sees it because the domain points elsewhere. One of those “obvious in retrospect” things.</p>

<h2 id="making-it-fast">Making It Fast</h2>

<p>IPFS has a reputation for being slow, and it can be. The solution is boring but effective: run your own node, proxy through nginx. Adding a swarm connect to Pinata’s node right after upload—basically saying “hey, connect directly to this node that has my content”—took propagation from minutes to seconds.</p>

<p>The piece that ties it together is ENS. My <code class="language-plaintext highlighter-rouge">benwoodall.eth</code> has a content hash pointing to the IPFS CID. If my VPS dies, content is still on Pinata and accessible through ENS gateways. If Pinata dies, my VPS has everything pinned. The content persists independent of any single point of failure.</p>

<p>Is it worth it? For practical purposes, probably overkill for a blog. But I write about digital sovereignty and censorship resistance; it would feel hollow to host that on infrastructure that could disappear with a terms-of-service violation. Plus, every time I deploy, I get a little hit of satisfaction watching the CID propagate. My words, addressed by their content, retrievable by anyone who knows the hash. That’s pretty cool.</p>]]></content><author><name></name></author><category term="ipfs" /><category term="web3" /><category term="infrastructure" /><category term="self-hosting" /><summary type="html"><![CDATA[When I hit publish on this blog, something unusual happens. The words you’re reading don’t live on a server somewhere—at least, not in the traditional sense. They exist as content-addressed data scattered across a distributed network, pinned to nodes around the world, accessible through pathways that no single entity controls. This is IPFS, and it’s how I publish everything.]]></summary></entry><entry><title type="html">ENS as a digital identity gateway</title><link href="https://benwoodall.eth.limo/blog/ens-as-a-digital-identity-gateway/" rel="alternate" type="text/html" title="ENS as a digital identity gateway" /><published>2025-07-31T22:06:00-05:00</published><updated>2025-07-31T22:06:00-05:00</updated><id>https://benwoodall.eth.limo/blog/ens-as-a-digital-identity-gateway</id><content type="html" xml:base="https://benwoodall.eth.limo/blog/ens-as-a-digital-identity-gateway/"><![CDATA[<p><em>Why your <code class="language-plaintext highlighter-rouge">.eth</code> name might be the most important crypto purchase you never considered</em></p>

<p>When most people think about cryptocurrency, they think about money—Bitcoin, trading, getting rich quick. But what if I told you that one of the most transformative aspects of crypto has nothing to do with financial speculation and everything to do with something far more fundamental: <strong>your digital identity</strong>?</p>

<p>Enter ENS (Ethereum Name Service), a technology that’s quietly revolutionizing how we think about identity, privacy, and ownership in the digital age.</p>

<h2 id="what-is-ens-really">What is ENS, Really?</h2>

<p>Think of ENS as the phone book for the decentralized web. Just like how <code class="language-plaintext highlighter-rouge">google.com</code> is easier to remember than <code class="language-plaintext highlighter-rouge">142.250.191.14</code>, an ENS name like <code class="language-plaintext highlighter-rouge">alice.eth</code> is infinitely more human-friendly than <code class="language-plaintext highlighter-rouge">0x742d35Cc6b...</code> (a typical Ethereum address).</p>

<p>But ENS is so much more than just a convenience layer. It’s your <strong>sovereign digital identity</strong>—a name that you truly own, that no corporation can take away, and that works across the entire decentralized web.</p>

<h2 id="why-this-matters-more-than-you-think">Why This Matters More Than You Think</h2>

<h3 id="true-ownership">True Ownership</h3>
<p>When you register <code class="language-plaintext highlighter-rouge">yourname.eth</code>, you don’t just get a cool username. You get cryptographic proof of ownership that’s enforced by code, not corporate policy. Twitter can suspend your account, Instagram can delete your handle, but nobody can take your <code class="language-plaintext highlighter-rouge">.eth</code> name without your private key.</p>

<h3 id="universal-identity">Universal Identity</h3>
<p>Your ENS name works everywhere in web3. One identity across:</p>
<ul>
  <li>Cryptocurrency wallets and transactions</li>
  <li>Decentralized websites (try visiting <code class="language-plaintext highlighter-rouge">vitalik.eth</code> in a web3 browser)</li>
  <li>Social platforms built on blockchain</li>
  <li>Decentralized finance (DeFi) protocols</li>
  <li>NFT galleries and digital art platforms</li>
</ul>

<h3 id="your-decentralized-website">Your Decentralized Website</h3>
<p>ENS isn’t just a wallet address—it’s also your decentralized domain name. You can host entire websites on IPFS and point your ENS name to them, creating truly censorship-resistant web presence.</p>

<p>For example, I use <code class="language-plaintext highlighter-rouge">benwoodall.eth</code> to host my content on IPFS. You can visit it directly in web3-enabled browsers, or through traditional browsers using gateways like <a href="https://benwoodall.eth.link" target="_blank">benwoodall.eth.link</a>. This creates multiple ways for people to find your content:</p>
<ul>
  <li><strong>Web3 browsers</strong>: Direct access via <code class="language-plaintext highlighter-rouge">benwoodall.eth</code></li>
  <li><strong>Traditional browsers</strong>: Gateway access via <a href="https://benwoodall.eth.link" target="_blank">benwoodall.eth.link</a></li>
  <li><strong>IPFS networks</strong>: Distributed across thousands of nodes worldwide</li>
</ul>

<p>This redundancy means your content stays online even if traditional hosting fails. No single point of failure, no corporate overlord deciding whether your voice deserves to be heard.</p>

<h3 id="privacy-by-design">Privacy by Design</h3>
<p>Unlike traditional domain names, ENS gives you granular control over what information you share. You can associate your name with just a wallet address, or build a rich profile with social links, avatars, and contact information—all on your terms.</p>

<h2 id="the-perfect-web3-gateway">The Perfect Web3 Gateway</h2>

<p>ENS serves as an ideal introduction to web3 concepts because it’s:</p>

<p><strong>Immediately Useful</strong>: Even crypto beginners understand the value of a memorable name over a hexadecimal address.</p>

<p><strong>Non-Financial</strong>: You’re not gambling on price movements—you’re investing in digital infrastructure and identity.</p>

<p><strong>Educational</strong>: The registration process naturally introduces you to:</p>
<ul>
  <li>Wallet management</li>
  <li>Blockchain transactions</li>
  <li>Gas fees</li>
  <li>Smart contracts</li>
  <li>IPFS (for decentralized websites)</li>
</ul>

<p><strong>Future-Proof</strong>: As web3 grows, your ENS name becomes more valuable as digital real estate, not just as a speculative asset.</p>

<h2 id="beyond-money-identity-and-privacy">Beyond Money: Identity and Privacy</h2>

<p>This is where ENS reveals crypto’s true potential. We’re not just building a new financial system—we’re architecting a new internet where:</p>

<ul>
  <li><strong>Identity is portable</strong>: Your reputation and connections aren’t trapped in corporate silos</li>
  <li><strong>Privacy is programmable</strong>: You control exactly what information to share and with whom</li>
  <li><strong>Censorship is nearly impossible</strong>: Your identity lives on a decentralized network, not corporate servers</li>
</ul>

<p>In an age where tech giants control our digital identities, ENS offers something revolutionary: <strong>digital sovereignty</strong>.</p>

<h2 id="getting-started-your-first-step-into-web3">Getting Started: Your First Step Into Web3</h2>

<p>Ready to claim your digital identity? Here’s how:</p>

<ol>
  <li><strong>Choose your name</strong>: Check availability at <a href="https://ens.domains">ens.domains</a></li>
  <li><strong>Set up a wallet</strong>: MetaMask is beginner-friendly</li>
  <li><strong>Register your name</strong>: Annual fees are surprisingly affordable (usually $5-20/year depending on name length)</li>
  <li><strong>Configure your profile</strong>: Add your social links, avatar, and website</li>
  <li><strong>Share your identity</strong>: Start using <code class="language-plaintext highlighter-rouge">yourname.eth</code> instead of your wallet address</li>
</ol>

<h2 id="why-now">Why Now?</h2>

<p>We’re at an inflection point. The next wave of internet users will expect:</p>
<ul>
  <li>True ownership of their digital identity</li>
  <li>Control over their personal data</li>
  <li>Interoperability between platforms</li>
  <li>Censorship resistance</li>
</ul>

<p>ENS isn’t just a technical innovation—it’s a statement about the kind of internet we want to build. One where you own your identity, control your data, and can’t be de-platformed by corporate decree.</p>

<h2 id="the-bigger-picture">The Bigger Picture</h2>

<p>ENS represents something profound: proof that cryptocurrency is about much more than money. It’s about building infrastructure for human dignity in the digital age.</p>

<p>Your <code class="language-plaintext highlighter-rouge">.eth</code> name is more than a domain—it’s your flag planted in the digital frontier.</p>

<p>So the next time someone asks you about crypto, don’t start with Bitcoin prices or trading strategies. Start with ENS. Start with identity. Start with the revolutionary idea that in web3, you truly own your digital self.</p>]]></content><author><name></name></author><category term="ens" /><category term="web3" /><category term="privacy" /><category term="identity" /><summary type="html"><![CDATA[Why your .eth name might be the most important crypto purchase you never considered]]></summary></entry><entry><title type="html">YABB(Yet Another Ben Blog)</title><link href="https://benwoodall.eth.limo/blog/welcome-to-my-blog/" rel="alternate" type="text/html" title="YABB(Yet Another Ben Blog)" /><published>2025-07-26T13:00:00-05:00</published><updated>2025-07-26T13:00:00-05:00</updated><id>https://benwoodall.eth.limo/blog/welcome-to-my-blog</id><content type="html" xml:base="https://benwoodall.eth.limo/blog/welcome-to-my-blog/"><![CDATA[<h2 id="what-youll-find-here">What You’ll Find Here</h2>

<p>I plan to share thoughts and experiences about:</p>

<ul>
  <li><strong>Amateur Radio</strong>: My adventures with W0ODL, including SOTA activations, QRP operations, and learning CW</li>
  <li><strong>Coding</strong>: Projects in Ruby, Rust, Solidity, and other languages I’m working with</li>
  <li><strong>Privacy &amp; Cryptography</strong>: Thoughts on digital privacy, cryptocurrency, and security</li>
  <li><strong>General Musings</strong>: Whatever else catches my interest</li>
</ul>

<h2 id="technical-details">Technical Details</h2>

<p>This site is built with Jekyll and designed to be:</p>
<ul>
  <li>Static and IPFS-friendly</li>
  <li>Responsive and minimal</li>
  <li>Domain-aware (different branding for different access points)</li>
  <li>Easy to maintain</li>
</ul>

<p>The same codebase serves content for <code class="language-plaintext highlighter-rouge">benwoodall.com</code>, <code class="language-plaintext highlighter-rouge">bendoubleu.llyxx.me</code>, and <code class="language-plaintext highlighter-rouge">bendoubleu.eth</code> with appropriate branding adjustments.</p>

<h2 id="get-in-touch">Get in Touch</h2>

<p>Feel free to reach out via the usual channels. You can find my contact info and public keys linked in the navigation.</p>

<p>73,
Ben / W0ODL</p>]]></content><author><name></name></author><category term="meta" /><category term="amateur-radio" /><category term="coding" /><summary type="html"><![CDATA[What You’ll Find Here]]></summary></entry></feed>