<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
      <title>FalseBlue</title>
      <link>https://falseblue.com</link>
      <description>The personal site of Ben Craton: software developer, project manager, and cybersecurity professional.</description>
      <generator>Zola</generator>
      <language>en</language>
      <atom:link href="https://falseblue.com/rss.xml" rel="self" type="application/rss+xml"/>
      <lastBuildDate>Thu, 13 Jun 2024 12:09:27 -0400</lastBuildDate>
      <item>
          <title>The Robot Over My Shoulder</title>
          <pubDate>Thu, 13 Jun 2024 12:09:27 -0400</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/posts/the-robot-over-my-shoulder/</link>
          <guid>https://falseblue.com/posts/the-robot-over-my-shoulder/</guid>
          <description xml:base="https://falseblue.com/posts/the-robot-over-my-shoulder/">&lt;figure&gt;
    &lt;img src=&quot;cover.png&quot; alt=&quot;Illustration of a woman working at her computer while a large robot sits directly behind her, watching&quot; loading=&quot;lazy&quot;&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;In a recent announcement at Microsoft Build, the CEO told the world what everyone knew but no one wanted to say out loud: AI requires &lt;em&gt;your&lt;&#x2F;em&gt; data. Windows is getting a new AI assistant feature to help you remember what you were up to and search through whatever you did on your computer; this includes games you played, who you were on a call with, or what you might be interested in doing next. Sounds fantastic! The digital assistant that Silicon Valley has been dreaming of since HG Wells is finally available to the masses. And the first question on everyone’s mind was, according to numerous articles, blogs, and even my local morning radio DJs was, “Wait, how does it know all this about &lt;em&gt;me&lt;&#x2F;em&gt;?” followed quickly by “What the hell?” Hopefully I can help shed some light on what kind of hell this is turning out to be.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-does-ai-work&quot;&gt;How Does AI Work?&lt;&#x2F;h2&gt;
&lt;p&gt;I have no insider knowledge on how Microsoft is rolling out AI into Windows, only an understanding of the fundamentals behind the technology that these tools have been built on since the initial release of ChatGPT. In general, and at a very high level, the AI works like the auto-complete in your mobile keyboard of choice. The key difference is that these AIs can “know about” more than just text; they can “see” and “learn about” sound, images, or really any kind of information that can be stored in a structured way in a computer.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-a-robot-learns&quot;&gt;How a Robot Learns&lt;&#x2F;h3&gt;
&lt;p&gt;At its core, all machine learning is an exercise in trying to predict what comes next. In your mobile keyboard’s auto-complete, this is accomplished by a very simple method of prediction called a Markov-chain. Think of it as a big excel sheet with words in column A, and then in each column after that, another word and the probability that it comes after the word in column A. Now have every row be a word in the English language.&lt;&#x2F;p&gt;
&lt;p&gt;AI  training is the process where we figure out what those probabilities are. That would take a while to determine, right? You’d need to think about all the combinations that words would appear in. We could feed it all the books, newspapers, and webpages you could find. It’s daunting, but doable.&lt;&#x2F;p&gt;
&lt;div class=&quot;admonition note&quot;&gt;
    &lt;div class=&quot;admonition-icon admonition-icon-note&quot;&gt;&lt;&#x2F;div&gt;
    &lt;div class=&quot;admonition-content&quot;&gt;
        &lt;strong class=&quot;admonition-title&quot;&gt;NOTE&lt;&#x2F;strong&gt;
        &lt;p&gt;&lt;strong&gt;Key Terms&lt;&#x2F;strong&gt;&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;The books etc are the “Corpus” or library of source material&lt;&#x2F;li&gt;
&lt;li&gt;The Excel sheet is an “AI model”&lt;&#x2F;li&gt;
&lt;li&gt;The formula is an “AI Assistant”&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;

    &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;In the end, we will have our excel sheet. Since we’ve calculated all these probabilities once, we can save the sheet and use it again and again without needing a rebuild. Now we can get to the predictions and figure out a formula for “given any word, give me a word that’s likely to come next.”&lt;&#x2F;p&gt;
&lt;p&gt;You may have noticed some major limitations with our Excel sheet example, though. We can only check what word might follow some other word. What about the case where you’ve been texting “I love” to someone and auto-complete helpfully suggests not only “you” but also “pizza,” “puppies,” or “your ex’s name”?&lt;&#x2F;p&gt;


&lt;noscript&gt;
    &lt;strong&gt;⚠️ JavaScript is required to render the diagram.&lt;&#x2F;strong&gt;
&lt;&#x2F;noscript&gt;
&lt;pre class=&quot;mermaid invertible-image&quot;&gt;
    graph TD
  A[I] --&gt;|0.5| B[love];
    A --&gt;|0.4| C[want];
    A --&gt;|0.1| D[think];
    B --&gt;|0.9| E[you];
    B --&gt;|0.1| F[your ex&#x27;s name];
&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Simple Markov Chain&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;context-matters&quot;&gt;Context Matters&lt;&#x2F;h3&gt;
&lt;p&gt;Clearly, “love” has different meanings based on context and we need more than just one word to figure out the next appropriate word. But now we’re going to need an Excel sheet for every word-A, a row for every word-B, and columns for all the possibilities. Our Excel file just got massive. What about three words? 20? Ok, we’ll need a different approach.&lt;&#x2F;p&gt;
&lt;p&gt;In step the current AI models. At their core, all of them are prediction models based on a corpus of previously assembled data that can “look back” much, much further on more than just words. They are fancier and beautiful mathematically, but the models are big sets of probabilities that one thing might follow another.&lt;&#x2F;p&gt;
&lt;p&gt;All the investment and media coverage around how these AIs are trained is rooted in what the “things” are and what content was used to figure out those probabilities. The concerns around privacy are (rightly) rooted in whether the proprietary information you entrusted to a company is now a “probable next thing” in a stranger’s document. The fears about hallucinations and AI malpractice are the same as accidentally getting your ex’s name sent to your spouse.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;enter-the-assistant&quot;&gt;Enter the Assistant&lt;&#x2F;h3&gt;
&lt;p&gt;The assistant, or agent, or robot, or digital therapist is the Excel formula on steroids. It can not only take in what you’ve written so far in your text, but what time you’re writing it, where you are, what apps are open, who you’re talking to, where they are or might be, the weather, the news, your temperament, and so on. This one-time snapshot is the “one-shot” colloquially. Take all that context, feed it into your formula and it gives you a likely next word (or paragraph).&lt;&#x2F;p&gt;


&lt;noscript&gt;
    &lt;strong&gt;⚠️ JavaScript is required to render the diagram.&lt;&#x2F;strong&gt;
&lt;&#x2F;noscript&gt;
&lt;pre class=&quot;mermaid invertible-image&quot;&gt;
    flowchart TB
subgraph Sources

    A(📝 Current Text)
    B(🕗 Time)
    C(📍 Location)

    direction LR
    D(📱 Open Apps)
    E(👥 Contacts)
    F(⛅ Weather)

end

A &amp; B &amp; C &amp; D &amp; E &amp; F --&gt; G
G(🧑‍💼 AI Assistant)

G --&gt;|Produces| H(💬 Next Word Prediction)
&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;Hypothetical AI Assistant&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Note that we never saved that context. The model, or “excel sheet,” didn’t change. Nothing &lt;em&gt;has&lt;&#x2F;em&gt; to be saved to get the result we are after.&lt;&#x2F;p&gt;
&lt;p&gt;But we could.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;throwing-a-robot-out-with-the-bath-water&quot;&gt;Throwing a Robot out with the Bath Water?&lt;&#x2F;h2&gt;
&lt;p&gt;Hopefully, I’ve helped provide a solid basis for how these AI tools work in general. The devil, as they say, is in the details. And with so much data, it’s details all the way down.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;sourcing-locally-is-usually-fine&quot;&gt;Sourcing Locally is Usually Fine&lt;&#x2F;h3&gt;
&lt;p&gt;As with farmers markets, the closer you get to the source, the more you know about where your data comes from and how it’s been processed. When a company like Microsoft says that “the model is on your computer,” what they mean is the Excel sheet is saved on your hard drive somewhere. When they say, “it will know about what you are doing and what you’ve been up to,” they are saying “we’re going to use things like system logs, documents, and files that already exist, plus what’s on your screen as inputs to the formula.”&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;As stated,&lt;&#x2F;em&gt; that’s usually fine. But, what if, say, you wanted to keep the processing of all those probabilities, based on everything your computer can offer, for later? We’d probably not like our laptop battery draining every 10 minutes as it crunches numbers. That’s where things get tricky.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-is-saved-and-how&quot;&gt;What is Saved and How&lt;&#x2F;h3&gt;
&lt;p&gt;To recap, we have the base model on our hard drive along with all our files provided to us by a vendor like Microsoft. We’d like to personalize it with the content that is available on our computer. So that’s what we do. We create a new “baby” model based only on the content on the machine. Then we update our assistant formula to use both the base model &lt;em&gt;and&lt;&#x2F;em&gt; our baby model when making personalized predictions.&lt;&#x2F;p&gt;
&lt;p&gt;But that baby model needs to be secure. It has a probability record of &lt;em&gt;everything&lt;&#x2F;em&gt; on our computer. It &lt;em&gt;has&lt;&#x2F;em&gt; to be secure.&lt;&#x2F;p&gt;
&lt;p&gt;Thankfully, most modern devices (and specifically ones that run Windows 11) have what’s called a TPM (trusted platform module) that uses public-key cryptography to encrypt and decrypt files like our model. This is unique to our device and &lt;em&gt;should&lt;&#x2F;em&gt; keep the baby model secure from all but the most determined state-sponsored hacker.&lt;&#x2F;p&gt;


&lt;noscript&gt;
    &lt;strong&gt;⚠️ JavaScript is required to render the diagram.&lt;&#x2F;strong&gt;
&lt;&#x2F;noscript&gt;
&lt;pre class=&quot;mermaid invertible-image&quot;&gt;
    %%{ init: { &#x27;flowchart&#x27;: { &#x27;curve&#x27;: &#x27;basis&#x27;, &#x27;htmlLabels&#x27;: false,  } } }%%
flowchart TB
    M --&gt;|&quot;`Searches`&quot;|V
    V -.-&gt;|&quot;`_Maybe also_ Provides`&quot;| C &amp; TPM

    subgraph C[&quot;`**Our Computer**`&quot;];
        AI --&gt;|&quot;Uses&quot;|M &amp; B
        subgraph E[&quot;🔒 Encrypted&quot;];
            B --&gt;|&quot;`Searches`&quot;|D
            D -.-&gt;|&quot;`&#x27;Learning&#x27;`&quot;|B
            B(&quot;`🤖 &#x27;Baby&#x27; (local) Model`&quot;)
            D[(&quot;`💾 Our Personal Data`&quot;)]
        end
        TPM(&quot;🔐 TPM&quot;) --&gt;|&quot;Encrypts&quot;|E
    end
    Me(&quot;🤓 Me&quot;) --&gt;|&quot;Asks&quot;|AI
    V(&quot;🏢 AI Provider&quot;) --&gt;|&quot;Provides&quot;| AI(&quot;🧑‍💼 AI Assistant&quot;) &amp; M(&quot;🤖 Vendor Model&quot;)
&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;em&gt;An “ideal” AI set up&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;h3 id=&quot;but-microsoft&quot;&gt;But Microsoft&lt;&#x2F;h3&gt;
&lt;p&gt;Here’s where the public writ large seems to bristle at the Built AI announcement, even if they aren’t sure exactly why. If I may be so bold as to speak for the layman, the issue lies with all the “yeah but“s:&lt;&#x2F;p&gt;
&lt;h4 id=&quot;yeah-but-companies-like-microsoft-and-apple-also-make-the-devices-these-things-run-on-so-how-could-we-trust-they-don-t-have-access-to-this-tpm&quot;&gt;“Yeah, but companies like Microsoft and Apple also make the devices these things run on, so how could we trust they don’t have access to this TPM?”&lt;&#x2F;h4&gt;
&lt;p&gt;You must trust them based on their published documentation and marketing.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;yeah-but-can-t-they-just-send-the-saved-file-back-to-headquarters&quot;&gt;“Yeah, but can’t they just send the saved file back to headquarters?”&lt;&#x2F;h4&gt;
&lt;p&gt;They absolutely can and do. It’s usually based on the privacy policy or user agreement which is miles long and written (deliberately in too many cases) in legalese like a contract (which it is).&lt;&#x2F;p&gt;
&lt;h4 id=&quot;yeah-but-won-t-they-train-the-models-they-send-out-with-my-model&quot;&gt;“Yeah, but won’t they train the models they send out with my model?”&lt;&#x2F;h4&gt;
&lt;p&gt;They aren’t supposed to unless you’ve agreed to it.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;yeah-but-how-did-they-train-it-to-begin-with&quot;&gt;“Yeah, but how did they train it to begin with?”&lt;&#x2F;h4&gt;
&lt;p&gt;Using scraped internet websites (under litigation), bulk-data sales (now illegal in California), metrics and content from their free-tiers of services (usually allowed in lieu of cash for continued use). The list goes on (and can you see a pattern)?&lt;&#x2F;p&gt;
&lt;h4 id=&quot;yeah-but-how-are-they-going-to-keep-this-base-model-updated&quot;&gt;“Yeah, but how are they going to keep this base model updated?”&lt;&#x2F;h4&gt;
&lt;p&gt;An excellent question. Does it need updated? If so, what’s going to feed in the future if we, the consumers, start exercising our rights to restrict that use? Won’t the models stagnate? It remains to be seen.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;consumers&quot;&gt;Consumers&lt;&#x2F;h3&gt;
&lt;p&gt;Question the use of &lt;em&gt;your&lt;&#x2F;em&gt; data. Data about you, your family and loved ones is being used by these  companies offering services. Some of them are taking your concerns seriously with dedicated people keeping these risks at heart while still offering great AI services, but not all of them. Maybe not even a majority of them.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;founders&quot;&gt;Founders&lt;&#x2F;h3&gt;
&lt;p&gt;Security and privacy is a strength in selling. If early morning DJs in Indiana are talking about it, your customers are thinking about it. It is a boon to have an upfront and honest commitment to your ultimate source of income about how you use the data they entrust to you.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;product-and-security-leaders&quot;&gt;Product and Security Leaders&lt;&#x2F;h3&gt;
&lt;p&gt;Know what you are requiring of the users to make your amazing features work and &lt;em&gt;why&lt;&#x2F;em&gt;. Let your users know about it in a proactive manner, not hiding it behind a labyrinth of micro-service options that change every full moon.&lt;&#x2F;p&gt;
&lt;p&gt;As I have advised since GPT mania in 2022:&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;You wouldn’t let your keyboard auto-complete do anything on your behalf without your oversight. Don’t let “AI.”&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;hr &#x2F;&gt;
&lt;p&gt;Editor’s note: Revised to add visualisations for clarity&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Quit Reading QR Codes without Thinking</title>
          <pubDate>Thu, 04 Apr 2024 20:12:09 -0400</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/posts/qr-code-safety/</link>
          <guid>https://falseblue.com/posts/qr-code-safety/</guid>
          <description xml:base="https://falseblue.com/posts/qr-code-safety/">&lt;figure&gt;
    &lt;img src=&quot;cover.png&quot; alt=&quot;Illustration of a person with headphones scanning a giant QR code displayed on a phone-shaped street sign&quot; loading=&quot;lazy&quot;&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;A while back I was in Seattle visiting my brother. My wife and I did the normal touristy things around downtown: go up the Needle, look at the museums, gawk at The Mountain, etc. Though while riding the monorail for the second time, back through the dense urban forest, I noticed a poster for some charity or other whose call to action was a giant QR code.&lt;&#x2F;p&gt;
&lt;p&gt;Many of us probably would pass it by without notice. Those few that found the plea for contributions and the cause worthy enough to scan a code no doubt didn’t think twice about it. After all, their phone was out anyway doing tik-toks or planking or whatever kids and bored adults do these days. But consider this. Anyone can throw up a poster in a subway or bus. Anyone can &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;goqr.me&#x2F;&quot;&gt;make a QR code&lt;&#x2F;a&gt; linking to any website. And unfortunately, anyone can lie.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-are-qr-codes-really&quot;&gt;What Are QR Codes Really?&lt;&#x2F;h2&gt;
&lt;p&gt;QR codes are essentially &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.qrcode.com&#x2F;en&#x2F;about&#x2F;standards.html&quot;&gt;fancy barcodes&lt;&#x2F;a&gt; like those you’d use at the store to check out. Most product (&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gs1us.org&#x2F;upcs-barcodes-prefixes&#x2F;guide-to-upcs&quot;&gt;UPC&lt;&#x2F;a&gt;) codes are simply a number, which is almost always written below it for verification.&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;barcode.png&quot; alt=&quot;barcode&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;UPC Barcode&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;Because a QR code is two-dimensional, it can hold more information than a &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.gs1us.org&#x2F;upcs-barcodes-prefixes&#x2F;what-is-a-gtin&quot;&gt;number less than a hundred trillion&lt;&#x2F;a&gt;. In fact, they can hold many numbers which can be interpreted by your phone as text, wifi password, or &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=ExwqNreocpg&quot;&gt;even a game&lt;&#x2F;a&gt;. I’ve used them for &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.qr-code-generator.com&#x2F;blog&#x2F;qr-code-inventory-management&#x2F;&quot;&gt;inventory documentation&lt;&#x2F;a&gt; for myself.&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;qr-code.png&quot; alt=&quot;qr code&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;QR Code&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;should-i-quit-relying-on-them&quot;&gt;Should I Quit Relying on Them?&lt;&#x2F;h2&gt;
&lt;p&gt;No more than you should trust a normal link you’d click on to open a website. In fact, even less so. When was the last time you felt the urge to manually type in a web address into the url? Probably only when you had an existing problem and saw a billboard or flyer that would undeniably address that need: communicated in the very limited space available. QR codes’ &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.uniqode.com&#x2F;blog&#x2F;qr-code-insights&#x2F;5-reasons-why-qr-codes-are-still-effective&#x2F;&quot;&gt;selling point&lt;&#x2F;a&gt; in marketing and communication is to lower the barrier to action or information. And without a doubt, for that, they are great!&lt;&#x2F;p&gt;
&lt;p&gt;However, lowering a barrier isn’t an excuse to remove it entirely for convenience. While typing in a URL was tedious, it made us mindful of what we were about to interact with. While a QR code is quick and easy, we still need to pause before clicking through our camera to the address.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;how-to-keep-quite-reasonably-safe&quot;&gt;How to Keep Quite Reasonably Safe&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;qualitatively-read-before-scanning&quot;&gt;Qualitatively Read before Scanning&lt;&#x2F;h3&gt;
&lt;p&gt;The context always matters. A QR code on the menu at your &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.upmenu.com&#x2F;qr-code-menu&#x2F;&quot;&gt;local diner&lt;&#x2F;a&gt; probably is not malicious. It would be quite a conspiracy to forge a delicious line-up to get you onto a malware site. A billboard is often the same. The visibility and cost is way too high for a common criminal to exploit it without getting turned over by the ad agency.&lt;&#x2F;p&gt;
&lt;p&gt;It is much simpler to attack using plain paper with a generic message in a public space. If you see QR codes on stickers, flyers, or anything the teenager in your life can purchase at Wal-Mart and print onto, perhaps give them a pass. If you see an identical sticker etc again in a completely different setting and your interest is again piqued, then it might be worth pulling out the phone for step two.&lt;&#x2F;p&gt;
&lt;p&gt;Also glance below or around the code. If there is no alternative URL and there’s enough space that there’s no reason it &lt;em&gt;couldn’t&lt;&#x2F;em&gt; have been there, then someone made a choice to omit it. Question why and move on with life.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;quickly-read-the-link&quot;&gt;Quickly Read the Link&lt;&#x2F;h3&gt;
&lt;p&gt;Your phone should preview the code’s link for you to authorize opening a browser.&lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-1-1&quot;&gt;&lt;a href=&quot;#fn-1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; Usually the preview is tiny, showing only the first few characters of the link. Marketers and scammers alike know this and often use link shorteners so that you can see their brand (or not). You can see this with &lt;code&gt;yt.be&lt;&#x2F;code&gt;, &lt;code&gt;fb.me&lt;&#x2F;code&gt;, etc. If the link looks like it is strongly associated with the brand or organization on the material, then you can proceed to step three.&lt;&#x2F;p&gt;
&lt;p&gt;If the QR code is using a generic link shortener such as &lt;code&gt;bit.ly&lt;&#x2F;code&gt;, or something that doesn’t look right, stop. Your curiosity can be satiated by typing in a url manually.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;question-redirects&quot;&gt;Question Redirects&lt;&#x2F;h3&gt;
&lt;p&gt;If you got this far in the 0.75 seconds since you began this process, you’re jumping to a browser and the url bar is updating a few times. That’s the url “un-shortening,” so to speak. Going to &lt;code&gt;yt.be&lt;&#x2F;code&gt; would expand to &lt;code&gt;youtube.com&lt;&#x2F;code&gt; for example. That redirection causes a page refresh. One is normal. Two? Probably some kind of single-sign-on authentication and also fine. Three to five? Ok, maybe the poor developers have to use &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=y8OnoxKotPQ&quot;&gt;microservices&lt;&#x2F;a&gt; and that’s the price we pay. More than that? You should probably lock your phone now if you’re around others because there’s a good chance where you’re going isn’t safe for work. &lt;sup class=&quot;footnote-reference&quot; id=&quot;fr-2-1&quot;&gt;&lt;a href=&quot;#fn-2&quot;&gt;2&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt;&lt;&#x2F;p&gt;
&lt;p&gt;After the page loads, double-check the url that you landed on. All mobile-browsers that I’m aware of keep the url bar displayed until you start scrolling down. Take a last glance. Does the url make sense based on that original material you read? Is it a secure connection? Is the page what you expected? If yes to all of these, carry on. If not, close the tab, silently curse the greed of others, and get on with the day.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;quintessential-recap&quot;&gt;Quintessential Recap&lt;&#x2F;h2&gt;
&lt;p&gt;Ok, I’ll stop with the alliteration. If you take nothing else from this piece, take this: &lt;strong&gt;don’t let convenience blind you to risk&lt;&#x2F;strong&gt;. In those few seconds while passing a tree, the 5g cuts out, and your phone is deciding if it really can do anything without the cloud, think what you could have done as a rebellious child with this tool at your disposal; what pranks you would have pulled; and what Charles Ponzi would have attempted.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;URLs, information, and food are all the same. We should consider what we put into our bodies and devices respectively.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;em&gt;- Abraham Lincoln&lt;sub&gt;probably&lt;&#x2F;sub&gt;&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;section class=&quot;footnotes&quot;&gt;
&lt;ol class=&quot;footnotes-list&quot;&gt;
&lt;li id=&quot;fn-1&quot;&gt;
&lt;p&gt;If it does not, and it automatically opens for you for any QR code you point it at, check with your phone’s manufacturer’s support website on how to disable that behavior. &lt;a href=&quot;#fr-1-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;li id=&quot;fn-2&quot;&gt;
&lt;p&gt;And that’s not just glib advice. Locking your phone will stop the browser from continuing down a rabbit-hole of sin and viruses until you unlock it again. I would suggest locking your phone and then immediately powering it off and restarting it. That will kill the browser. &lt;a href=&quot;#fr-2-1&quot;&gt;↩&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;&#x2F;section&gt;
</description>
      </item>
      <item>
          <title>Self Hosting Update, or &quot;Where did X go?&quot;</title>
          <pubDate>Sat, 09 Mar 2024 00:00:00 +0000</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/posts/self-hosting/</link>
          <guid>https://falseblue.com/posts/self-hosting/</guid>
          <description xml:base="https://falseblue.com/posts/self-hosting/">&lt;figure&gt;
    &lt;img src=&quot;cover.jpg&quot; alt=&quot;A living room being slowly consumed by a homelab: glowing server racks, bundles of cable across the ceiling, and one increasingly cornered couch&quot; loading=&quot;lazy&quot;&gt;
&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;I started my tech journey back in the ’90s writing HTML by hand. Ever since I started doing tech work for money in 2006, I’ve been trying to keep abreast of the systems and machines I’ve helped maintain and manage by doing it myself in a home lab. I credit where I am today on essentially taking the same tools from work and breaking my home network, much to my wife’s chagrin.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;keeping-costs-low&quot;&gt;Keeping Costs Low&lt;&#x2F;h2&gt;
&lt;p&gt;Even though I’ve been self-hosting since 2006, I had, until 2013, no real server in the house. I rented machines in data-centers for cheap, having known the best deals from working web-hosting support. I moved all of my hosting literally in-house for the better part of a decade. This saved tremendously on monthly hosting costs, even if the up-front cost of hardware was a little pricy.&lt;&#x2F;p&gt;
&lt;p&gt;However, as what I worked on professionally changed in complexity, so did my home-lab and my projects. My costs were measured in time instead of dollars, and they were annoying, but manageable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;security-and-exposure&quot;&gt;Security and Exposure&lt;&#x2F;h2&gt;
&lt;p&gt;As my position and responsibilities grew, the less I could focus on my hobby projects in long-stretches as I had in the past. Also, the more I became a potential target for attackers. After 2020 and the shuttering of physical offices in my city, the less I liked having my work and personal devices on the same network as the hosting services (even with VLANs and VPN).&lt;&#x2F;p&gt;
&lt;p&gt;Since my CISSP exam in January of 2024, I decided to essentially pull the plug on all non-essential hosting until I’ve had time to vet the services and get them into a self-compliant state. If you want to know the state of a service, see below.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;aniki-fm&quot;&gt;Aniki.fm&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;projects&#x2F;anikifm&#x2F;&quot;&gt;Project page&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Status: Down&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;Aniki was originally just a wordpress &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;blubrry.com&#x2F;&quot;&gt;blubrry&lt;&#x2F;a&gt; site. It eventually evolved into a more dynamic site that had a wordpress backend and a &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;v2.nuxt.com&#x2F;&quot;&gt;nuxt v2&lt;&#x2F;a&gt; frontend. However, I built a new version in 2020&#x2F;2021, and then let the code sit for a long while. As of March 2024, the project no longer builds at all and the kubernetes infrastructure that I used to host it, while useful for keeping up with my DevOps guys, was not useful in being maintainable in the slightest (k8s is a castle of glass, in my honest opinion).&lt;&#x2F;p&gt;
&lt;h3 id=&quot;future&quot;&gt;Future&lt;&#x2F;h3&gt;
&lt;p&gt;Our recording is currently on hiatus for present while I, at least, get some long-term life stuff sorted out. I would like to convert the site to &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;castopod.com&#x2F;en&quot;&gt;castopod&lt;&#x2F;a&gt; or similar should we continue. Until then, recordings are available on &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;open.spotify.com&#x2F;show&#x2F;0CDLvxkVrQZ8xB3GpAAx9e&quot;&gt;Spotify&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;magic-falseblue-com&quot;&gt;Magic.Falseblue.com&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;projects&#x2F;magic-card-generator&#x2F;&quot;&gt;Project page&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Status: Down&lt;&#x2F;p&gt;
&lt;h3 id=&quot;rationale-1&quot;&gt;Rationale&lt;&#x2F;h3&gt;
&lt;p&gt;While the magic card site started as a simple php form, it evolved to have multiple backend-services, including an AI NSFW photo filter beginning in ~2015. The site never had user-management by design.&lt;&#x2F;p&gt;
&lt;p&gt;As of January 2024, more than 250,000 cards had been created by people all over the world.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;future-1&quot;&gt;Future&lt;&#x2F;h3&gt;
&lt;p&gt;I doubt this will return. If you found it fun, let me know!&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Why We Check</title>
          <pubDate>Thu, 22 Feb 2024 12:26:53 -0500</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/posts/why-we-check/</link>
          <guid>https://falseblue.com/posts/why-we-check/</guid>
          <description xml:base="https://falseblue.com/posts/why-we-check/">&lt;figure&gt;
    &lt;img src=&quot;cover.jpg&quot; alt=&quot;Two people at a desk with laptops, reviewing hand-drawn diagrams on paper&quot; loading=&quot;lazy&quot;&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;What comes to mind when you hear that a security audit is underway? Nervousness? Trepidation? It would be surprising if you found the news exhilarating, but must we associate a security audit purely with negativity?&lt;&#x2F;p&gt;
&lt;p&gt;We are all human and the fear of “being found out” is one that haunts us our whole lives. When a security audit is announced, our minds immediately go to our past failures, the mountain of work in front of us, and intimate knowledge of where we could have done better. However, the purpose of an audit is not to cast judgement or find fault, but instead to put aside that task list, discuss those mistakes, and bring weaknesses to the forefront.&lt;&#x2F;p&gt;
&lt;p&gt;In school, exams were always a stressful time. Would you pass or would you fail? The exam was the focus and we were perhaps myopic to the real purpose of those tests: to find where your weaknesses were and train those skills further. In football, cricket, or any sport, to succeed and dominate the competition, discovering where you could improve is always the key differentiator.&lt;&#x2F;p&gt;
&lt;p&gt;Audits are a chance for us to reflect on our progress, our strategy, and our prowess. Yes, they can bring on stress and anxiety, but if we are brave enough to face the threats and competition in the market that we do on a daily basis, we can face our opportunities for growth and maturity with the same confidence.&lt;&#x2F;p&gt;
&lt;p&gt;Photo by &lt;a href=&quot;https:&#x2F;&#x2F;unsplash.com&#x2F;@homajob?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash&quot;&gt;Scott Graham&lt;&#x2F;a&gt; on &lt;a href=&quot;https:&#x2F;&#x2F;unsplash.com&#x2F;photos&#x2F;person-holding-pencil-near-laptop-computer-5fNmWej4tAA?utm_content=creditCopyText&amp;utm_medium=referral&amp;utm_source=unsplash&quot;&gt;Unsplash&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Cirno</title>
          <pubDate>Wed, 24 Jan 2024 12:05:51 -0500</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/posts/cirno/</link>
          <guid>https://falseblue.com/posts/cirno/</guid>
          <description xml:base="https://falseblue.com/posts/cirno/">&lt;figure&gt;
    &lt;img src=&quot;&amp;#x2F;images&amp;#x2F;cirno.jpg&quot; alt=&quot;Fan art of Cirno, a small blue-haired ice fairy, looking extremely confident&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;The strongest.&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;h2 id=&quot;who-is-she&quot;&gt;Who is She?&lt;&#x2F;h2&gt;
&lt;p&gt;So what’s up with this image on the site? This is &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.touhouwiki.net&#x2F;wiki&#x2F;Cirno&quot;&gt;Cirno&lt;&#x2F;a&gt; from the &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Touhou_Project&quot;&gt;Touhou&lt;&#x2F;a&gt; series of games. She is a little ice fairy you meet in several of the games who believes that she is the “strongest” despite being introduced as a mid-boss for level 1. This fan art of her by an unknown (to me) artist enchanted me when I saw it. She’s so full of confidence and so unaware of her own weakness while, in my mind’s eye, spouting off nonsense to a patronizing and exasperated audience.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-why-your-profile-picture&quot;&gt;But why Your Profile Picture?&lt;&#x2F;h2&gt;
&lt;p&gt;tl;dr I do what I want.&lt;&#x2F;p&gt;
&lt;p&gt;Back when I worked at EDS&#x2F;HPE, we were required to use the enterprise equivalent of MSN Messenger. I was fresh out of college, rebellious, but not provocative. At some point we were required to have an image in the app. Being private by nature, I didn’t like the idea of the entire corporate directory knowing what I look like. Plus, it wasn’t fair to my co-workers to expose them to my visage on a daily basis.&lt;&#x2F;p&gt;
&lt;p&gt;The corporate IT guys did the best they could with what they were given. You had to use your corporate profile image. No uploading a custom one. Oh dear, but what was this? In the settings, while profile images were greyed out, there was a field to allow for a remote image, in retrospect, probably there to facilitate subsidiary domains. Regardless, having my own server, I went about hacking together a script that not only would host my remote image, but change it on a daily basis.&lt;&#x2F;p&gt;
&lt;p&gt;I was big into Touhou at the time. Something about the indie-dev spirit and the wildly creative fan-base with virtually no limits on creative license appealed to me. I used a bunch of character images from the games as my pool of avatars. Other than the occasional inquiry from a co-worker who found it silly, no one noticed for my entire tenure there.&lt;&#x2F;p&gt;
&lt;p&gt;It’s since then become my thing. The Cirno image here specifically started when I was at Arxan and had to settle for one image since they used Slack. This is the one I landed on.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-s-how-i-try-to-see-myself&quot;&gt;It’s how I Try to See Myself&lt;&#x2F;h3&gt;
&lt;p&gt;While I may have letters after my name and a lot of experience, I’m still one man on current-year planet earth. Since one of my hobbies is just learning for the sake of it, I’m confronted daily with things I didn’t know or was mistaken about. I like to remind myself that confidence does not equate correctness. Having that image front and center every working day helps with that.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;it-s-how-i-choose-to-have-others-see-me-digitally&quot;&gt;It’s how I Choose to Have Others See Me Digitally&lt;&#x2F;h3&gt;
&lt;p&gt;I’m well aware that post-2020, the profile picture is often the first thing your co-workers, or even the public, see and associate with you. I’m still that private guy I was post college, even more so now with the CISSP. I put myself in the shoes of a brand-new dev who I need to ask a question: how would getting a ping from this image sit with me?&lt;&#x2F;p&gt;
&lt;p&gt;My answer is: I would be a lot less terrified of a leader who chooses to be silly over one who chooses an image that exudes power. Let me be seen as clownish. It breaks down a wall if nothing else. And if they see me as I see me, they will take my advice as a fellow imperfect human, and treat it with their own critical eye.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;but-also&quot;&gt;But also&lt;&#x2F;h2&gt;
&lt;p&gt;it’s funny&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>A History Degree?</title>
          <pubDate>Tue, 23 Jan 2024 12:45:37 -0500</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/posts/a-history-degree/</link>
          <guid>https://falseblue.com/posts/a-history-degree/</guid>
          <description xml:base="https://falseblue.com/posts/a-history-degree/">&lt;figure&gt;
    &lt;img src=&quot;cover.jpg&quot; alt=&quot;An open book whose pages glow with starlit text, before ancient temple ruins under a night sky&quot; loading=&quot;lazy&quot;&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;I’ve told this story many times, but might as well put it here. I started at Purdue in the nuclear engineering program for NROTC with the intent of becoming a naval officer working on “really cool physics stuff.” I had a full ride scholarship to do so but…&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;I was not prepared for the amount of outside-class work required.&lt;&#x2F;li&gt;
&lt;li&gt;I was not prepared for the physical toll of P.T. on top of the academic load.&lt;&#x2F;li&gt;
&lt;li&gt;I was not prepared for being taught physics and calculus by (some) professors who were not native English speakers and who were not interested in teaching.&lt;&#x2F;li&gt;
&lt;li&gt;The commitment required for the commission was 4 years longer that I had been initially lead to believe.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Well what do you do at the end of the first semester when you’re presented with the choice of “you can stay in the NROTC program and we’ll pay for your education, but you have to do this for 10-12 more years,” “you can decide to drop out of the NROTC program later, but then you will have to enlist after college,” or “you can drop out of the NROTC program now and pay for college yourself, with no guarantee of a job in the United States after college.” I chose the last option.&lt;&#x2F;p&gt;
&lt;p&gt;I finished out the first year course schedule, but dropped out of NROTC and gave up the scholarship after the first semester. In the second semester I found the Purdue anime club and a sub-group called boilermaker-anime. They were the ones that re-sparked the interest in computers and programming that I had in middle school. My goal changed to getting into the computer science program and doing something along the lines of high-performance computing (beowulf clusters were the cool thing at the time).&lt;&#x2F;p&gt;
&lt;p&gt;My second year was spent trying to convince the Purdue computer science department to let me in. It was a college transfer away from engineering so it came with a lot of red tape. I was a good boy and did as instructed, but after a year of being told “no you need more of these classes that cover material you learned while sitting on the couch in your apartment,” I was getting frustrated and running up against graduating on time and in budget.&lt;&#x2F;p&gt;
&lt;p&gt;With two years left, I looked through the course catalog and found that a B.A. in history would only require those two more years and allow me to essentially go learn whatever I wanted in the process using required electives. So it was decided that with only a single extra semester, I could graduate on time and in budget with a degree in history. I used that time to learn about the history of science and technology, especially concerning the development of nuclear weapons and energy. Most of the electives were taken up by earth and atmospheric science and cosmology classes because you cant keep a good nerd down.&lt;&#x2F;p&gt;
&lt;p&gt;That last semester I only had one class, so I took a job at a local outsourced-tech support company. One thing led to another and here I am.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>LastChoice - A Zig Journey to Data Recovery</title>
          <pubDate>Mon, 30 Oct 2023 00:00:00 +0000</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/projects/lastchoice/</link>
          <guid>https://falseblue.com/projects/lastchoice/</guid>
          <description xml:base="https://falseblue.com/projects/lastchoice/">&lt;!-- TODO(ben): when the &quot;Data Archeology&quot; blog post publishes
     (content&#x2F;posts&#x2F;lastchoice-data-archeology&#x2F;), link it from here. --&gt;
&lt;h2 id=&quot;why-this-exists&quot;&gt;Why This Exists&lt;&#x2F;h2&gt;
&lt;p&gt;My dad was an early adopter. He ran his business and much of his life through &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;winworldpc.com&#x2F;product&#x2F;pfs-first-choice&#x2F;3x&quot;&gt;PFS: First Choice&lt;&#x2F;a&gt;, an all-in-one DOS suite from the late ’80s, and over the years its little flat-file database accumulated things worth keeping. Then his old computer finally died, and the data was stranded in &lt;code&gt;.FOL&lt;&#x2F;code&gt; files that nothing modern can open. The recovery options I found were either paid services or tools you’d need to already be a programmer to use.&lt;&#x2F;p&gt;
&lt;p&gt;So: a family IT ticket, escalated to engineering.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;enter-lastchoice-and-zig&quot;&gt;Enter LastChoice (and Zig)&lt;&#x2F;h2&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tsunaminoai&#x2F;lastchoice&quot;&gt;LastChoice&lt;&#x2F;a&gt; is a command-line tool that reads FirstChoice &lt;code&gt;.FOL&lt;&#x2F;code&gt; databases and exports them to formats that will outlive us all (SQLite, CSV, JSON). I wrote it in &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;ziglang.org&quot;&gt;Zig&lt;&#x2F;a&gt;, partly because a binary file format parser is a great fit for a systems language, and mostly because I wanted an excuse to learn Zig properly.&lt;&#x2F;p&gt;
&lt;p&gt;It turned out to be a good pairing. Parsing a 1980s block-structured format (128-byte blocks, records that span blocks, a schema you have to reconstruct) is exactly the kind of work where Zig’s explicit memory management keeps you honest. No garbage collector to hide behind; you know where every byte lives, which is rather the point when the bytes are your dad’s records.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-came-of-it&quot;&gt;What Came of It&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The data came back.&lt;&#x2F;strong&gt; Records that would have been lost are now in a SQLite file my dad’s newer software can actually use. That felt better than shipping most professional projects, if I’m honest.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;It’s public.&lt;&#x2F;strong&gt; Anyone else sitting on &lt;code&gt;.FOL&lt;&#x2F;code&gt; files (and the retro-computing corners of the internet suggest there are more of you than you’d think) can recover their own data for free. Data archeology as a public good.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;I learned Zig on a real problem&lt;&#x2F;strong&gt; instead of a tutorial, which is the only way it sticks for me. (It wasn’t the last time, and the language keeps showing up in my projects.)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Niche? Extremely. But formats die and bytes don’t, and somebody has to keep the ferry running between them.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Bio</title>
          <pubDate>Tue, 26 Sep 2023 11:57:33 -0400</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/bio/</link>
          <guid>https://falseblue.com/bio/</guid>
          <description xml:base="https://falseblue.com/bio/">&lt;h2 id=&quot;my-career&quot;&gt;My Career&lt;&#x2F;h2&gt;
&lt;p&gt;I’ve been doing this for a bit over two decades now. It started with an unhealthy interest in computers and *nix systems at Purdue (see &lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;posts&#x2F;a-history-degree&#x2F;&quot;&gt;the history degree&lt;&#x2F;a&gt; for how &lt;em&gt;that&lt;&#x2F;em&gt; went) and turned into an actual career almost by accident: one tech-support job during my last semester, and one thing led to another.&lt;&#x2F;p&gt;
&lt;p&gt;Since then I’ve worked in small startups, one very large corporation, and growth-phase companies in between. I’ve done embedded systems, web applications, a state medicaid system, an encryption product, and now security compliance. The common thread is that I’ve had a seat in nearly every part of a technology company at some point (development, project management, operations, security), which mostly means I’ve collected a lot of examples of what makes projects succeed, and rather more examples of what makes them fail.&lt;&#x2F;p&gt;
&lt;p&gt;I hold the CISSP (Certified Information Systems Security Professional), PMP (Project Management Professional), and CSM (Certified ScrumMaster). The certificates are useful shorthand, but honestly the more valuable education came from the mistakes (mine and other people’s). My approach keeps changing because I keep learning, and one of my hobbies is just learning for the sake of it.&lt;&#x2F;p&gt;
&lt;p&gt;If you’re here to see whether we should work together, or just poking around: welcome. The &lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;projects&#x2F;&quot;&gt;projects&lt;&#x2F;a&gt; section is the portfolio, the &lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;posts&#x2F;&quot;&gt;blog&lt;&#x2F;a&gt; is where the stories go.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;experience&quot;&gt;Experience&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;founder-principal-consultant&quot;&gt;Founder, Principal Consultant&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;sc2.in&quot;&gt;SC2&lt;&#x2F;a&gt; · Apr 2024 – Present&lt;&#x2F;p&gt;
&lt;p&gt;I started Star City Security Consulting to bring my knowledge and experience to the small and medium-sized businesses of Lafayette. I am responsible for everything as of this writing. Our chief aim is to provide data security guidance for where you are, what you want to do, and what you have on hand.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;compliance-manager&quot;&gt;Compliance Manager&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;onboardmeetings.com&quot;&gt;OnBoard&lt;&#x2F;a&gt; · Aug 2018 – Present&lt;&#x2F;p&gt;
&lt;p&gt;I am currently working as a compliance manager at OnBoard taking our InfoSec compliance posture to the next level; maintaining compliance with SOC 2 Type 2, ISO 27001, ISO 27701, and emerging privacy regulations around the globe. I am leveraging prior technical experience for a holistic and knowledge-led approach to security compliance.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Completed external audits of ISO 27001&#x2F;27701 and SOC 2 Type 2 with zero non-conformities two years in a row&lt;&#x2F;li&gt;
&lt;li&gt;Created GRC tracking and management solutions focused on objective risk assessment and greater non-compliance visibility&lt;&#x2F;li&gt;
&lt;li&gt;Led business and product compliance efforts on AI, requiring rapid learning of LLMs and transformers, vendors, architecture approaches, public concern, and reinterpreting privacy regulations in light of how LLMs function.&lt;&#x2F;li&gt;
&lt;li&gt;Instituted an organization-wide rollout of ISO 27701&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;scrum-master&quot;&gt;Scrum Master&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;arxan.com&quot;&gt;Arxan&lt;&#x2F;a&gt; · May 2016 – Feb 2018&lt;&#x2F;p&gt;
&lt;p&gt;As a Scrum Master for our encryption product team, I was responsible for transitioning the team to more agile work methods, adapting to new standards and initiatives, identifying and mitigating risks, advocating for the team with internal management, and assisting the team in meeting feature goals and objectives.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Guided team to more consistent agile development with 2 week sprints utilizing JIRA&lt;&#x2F;li&gt;
&lt;li&gt;Assisted product owner in maintaining product and sprint backlog in accordance with product road-map&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h3 id=&quot;technical-functional-area-lead&quot;&gt;Technical Functional Area Lead&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;hpe.com&quot;&gt;Hewlett Packard Enterprise&lt;&#x2F;a&gt; · Feb 2008 – April 2016&lt;&#x2F;p&gt;
&lt;p&gt;While also being a developer, I was responsible for managing the prior authorization subsystem and Atlantes subsystem of the medicaid account. I was also responsible for the coordinated efforts of a small team of developers to maintain and build onto the eligibility system as well as communicating with account management regarding improvements, problem mitigation, and policy.&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;Architected the flow of data along with interfaces and standards between subsystems&lt;&#x2F;li&gt;
&lt;li&gt;Rearchitected full letter generation engine&lt;&#x2F;li&gt;
&lt;li&gt;Rearchitected testing environment refresh process&lt;&#x2F;li&gt;
&lt;li&gt;Worked with client to define business rules&lt;&#x2F;li&gt;
&lt;li&gt;Performed project management duties on behalf of PMO for the prior authorization subsystem team&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;education&quot;&gt;Education&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;bachelor-of-arts-in-history-of-science-and-technology&quot;&gt;Bachelor of Arts in History of Science and Technology&lt;&#x2F;h3&gt;
&lt;p&gt;&lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;purdue.edu&quot;&gt;Purdue University&lt;&#x2F;a&gt; · 2002 – 2006&lt;&#x2F;p&gt;
&lt;p&gt;My path through Purdue was a winding one, starting out in NROTC and Nuclear Engineering. The timing was not right for me, and I took a year of computer science in an attempt to transfer colleges. Long story short, I ended up in the History department with a minor in the history of science and technology.&lt;&#x2F;p&gt;
&lt;p&gt;Extracurricular Activities:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;NROTC&lt;&#x2F;li&gt;
&lt;li&gt;Pre-law Society&lt;&#x2F;li&gt;
&lt;li&gt;Japanese Club&lt;&#x2F;li&gt;
&lt;li&gt;Purdue Anime Club&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;certifications&quot;&gt;Certifications&lt;&#x2F;h2&gt;
&lt;div class=&quot;cert-badges&quot;&gt;
  &lt;a href=&quot;https:&#x2F;&#x2F;www.credly.com&#x2F;badges&#x2F;54b23151-f2cc-4f68-afab-9dd26683ae1d&#x2F;public_url&quot; title=&quot;CISSP, Certified Information Systems Security Professional&quot;&gt;&lt;img src=&quot;&#x2F;images&#x2F;cissp.png&quot; alt=&quot;CISSP, Certified Information Systems Security Professional&quot;&gt;&lt;&#x2F;a&gt;
  &lt;a href=&quot;https:&#x2F;&#x2F;www.credly.com&#x2F;badges&#x2F;e6ddcb92-2826-474c-8180-fa8853e8c593&#x2F;public_url&quot; title=&quot;PMP, Project Management Professional&quot;&gt;&lt;img src=&quot;&#x2F;images&#x2F;pmp.png&quot; alt=&quot;PMP, Project Management Professional&quot;&gt;&lt;&#x2F;a&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Click through for the Credly verifications.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;contact&quot;&gt;Contact&lt;&#x2F;h2&gt;
&lt;p&gt;If you have any questions or would like to work together, please feel free to reach out to me at &lt;a href=&quot;mailto:benjamin.craton+contact@gmail.com&quot;&gt;benjamin.craton+contact@gmail.com&lt;&#x2F;a&gt;. For sensitive requests, my GPG key fingerprint is &lt;code&gt;E48B 9BA1 3823 B0D8 D065 C110 7467 B453 13F5 5526&lt;&#x2F;code&gt;&lt;&#x2F;p&gt;
&lt;h2 id=&quot;some-frequently-asked-questions&quot;&gt;Some Frequently Asked Questions&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;what-s-with-the-name-tsunami-no-ai&quot;&gt;What’s with the name “Tsunami.No.Ai”?&lt;&#x2F;h3&gt;
&lt;p&gt;In high-school (c. 2000) I was big into this new thing I’d been exposed to called “anime.” Around the time our family got our first hosted domain with our ISP, I got to choose a subdomain for myself. Having just watched the original Tenchi Muyo OVA, I wanted “tsunami” in the name. It was taken, of course, so being a romantic, I added “noai” to the end. It was a play on words, “tsunami no ai” meaning (incorrectly) “tsunami of love” in Japanese. I was a teenager, what can I say? Not too long after, I found out that the correct phrase would be “ai no tsunami” and that “tsunami no ai” would mean “love of tsunamis.” It must have been a sign of not wanting to fool with DNS records that I kept it ever since.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;what-s-up-with-that-profile-picture&quot;&gt;What’s up with that Profile Picture?&lt;&#x2F;h3&gt;
&lt;p&gt;It’s &lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;posts&#x2F;cirno&#x2F;&quot;&gt;Cirno&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;a-history-degree&quot;&gt;A History Degree?&lt;&#x2F;h3&gt;
&lt;p&gt;Yes, &lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;posts&#x2F;a-history-degree&#x2F;&quot;&gt;a history degree&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>What is Security Training for Anyway?</title>
          <pubDate>Tue, 26 Sep 2023 11:55:22 -0400</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/posts/what-is-security-training-for-anyway/</link>
          <guid>https://falseblue.com/posts/what-is-security-training-for-anyway/</guid>
          <description xml:base="https://falseblue.com/posts/what-is-security-training-for-anyway/">&lt;figure&gt;
    &lt;img src=&quot;cover.jpg&quot; alt=&quot;A man at a home desk smiling through a video call on his laptop&quot; loading=&quot;lazy&quot;&gt;
&lt;&#x2F;figure&gt;
&lt;p&gt;You know the drill, it’s audit time, you’re scrambling to get all your ducks in a row, and then your HR department realizes that you’ve still got stragglers who haven’t completed their security training. Leaders have been emailed, reminders have been sent, and still, there are people who haven’t completed their training. You’re not alone, this is a common problem for many organizations. So what can you do about it?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-problem-with-compelled-training&quot;&gt;The Problem with Compelled Training&lt;&#x2F;h2&gt;
&lt;p&gt;Most companies and employees treat security training as a box that must be checked by a certain calendar date. As security professionals, this makes us want to bang our head against a wall. We know that the training is important, but the priority that takes in each person’s head is different. For some, it’s a fire that should be extinguished immediately, for others, it’s a nuisance to be filtered out by email clients. For most, it’s somewhere in between.&lt;&#x2F;p&gt;
&lt;p&gt;Think back to when you were in grade-school. The times you can recall being excited for homework were few and far between. Not only did you dread having extra tasks piled on you that you didn’t ask for, you don’t even know why you have to do it. What’s the point? The same applies to security training for most employees. They know why they have to complete it, but do they really know &lt;em&gt;why&lt;&#x2F;em&gt;?&lt;&#x2F;p&gt;
&lt;h2 id=&quot;finding-empathy-in-security&quot;&gt;Finding Empathy in Security&lt;&#x2F;h2&gt;
&lt;p&gt;The most compelling training, unfortunately, is the training some people get when they’ve had “information security” as a concept bleed into their personal lives.&lt;&#x2F;p&gt;
&lt;p&gt;A friend of mine called me up one day asking for guidance. Her friend had been the victim of one those “There’s a problem with your account and you should call this number, which is definitely Microsoft” scams. She felt stupid, ashamed, and violated. In fact, she was embarrassed for having her friend call me to ask for help.&lt;&#x2F;p&gt;
&lt;p&gt;Now in this case, everything worked out fine. She’d not given them any vital information, no private information was on her computer at the time, and her computer was able to be restored. She learned a lesson and was eager to warn others in her social circle using her experience as a cautionary tale.&lt;&#x2F;p&gt;
&lt;p&gt;Is that a success? I’d say so. She learned a lesson, and she was eager to share it with others. She was able to empathize with the victims of these scams and wanted to help them avoid the same fate. Suddenly, she was a security advocate.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;make-security-training-personal&quot;&gt;Make Security Training Personal&lt;&#x2F;h2&gt;
&lt;p&gt;The key to making security training effective is to make it personal, relatable, and shareable. If you can make it personal, you can make it relatable. If you can make it relatable, you can make it shareable. If you can make it shareable, you can make it stick.&lt;&#x2F;p&gt;
&lt;p&gt;Think about your employees and how they interact with the technology you’ve provided them. They all see those tools in different ways and use them in different ways. Some may see email as simply a chat session whereas others use it to archive critical business documents. You may see a VPN as a way to access internal resources, but they may see it as a way to get around a firewall to access their favorite streaming service. To connect with your employees, you need to understand how they use the tools at their disposal.&lt;&#x2F;p&gt;
&lt;p&gt;Let’s consider two cases where I’ve (rightly or wrongly) assumed you have a good ISMS or equivalent rolled out to your organization.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-developer&quot;&gt;The developer&lt;&#x2F;h3&gt;
&lt;p&gt;The developer sees the world in terms of code. The tools they have to do the work of building more tools has given them an experience of how to break things and fix them again. Asking developers to do security training is not a problem in understanding &lt;em&gt;why&lt;&#x2F;em&gt;, for them it’s a problem of interest. They have other work and more interesting challenges to solve.&lt;&#x2F;p&gt;
&lt;p&gt;To connect with the developer, connect the lessons in the training to those they can use personally. Perhaps they have side projects that they are working on and could use insight on how to apply security practices to a solo project. Perhaps they have a friend or family member who has been the victim of a scam or hack. Perhaps they have a favorite open source project that they could contribute to by adding security features.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;the-salesperson&quot;&gt;The salesperson&lt;&#x2F;h3&gt;
&lt;p&gt;The salesperson sees the world in terms of people and connections between them. For them, the technology we put in front of them is a means to that end and nothing more. Asking a salesman about applying security to their work is like asking a sprinter to please wear a weighted vest. It’s not going to help them do their job, and it’s going to slow them down.&lt;&#x2F;p&gt;
&lt;p&gt;To connect with the sales person, connect the lessons in the training to those they can weave into their pitch. Security is not a list of “do’s and don’ts” it is a commitment to quality in the services you provide your customers. Taking training isn’t a yearly reminder of what not to do, it’s a reminder of the trust your customers have put in you to keep them safe. And it’s a reminder that they can use to show their customers that they are committed to that trust.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;&#x2F;h2&gt;
&lt;p&gt;Security training is a necessary part of life. You have an opportunity to make it a positive part of your employees’ lives and empower them as people first, employees second. It might sound cheesy, but those are the facts. If you can make security training personal, relatable, and shareable not only will you have checked all your GRC boxes, you’ll have a workforce that evangelizes on your behalf.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Pioneering AI Privacy Policy: Leading the Charge in Responsible AI Implementation</title>
          <pubDate>Tue, 30 May 2023 00:00:00 +0000</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/projects/ai-compliance/</link>
          <guid>https://falseblue.com/projects/ai-compliance/</guid>
          <description xml:base="https://falseblue.com/projects/ai-compliance/">&lt;p&gt;When ChatGPT dropped in November 2022, my phone started ringing. Not literally, but everyone at work suddenly wanted to know what this thing was, whether we could use it, and whether we were allowed to. As the compliance guy, “are we allowed to” was my desk.&lt;&#x2F;p&gt;
&lt;p&gt;The honest answer at the time was “nobody knows yet,” which is not an answer you can put in a policy. So I went and learned how the things actually work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;doing-the-homework&quot;&gt;Doing the Homework&lt;&#x2F;h2&gt;
&lt;p&gt;Regulation always lags technology, and LLMs were lapping it. Rather than wait for a framework to be handed down, I dug into the architecture of transformer models (what they actually do with the data you feed them, where that data goes, and where the compliance landmines were likely to be). That turned into a compliance overview written for &lt;em&gt;our&lt;&#x2F;em&gt; business specifically, not a generic think-piece. (Some of that thinking eventually became a blog post: &lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;posts&#x2F;the-robot-over-my-shoulder&#x2F;&quot;&gt;The Robot Over My Shoulder&lt;&#x2F;a&gt;.)&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-onboard-ai-assistant-beta&quot;&gt;The OnBoard AI Assistant Beta&lt;&#x2F;h2&gt;
&lt;p&gt;By March 2023 that homework paid off: I led the compliance side of the OnBoard AI Assistant beta rollout. The goal was to have privacy and security in the design conversation from day one, instead of the traditional approach where security reviews the finished thing and everyone gets mad at each other.&lt;&#x2F;p&gt;
&lt;p&gt;A surprising amount of the job was translation. “Context window,” “fine-tuning,” and “vendor model training rights” mean nothing to a business stakeholder until you convert them into “here’s what happens to the customer’s data and here’s what we’re promising.” Once people understood the mechanics, they made good decisions on their own.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;an-ai-policy-before-it-was-cool&quot;&gt;An AI Policy Before It Was Cool&lt;&#x2F;h2&gt;
&lt;p&gt;By June 2023 I had drafted and rolled out an organization-wide generative AI tool policy (at a time when most companies’ policy was a shrug). It covered data privacy, acceptable use, security requirements, and how existing law applied to the new toys. Nothing exotic; just written down, agreed to, and enforceable, which put us well ahead of the curve.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;what-came-of-it&quot;&gt;What Came of It&lt;&#x2F;h2&gt;
&lt;p&gt;We got to say “yes, and here’s how” instead of “no”, which is the whole job, really. The company adopted generative AI with guardrails already in place, the auditors had something to point at, and I got a crash course in a technology that clearly wasn’t going away. I’d rather write the policy before the incident than after it.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Aniki.fm: A Podcast About Anime with Two Brothers</title>
          <pubDate>Sun, 26 Jul 2020 12:43:39 -0400</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/projects/anikifm/</link>
          <guid>https://falseblue.com/projects/anikifm/</guid>
          <description xml:base="https://falseblue.com/projects/anikifm/">&lt;h2 id=&quot;about-aniki-fm&quot;&gt;About Aniki.fm&lt;&#x2F;h2&gt;
&lt;div class=&quot;admonition note&quot;&gt;
    &lt;div class=&quot;admonition-icon admonition-icon-note&quot;&gt;&lt;&#x2F;div&gt;
    &lt;div class=&quot;admonition-content&quot;&gt;
        &lt;strong class=&quot;admonition-title&quot;&gt;NOTE&lt;&#x2F;strong&gt;
        &lt;p&gt;If you’re wonder where the site is: see &lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;posts&#x2F;self-hosting&#x2F;#aniki-fm&quot;&gt;this post&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;

    &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;p&gt;Aniki is a podcast about anime with two brothers, bringing the passion about their hobby to the world. It is a weekly project with set delivery dates and workflows which involve scheduling, sound production, research, and social marketing. It is currently a nonprofit project. Three seasons and over 50 episodes have been produced.&lt;&#x2F;p&gt;
&lt;p&gt;In addition to producing the podcast, I rewrote the front end of the podcast’s website to run nuxt with a headless Wordpress backend running on kubernetes. In doing so, I learned about streaming (as a custom audio player was implemented into the site) and how to implement vuex stores for reduced API traffic.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;the-podcast&quot;&gt;The Podcast&lt;&#x2F;h2&gt;
&lt;h3 id=&quot;design-work&quot;&gt;Design Work&lt;&#x2F;h3&gt;
&lt;p&gt;I designed the logo and branding for the podcast, as well as the website. The website was designed to be a simple, clean, and easy to navigate site that would be easy to maintain and update. The logo was designed to be simple and recognizable, and the branding was designed to be consistent across all platforms.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;season-designs&quot;&gt;Season Designs&lt;&#x2F;h3&gt;
&lt;p&gt;For each season, I designed a new logo and branding to match the theme of the season. This included creating a new color scheme, logo, and website design.&lt;&#x2F;p&gt;
&lt;figure&gt;
    &lt;img src=&quot;season_1_banner.jpg&quot; alt=&quot;Season 1 Banner&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;Season 1 Banner&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;figure&gt;
    &lt;img src=&quot;season_2_cover.jpg&quot; alt=&quot;Season 2 Cover&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;Season 2 Cover&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;figure&gt;
    &lt;img src=&quot;season_3_banner.jpg&quot; alt=&quot;Season 3 Banner&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;Season 3 Banner&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;figure&gt;
    &lt;img src=&quot;season_4_banner.jpg&quot; alt=&quot;Season 4 Banner&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;Season 4 Banner&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;figure&gt;
    &lt;img src=&quot;cover.jpg&quot; alt=&quot;Season 5 Banner&quot; loading=&quot;lazy&quot;&gt;
    &lt;figcaption&gt;Season 5 Banner&lt;&#x2F;figcaption&gt;
&lt;&#x2F;figure&gt;
&lt;h3 id=&quot;sound-production&quot;&gt;Sound Production&lt;&#x2F;h3&gt;
&lt;p&gt;Using Adobe Audition, I have been responsible for the all of the sound production for the podcast. This includes editing the audio, adding sound effects, and mixing the audio to create a professional sounding podcast, at least to my ears.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;interactivity&quot;&gt;Interactivity&lt;&#x2F;h3&gt;
&lt;p&gt;For our seasonal preview episodes, I created a web app that allowed users to follow along with the episode and see the images and videos we were discussing. This was done using Vue.js and the Vuetify framework.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;social-media&quot;&gt;Social Media&lt;&#x2F;h3&gt;
&lt;p&gt;I have been responsible for the social media presence of the podcast, including creating and maintaining the Twitter, Facebook, and Instagram accounts. I utilized Hootsuite to schedule posts and track engagement.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;analytics&quot;&gt;Analytics&lt;&#x2F;h3&gt;
&lt;p&gt;Before Castopod and other podcast analytics tools were available, I created a custom analytics dashboard using a webhook from the podcast backend and a custom database with a front end built in Vue.js. This allowed us to track our listener numbers and engagement directly without relying on third party tools.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;videos&quot;&gt;Videos&lt;&#x2F;h3&gt;
&lt;p&gt;For the seasonal podcast preview episodes, I created a video version of the podcast that included the images and videos we were discussing. Since we already had the timing information for the interactive episode page, I was able to use that to script a python program to automatically create the video with the correct timing and images. To a point. I still had to manually adjust the timing and add labels and transitions directly in Adobe Premiere.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;equipment-used&quot;&gt;Equipment Used&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Electro-Voice RE20 Microphone&lt;&#x2F;li&gt;
&lt;li&gt;Rode Procaster USB Microphone&lt;&#x2F;li&gt;
&lt;li&gt;Focusrite Scarlett 2i2 Audio Interface&lt;&#x2F;li&gt;
&lt;li&gt;dbx 286s Microphone Preamp&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;h2 id=&quot;technologies-used&quot;&gt;Technologies Used&lt;&#x2F;h2&gt;
&lt;ul&gt;
&lt;li&gt;Nuxt&lt;&#x2F;li&gt;
&lt;li&gt;Vue.js&lt;&#x2F;li&gt;
&lt;li&gt;Vuetify&lt;&#x2F;li&gt;
&lt;li&gt;Wordpress&lt;&#x2F;li&gt;
&lt;li&gt;Kubernetes&lt;&#x2F;li&gt;
&lt;li&gt;Hootsuite&lt;&#x2F;li&gt;
&lt;li&gt;Adobe Audition&lt;&#x2F;li&gt;
&lt;li&gt;Adobe Premiere&lt;&#x2F;li&gt;
&lt;li&gt;Adobe Illustrator&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
</description>
      </item>
      <item>
          <title>Evolution of the Magic Card Generator</title>
          <pubDate>Thu, 01 Jun 2017 00:00:00 +0000</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/projects/magic-card-generator/</link>
          <guid>https://falseblue.com/projects/magic-card-generator/</guid>
          <description xml:base="https://falseblue.com/projects/magic-card-generator/">&lt;div class=&quot;admonition note&quot;&gt;
    &lt;div class=&quot;admonition-icon admonition-icon-note&quot;&gt;&lt;&#x2F;div&gt;
    &lt;div class=&quot;admonition-content&quot;&gt;
        &lt;strong class=&quot;admonition-title&quot;&gt;NOTE&lt;&#x2F;strong&gt;
        &lt;p&gt;If you’re wonder where the site is: see &lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;posts&#x2F;self-hosting&#x2F;#magic-falseblue-com&quot;&gt;this post&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;

    &lt;&#x2F;div&gt;
&lt;&#x2F;div&gt;
&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;&#x2F;h2&gt;
&lt;p&gt;I like Magic: The Gathering and I like programming, so in 2017 I built a web page that let people make their own Magic cards: upload some art, fill in the card attributes, get a card. That’s it. That was the whole idea. It then proceeded to eat nearly a decade of my hobby time, one rewrite at a time, and by January 2024, strangers on the internet had made &lt;strong&gt;over 250,000 cards&lt;&#x2F;strong&gt; with it.&lt;&#x2F;p&gt;
&lt;p&gt;The honest framing: every version of this site was an excuse to learn whatever I’d just been exposed to at work.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;version-1-php-like-an-honest-man&quot;&gt;Version 1: PHP, Like an Honest Man&lt;&#x2F;h2&gt;
&lt;p&gt;A basic PHP form and an image generator. Users typed in card text, the server composited it onto a card frame. It taught me web development fundamentals the traditional way: by breaking a live site repeatedly.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;version-2-the-learning-platform-era&quot;&gt;Version 2: The Learning Platform Era&lt;&#x2F;h2&gt;
&lt;p&gt;When I came back to it, I rebuilt it as an excuse to learn the “grown-up” stack of the mid-2010s:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Python 3 &amp;amp; Django&lt;&#x2F;strong&gt; for the backend&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Neural networks &amp;amp; image recognition&lt;&#x2F;strong&gt; for automated analysis of uploaded card art&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Bitbucket, Jenkins, Docker, Rancher&lt;&#x2F;strong&gt; (a real CI&#x2F;CD pipeline for a silly card site)&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The unglamorous lesson came from migrating 250k existing images and their data to a new format. Nothing teaches you respect for data integrity like the possibility of destroying a quarter-million pieces of other people’s art with one bad script.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;version-3-peak-complexity&quot;&gt;Version 3: Peak Complexity&lt;&#x2F;h2&gt;
&lt;p&gt;Version 3 adopted whatever my DevOps colleagues were excited about that year:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Vue.js&lt;&#x2F;strong&gt; frontend, &lt;strong&gt;Node.js &amp;amp; MongoDB&lt;&#x2F;strong&gt; backend, &lt;strong&gt;Redis&lt;&#x2F;strong&gt; caching&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;An AI NSFW filter&lt;&#x2F;strong&gt; (because the site had no accounts by design, and anonymous internet users plus an image uploader is exactly the moderation problem you think it is)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Docker &amp;amp; Kubernetes&lt;&#x2F;strong&gt; for orchestration, &lt;strong&gt;Azure DevOps Pipelines&lt;&#x2F;strong&gt; for deployment&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;Yes, this is an absurd amount of infrastructure for a card generator. That was partly the point: I got to make my architecture mistakes on my own time instead of my employer’s.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;where-it-stands&quot;&gt;Where It Stands&lt;&#x2F;h2&gt;
&lt;p&gt;The site is down (see &lt;a href=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;posts&#x2F;self-hosting&#x2F;#magic-falseblue-com&quot;&gt;the self-hosting update&lt;&#x2F;a&gt; for why), and I doubt it’s coming back. But a quarter-million cards is a quarter-million small moments of someone making a thing and grinning at it, and every skill this project taught me got used professionally within a year or two of learning it. Not bad for a hobby project that started as one PHP file.&lt;&#x2F;p&gt;
</description>
      </item>
      <item>
          <title>Base Emoji</title>
          <pubDate>Fri, 03 Mar 2017 00:00:00 +0000</pubDate>
          <author>Ben Craton</author>
          <link>https://falseblue.com/projects/base-emoji/</link>
          <guid>https://falseblue.com/projects/base-emoji/</guid>
          <description xml:base="https://falseblue.com/projects/base-emoji/">&lt;!-- TODO(ben): when the &quot;Signing Tweets with Emoji&quot; blog post publishes
     (content&#x2F;posts&#x2F;base-emoji-signatures&#x2F;), link it from here. --&gt;
&lt;h2 id=&quot;what-is-it&quot;&gt;What is it?&lt;&#x2F;h2&gt;
&lt;p&gt;A silly project to learn unicode, &lt;a class=&quot;external&quot; rel=&quot;external&quot; href=&quot;https:&#x2F;&#x2F;github.com&#x2F;tsunaminoai&#x2F;baseEmoji&quot;&gt;baseEmoji&lt;&#x2F;a&gt; is a base1024 encoding scheme that uses emoji as its lookup table. The primary purpose is to represent otherwise ugly data in more “pleasing” form in social media.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;use-case&quot;&gt;Use Case&lt;&#x2F;h2&gt;
&lt;p&gt;The impetus for this module was to represent digital signatures in social media in a less obtrusive way. A signature on a tweet from a user to a bot is useful in alerting the bot to run commands that can be trusted to have come from a specific source. However, these signatures look like jibberish to human readers. Instead, this signature could be represented by emoji using baseEmoji and appear to a human reader like a typical Instagram user.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;practical-example-signing-a-tweet&quot;&gt;“Practical” Example: Signing a Tweet&lt;&#x2F;h3&gt;
&lt;h4 id=&quot;signing&quot;&gt;Signing&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; sys&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tweepy&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;import&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; baseEmoji&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword&quot;&gt;from&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; ecdsa&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword&quot;&gt; import&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; SigningKey&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;CONSUMER_KEY&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;********&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;CONSUMER_SECRET&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;********&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;ACCESS_KEY&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;********&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;ACCESS_SECRET&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;#39;********&amp;#39;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#set up tweepy and connect to Twitter&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;auth&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tweepy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;OAuthHandler&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;CONSUMER_KEY&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; CONSUMER_SECRET&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;auth&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;set_access_token&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;ACCESS_KEY&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; ACCESS_SECRET&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;api&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; tweepy&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;API&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;auth&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#create a signing key. In practice this would be saved&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;signKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; SigningKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;generate&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#our message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot;This tweet is signed&amp;quot;&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#sign the message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; signKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;sign&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;message&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#convert the signature into an emoji signature&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;emSig&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; baseEmoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;encodeStr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;signature&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#create the tweet with a delimiter for later parsing&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;tweet&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; message&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt; &amp;quot; #blessed &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; +&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; emSig&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#send the tweet&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; api&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;update_status&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;tweet&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;&lt;h4 id=&quot;viewing&quot;&gt;Viewing&lt;&#x2F;h4&gt;
&lt;p&gt;&lt;img src=&quot;https:&#x2F;&#x2F;falseblue.com&#x2F;projects&#x2F;base-emoji&#x2F;tweet.png&quot; alt=&quot;Tweet&quot; loading=&quot;lazy&quot; decoding=&quot;async&quot; &#x2F;&gt;&lt;&#x2F;p&gt;
&lt;h4 id=&quot;&quot;&gt;Verifying&lt;&#x2F;h4&gt;
&lt;pre class=&quot;giallo z-code&quot;&gt;&lt;code data-lang=&quot;python&quot;&gt;&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#...&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#get the verification key&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;verifyKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; signKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;get_verifying_key&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;()&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#retrieve a tweet (in this case the tweet we just sent)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;v&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; api&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;get_status&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;t&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;id&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#split the text of the tweet into the message and the signature&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;rmessage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;remSig&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; v&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt;text&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;split&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string z-string&quot;&gt;&amp;quot; #blessed &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-constant z-numeric&quot;&gt;1&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#convert the emoji signature back to its original form&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-source&quot;&gt;rsignature&lt;&#x2F;span&gt;&lt;span class=&quot;z-keyword z-operator&quot;&gt; =&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; baseEmoji&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;decodeStr&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;remSig&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation z-definition z-string&quot;&gt;&amp;quot; &amp;quot;&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-punctuation z-definition z-comment z-comment&quot;&gt;#verify that the signature is valid for the message&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;
&lt;span class=&quot;giallo-l&quot;&gt;&lt;span class=&quot;z-keyword z-control z-flow z-python&quot;&gt;assert&lt;&#x2F;span&gt;&lt;span class=&quot;z-source&quot;&gt; verifyKey&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;.&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-python&quot;&gt;verify&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;(&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt;rsignature&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;,&lt;&#x2F;span&gt;&lt;span class=&quot;z-meta z-function-call z-arguments z-python&quot;&gt; rmessage&lt;&#x2F;span&gt;&lt;span class=&quot;z-punctuation&quot;&gt;)&lt;&#x2F;span&gt;&lt;&#x2F;span&gt;&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In the wild, it may be advantageous to use a smaller digital signature algorithm and to also check that the length of the message plus the delimiter and signature don’t go beyond 140 characters. While the signature itself can be a fixed size of bytes, because some emoji require more than one code point, the emoji signature could be a few characters longer according to Twitter’s counting.&lt;&#x2F;p&gt;
</description>
      </item>
    </channel>
</rss>
