Jekyll2022-01-16T06:08:11+00:00https://zeroindexed.com/feed.xmlZeroIndexedRonuk's personal blogRonuk RavalEffective terminal presentations with asciinema and doitlive2022-01-15T00:00:00+00:002022-01-15T00:00:00+00:00https://zeroindexed.com/asciinema-doitlive<p>I’ve been trying to push my personal boundaries of “doing open source right”. <a href="https://github.com/rraval/git-nomad">On the most recent pet project</a>, that means putting those little README shields that people seem so fond of; leveraging GitHub actions for automated testing, linting, and deploying; and recording a screencast to give an interactive tour of functionality.</p> <p><a href="https://asciinema.org/">asciinema</a> is a popular utility for distributing screencasts but the interactive recording style resulted in a final product with quite a few flaws. I wrote a script, built <a href="https://github.com/rraval/git-nomad/commit/2874bad7e8d810a5ab06370a6fcceae3ad384770#diff-206b9ce276ab5971a2489d75eb1b12999d4bf3843b7988cbe8d687cfde61dea0">a few helpers</a>, and recorded segments in multiple takes until arriving at something passable. And “passable” just about summarizes the end result, there’s still the occasional typo, the cuts are jarring, and the typing has awkward pauses even with <code class="language-plaintext highlighter-rouge">--idle-time-limit=0.3</code>. Worst of all, it’s ~5 minutes long, which I’d reckon is enough to frustrate even the most motivated viewer.</p> <!--more--> <p><a href="https://asciinema.org/a/458630?autoplay=1"><img src="https://asciinema.org/a/458630.svg" alt="git-nomad 0.4.0 asciicast" /></a></p> <p>In hopes of doing better, I found a <a href="https://hackertyper.net">HackerTyper</a>-like tool called <a href="https://doitlive.readthedocs.io/en/stable/">doitlive</a> meant for live presentations in the terminal. Using it with asciinema is straight forward (based on <a href="https://gist.github.com/TApplencourt/f9b586051cfe3a640ca8">this gist by Thomas Applencourt</a>):</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>asciinema rec --command 'doitlive play --commentecho --quiet --shell bash &lt;script.sh&gt;' &lt;recording.cast&gt; </code></pre></div></div> <p>This runs the <code class="language-plaintext highlighter-rouge">asciinema</code> recorder on the outside and typing controls the pace at which <code class="language-plaintext highlighter-rouge">doitlive</code> reads the commands from the provided <code class="language-plaintext highlighter-rouge">&lt;script.sh&gt;</code>.</p> <p>Overall the experience is quite pleasant: you write the script and simply whack the keyboard as fast as you please to control the pacing. It also trivializes making future recordings as the behaviour of the underlying demo changes. It’s not quite a non-linear video editor, but it’ll do.</p> <p><code class="language-plaintext highlighter-rouge">doitlive</code> has features to inject environment variables and display commentary, however the nature of <a href="https://github.com/sloria/doitlive/blob/357d086d93c567a3e107efad496e33d1ee90470a/doitlive/cli.py#L51">maintaining independent shell state</a> and <a href="https://github.com/sloria/doitlive/blob/357d086d93c567a3e107efad496e33d1ee90470a/doitlive/keyboard.py#L91">interpreting commands</a> mean that <a href="https://github.com/rraval/git-nomad/commit/2874bad7e8d810a5ab06370a6fcceae3ad384770#diff-ba249f54c3ae36c2b54dc5ff6c09c440a01e2caaeb4e7e3f17fec5f2ef37af88">recording helpers that export variables and change directories cannot be used</a>. There’s also no affordance to execute hidden commands, though that’s understandable given the motivation of a presentation tool.</p> <p>Here’s the final result, equivalent to the previous one at just 93 seconds. It could be better, and I’m sure there’s someone that prefers the older version, but I’m shipping it and moving on.</p> <p><a href="https://asciinema.org/a/462028?autoplay=1"><img src="https://asciinema.org/a/462028.svg" alt="git-nomad 0.5.0 asciicast" /></a></p> <h2 id="changelog">Changelog</h2> <p>2022-01-16: Published.</p>Ronuk RavalI’ve been trying to push my personal boundaries of “doing open source right”. On the most recent pet project, that means putting those little README shields that people seem so fond of; leveraging GitHub actions for automated testing, linting, and deploying; and recording a screencast to give an interactive tour of functionality. asciinema is a popular utility for distributing screencasts but the interactive recording style resulted in a final product with quite a few flaws. I wrote a script, built a few helpers, and recorded segments in multiple takes until arriving at something passable. And “passable” just about summarizes the end result, there’s still the occasional typo, the cuts are jarring, and the typing has awkward pauses even with --idle-time-limit=0.3. Worst of all, it’s ~5 minutes long, which I’d reckon is enough to frustrate even the most motivated viewer.Nix solves the package manager ejection problem2021-05-30T00:00:00+00:002021-05-30T00:00:00+00:00https://zeroindexed.com/nix-ejection-problem<p>This blog post operates on two levels.</p> <p>On a very direct level, I built a desktop machine with an <a href="https://www.amd.com/en/products/graphics/amd-radeon-rx-5600-xt">AMD Radeon RX 5600 XT graphics card</a> and I’ve been fighting a rather annoying interaction with dual monitors on Linux. Here’s how it goes:</p> <ol> <li>After some defined period of inactivity, the system tries to standby / suspend / turn off both monitors.</li> <li>Both monitors respond to the <a href="https://wiki.archlinux.org/title/Display_Power_Management_Signaling">DPMS commands</a> and briefly blank.</li> <li>After a few seconds, one of them comes on again, quickly followed by the other one, in an arbitrary order.</li> <li>XFCE “helpfully” detects this as a monitor hotplug event and pops open a display configuration dialog.</li> </ol> <p>Stepping away to make a coffee now means periodic flickering and coming back to 5 - 10 XFCE monitor configuration dialogs taking over my screen. Very annoying!</p> <p>Googling around finds this <a href="https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1790861">Ubuntu issue</a> from 2018 that seems to describe the same problem, but the documented workaround of <code class="language-plaintext highlighter-rouge">amdgpu.dc=0</code> as a kernel parameter does not work. My graphics card decides to go into a glitchfest and the kernel doesn’t even make it past initrd.</p> <p>That Ubuntu issue links to <a href="https://bugs.freedesktop.org/show_bug.cgi?id=109246">this upstream Freedesktop issue</a>, which is old enough to get migrated to <a href="https://gitlab.freedesktop.org/drm/amd/-/issues/662">this new Freedesktop issue</a>, where <a href="https://gitlab.freedesktop.org/drm/amd/-/issues/662#note_909333">some kind soul has put together a patch that applies cleanly on recent kernels</a>. My understanding is that the monitor starts polling its inputs when it enters a DPMS mode, and the patch adjusts the timeouts on the driver to ignore the polling pulses instead of treating them as hotplug events.</p> <p>So that’s one level: write a blog post, stuff it with enough keywords that other affected users can find it, tell them to <a href="https://gitlab.freedesktop.org/drm/amd/-/issues/662#note_909333">USE THE KERNEL PATCH</a> until a fix is integrated into the mainline. A decent public service, but on its own not <em>interesting</em>.</p> <p>On a second level, I’ve recently been <a href="https://github.com/rraval/nix">experimenting with NixOS as my daily driver</a> and it rises to this challenge in ways that ArchLinux never could.</p> <!--more--> <p>Package management on Linux has a colourful history, with various distributions intermixing technology with philosophy to produce whole system configurations that real people can run on real machines with varying amounts of productivity. You have the Slackware “our packages are just tarballs you can extract over <code class="language-plaintext highlighter-rouge">/</code>”, the slightly more principled dpkg and RPM’s of the world, the source-first approach preferred ArchLinux, and the “invent the universe to bake a pie” doctrine that is Linux From Scratch.</p> <p>However, all of them share the fundamental notion of what it means to be a package: a monolithic reusable artifact that can be installed on a user’s machine. (Okay, Linux From Scratch doesn’t really belong in this category, but does it really belong anywhere?)</p> <p>And there lies the dilemma: if the user needs to go off the beaten path, like patch the damn Linux kernel, they must roll their own package. Sure, some distributions will let you <a href="https://wiki.archlinux.org/title/Kernel/Arch_Build_System">reuse their package building recipe and make the process straightforward</a>, but:</p> <ul> <li>You are now no longer a package consumer, you are now a package developer, which is considered its own distinct category.</li> <li>Which means you get none of the nice workflows that package consumers enjoy. You are responsible for tracking security disclosures, software updates, and rebasing your changes on top of whatever base you’re building off.</li> </ul> <p>Put another way: <a href="https://github.com/rraval/zeroindexed/issues/8">the package development workflow does not compose</a>.</p> <p>In contrast, NixOS makes patching the kernel a four liner:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>boot.kernelPatches = [{ name = "amdgpu-sleep-fix"; patch = ./amdgpu-sleep-fix.patch; }]; </code></pre></div></div> <p>And the “contrast” here isn’t how easy NixOS makes this (though that is appreciated), it’s that the intention of “build the existing NixOS kernel with just this patch applied” is being purely captured. That’s only possible here because the package management strategy is underpinned by a real programming language where it is derivations all the way down.</p> <p>There is no distinction between being a “package consumer” and a “package developer” here. I get all the updates that the people responsible for the NixOS kernel put out with no continuous maintenance on my part.</p> <p>The JavaScript community has a good word for this kind of “stay on the beaten path and get updates” or “do your own thing but carry the maintenance and complexity burden”. <a href="https://create-react-app.dev/docs/available-scripts/#npm-run-eject">They call it ejection</a>.</p> <p>NixOS (and Nix, which is the practical underpinning that makes this all possible) present a composable solution to this package management ejection problem. And that is <em>interesting</em>!</p> <h3 id="on-gentoo">On Gentoo</h3> <p>An earlier version of this article lumped Gentoo into the same source-first approach as ArchLinux. John Helmert III reached out over email and <a href="https://news.ycombinator.com/item?id=27346853">totony on HackerNews</a> pointed out that Portage has grown to be far more sophisticated than I gave it credit for.</p> <p>Portage supports a <a href="https://wiki.gentoo.org/wiki//etc/portage/patches">generalized mechanism for patching software</a> that seems like it would have worked just as well here (with fewer lines of code if you will).</p> <p>I only have a surface level understanding, but it seems like the ebuild itself cannot be patched, so there is no analogue to the <a href="https://nixos.org/guides/nix-pills/override-design-pattern.html">Nix override design pattern</a>; meaning there is still some distinction between “package consumer” and “package developer”. However, this is a pragmatic blog post motivated by a real problem, and it seems like Gentoo is quite capable of rising to the specifics of this situation. Fair play!</p> <h2 id="changelog">Changelog</h2> <p>2021-06-06: Credit John Helmert III by name.</p> <p>2021-05-31: Added a section on Gentoo and Portage.</p> <p>2021-05-30: Published.</p>Ronuk RavalThis blog post operates on two levels. On a very direct level, I built a desktop machine with an AMD Radeon RX 5600 XT graphics card and I’ve been fighting a rather annoying interaction with dual monitors on Linux. Here’s how it goes: After some defined period of inactivity, the system tries to standby / suspend / turn off both monitors. Both monitors respond to the DPMS commands and briefly blank. After a few seconds, one of them comes on again, quickly followed by the other one, in an arbitrary order. XFCE “helpfully” detects this as a monitor hotplug event and pops open a display configuration dialog. Stepping away to make a coffee now means periodic flickering and coming back to 5 - 10 XFCE monitor configuration dialogs taking over my screen. Very annoying! Googling around finds this Ubuntu issue from 2018 that seems to describe the same problem, but the documented workaround of amdgpu.dc=0 as a kernel parameter does not work. My graphics card decides to go into a glitchfest and the kernel doesn’t even make it past initrd. That Ubuntu issue links to this upstream Freedesktop issue, which is old enough to get migrated to this new Freedesktop issue, where some kind soul has put together a patch that applies cleanly on recent kernels. My understanding is that the monitor starts polling its inputs when it enters a DPMS mode, and the patch adjusts the timeouts on the driver to ignore the polling pulses instead of treating them as hotplug events. So that’s one level: write a blog post, stuff it with enough keywords that other affected users can find it, tell them to USE THE KERNEL PATCH until a fix is integrated into the mainline. A decent public service, but on its own not interesting. On a second level, I’ve recently been experimenting with NixOS as my daily driver and it rises to this challenge in ways that ArchLinux never could.This blog has analytics and a privacy policy now2021-05-16T00:00:00+00:002021-05-16T00:00:00+00:00https://zeroindexed.com/analytics<p>Even though the Jekyll Minima theme has <a href="https://github.com/jekyll/minima/blob/2.5-stable/_includes/google-analytics.html">off the shelf support for Google Analytics</a>, I decided to be a good internet denizen and use something that preserved visitor privacy.</p> <p>I thought that surely in 2021, somebody would have built a simple page view counter that I could just plug into my dinky blog for minimal cost. I ended up evaluating all the popular alternatives: <a href="https://matomo.org/">Matamo</a>, <a href="https://plausible.io/">Plausible</a>, and <a href="https://www.cloudflare.com/analytics/">Cloudflare analytics</a>.</p> <p>As it turns out, all of these are rather expensive. What should have been simple became bespoke and <a href="https://github.com/rraval/zeroindexed/tree/master/packages/toph-worker#readme">Toph was born</a>. It’s a Cloudflare workers service that sits in between the visitors browser and Google Analytics.</p> <!--more--> <p>Toph is a first party analytics solution, which is generally regarded favourably compared to the third party tracker status quo. It would have been completely okay to do visitor identity tracking by shoving a UUID into a cookie. This usage would likely <a href="https://law.stackexchange.com/a/29291">not even require explicit consent</a>.</p> <p>But for entirely dubious motivations, I decided to make the implementation cookie-less, trading accuracy and retention metrics for an even smaller privacy footprint. The end result works somewhat like <a href="https://plausible.io/data-policy#how-we-count-unique-users-without-cookies">Plausible’s cookie-less tracking</a>, but the <a href="https://github.com/rraval/zeroindexed/tree/master/packages/toph-worker#implementation">Toph implementation is interesting in its own right</a>.</p> <p>I think if you asked me “how much do you care about web privacy?”, I would have given an apathetic response. But clearly I care enough to spend many hours <a href="https://www.npmjs.com/package/@zeroindexed/toph-worker">building a reusable self deployable solution</a> and even <a href="https://www.npmjs.com/package/@zeroindexed/toph-pulumi">packaging it up with Pulumi to make deployment trivial</a>. I’m not sure what virtues this signals.</p> <p>Oh, and it’s called Toph because <a href="https://avatar.fandom.com/wiki/Toph_Beifong">it is blind to the visitor’s personal information</a>.</p> <h1 id="changelog">Changelog</h1> <p>2021-05-30: Added this changelog.</p> <p>2021-05-16: Published.</p>Ronuk RavalEven though the Jekyll Minima theme has off the shelf support for Google Analytics, I decided to be a good internet denizen and use something that preserved visitor privacy. I thought that surely in 2021, somebody would have built a simple page view counter that I could just plug into my dinky blog for minimal cost. I ended up evaluating all the popular alternatives: Matamo, Plausible, and Cloudflare analytics. As it turns out, all of these are rather expensive. What should have been simple became bespoke and Toph was born. It’s a Cloudflare workers service that sits in between the visitors browser and Google Analytics.PGP encryption subkeys are less useful than I thought2021-05-08T00:00:00+00:002021-05-08T00:00:00+00:00https://zeroindexed.com/gpg-encryption-subkeys<p>I recently <a href="https://github.com/rraval/zeroindexed/issues/6">revisited how I was managing passwords</a> but wanted to maintain the core structure of secrets encrypted via a PGP key. PGP is a good fit here, these secrets are linked to my identity as a person, as opposed to secrets linked to a specific machine or service.</p> <p>I already have <a href="https://keys.openpgp.org/search?q=D7C7F5708E5AAFACE0ED8D4C5D18C31569142F5F">an established PGP key</a>, but this use case demands distributing decryption capabilities to at least my primary computer and mobile phone. My existing PGP key is already used for a hodge podge of purposes, so to limit scope of compromise, it makes sense to generate an encryption and decryption scheme for the specific purpose of securing my passwords.</p> <p>I thought I could simply generate a new PGP subkey tied to my main identity and this idea <a href="https://security.stackexchange.com/a/31598">seems to have some colloquial support</a>:</p> <blockquote> <p>Use one primary key for each <em>identity</em> you need, otherwise, use subkeys.</p> <p>[…]</p> <p>Examples for using subkeys:</p> <ul> <li>You want to use multiple keys for multiple devices (so you won’t have to revoke your computer’s key if you lose your mobile)</li> </ul> </blockquote> <p><strong>tl;dr:</strong> Don’t bother. The PGP ecosystem does not support encryption subkeys for a specific purpose. You should just generate an entirely separate PGP key for your use case. For me securing passwords, I’m not even bothering to publish this new key to keyservers. The rest of this blog post is dedicated to describing the various rabbit holes I explored before settling on this “don’t bother” conclusion.</p> <!--more--> <h1 id="pgp-identities-and-keys">PGP identities and keys</h1> <p>The previous paragraphs have used the words “identity” and “key” rather loosely, so let’s bring some rigour here (though I’m optimizing for clarity and not pedantry so caveat emptor).</p> <p>At the top level for PGP, there is a private/public keypair called the <code class="language-plaintext highlighter-rouge">mainkey</code>. This keypair is used to certify various <code class="language-plaintext highlighter-rouge">subkey</code>s as belonging to the <code class="language-plaintext highlighter-rouge">mainkey</code>.</p> <p>Each <code class="language-plaintext highlighter-rouge">subkey</code> has associated <a href="https://datatracker.ietf.org/doc/html/rfc4880#section-5.2.3.21">key flags</a> which determine what operations this <code class="language-plaintext highlighter-rouge">subkey</code> is valid for. Besides ontological clarity, <a href="https://serverfault.com/a/399366">this distinction contributes to the security properties of the overall system</a>:</p> <blockquote> <p>If you look into the details of the math of public-key encryption, you will discover that signing and decrypting are actually identical operations. Thus in a naïve implementation it is possible to trick somebody into decrypting a message by asking them to sign it.</p> </blockquote> <p>The <code class="language-plaintext highlighter-rouge">mainkey</code> is also used to certify various <code class="language-plaintext highlighter-rouge">user id</code>s (also known as <code class="language-plaintext highlighter-rouge">UID</code>, <code class="language-plaintext highlighter-rouge">identity</code>), which usually ties the <code class="language-plaintext highlighter-rouge">mainkey</code> to one or more real world names and email addresses.</p> <p>For more on this topic, the clearest explanation I can find is <a href="https://davesteele.github.io/gpg/2014/09/20/anatomy-of-a-gpg-key/">Dave Steele’s anatomy of a GPG key</a>.</p> <h1 id="the-ecosystem-is-simplistic">The ecosystem is simplistic</h1> <p>The initial thought is to simply associate some metadata with a specially generated <code class="language-plaintext highlighter-rouge">subkey</code> that identifies it as special-only-for-explicit-personal-use. The vague hope is to prevent others from implicitly using this key when sending me encrypted email or sharing work related secrets.</p> <p>Unfortunately, the ecosystem doesn’t support any metadata of the sort. You can <a href="https://www.gnupg.org/documentation/manuals/gnupg/Specify-a-User-ID.html">force GPG to use a specific subkey with an explicit invocation</a>:</p> <blockquote> <p>When using <code class="language-plaintext highlighter-rouge">gpg</code> an exclamation mark (!) may be appended to force using the specified primary or secondary key and not to try and calculate which primary or secondary key to use.</p> </blockquote> <p>However the <a href="https://wiki.debian.org/Subkeys">default behaviour for GPG makes it easy to do the wrong thing</a>:</p> <blockquote> <p>If you have multiple encryption subkeys, gpg is said to encrypt only for the most recent encryption subkey and not for all known and not revoked encryption subkeys.</p> </blockquote> <p>In a somewhat similar vein, <a href="https://github.com/open-keychain/open-keychain/issues/2281#issuecomment-370384337">OpenKeychain</a> will encrypt to all subkeys with the encryption flag set, regardless of metadata:</p> <blockquote> <p>Since v 3.4 we encrypt to all subkeys with the capability flag for encryption: <a href="https://github.com/open-keychain/open-keychain/commit/7648602fc876df3ec5827f3bba1ebbb8ae92eaae">7648602</a></p> </blockquote> <p>Overall, this means that ecosystem support for any sort of metadata of encryption <code class="language-plaintext highlighter-rouge">subkey</code> purpose is weak. It cannot be relied upon without rolling our own tools, which is already more work than I’m willing to get into.</p> <h1 id="key-usage-flags-are-not-sufficient">Key usage flags are not sufficient</h1> <p>I’m not the first person to have thought of using subkeys in this fashion, here’s a <a href="https://lists.gnupg.org/pipermail/gnupg-users/2011-December/043365.html">mailing list post by Mike Cardwell from almost a decade ago</a> that’s short enough to quote in its entirety:</p> <blockquote> <p>If I have more than one signing subkey in my keypair, is there a way of advertising the purpose of each subkey with the public key that people download? Eg:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>This subkey is for signing email only This subkey is for signing sourcecode only </code></pre></div> </div> <p>I’ve considered generating an entirely separate keypair and then cross-signing them, but that seems inelegant.</p> </blockquote> <p>To which there is <a href="https://lists.gnupg.org/pipermail/gnupg-users/2011-December/043366.html">a helpful reply by Daniel Kahn Gillmor</a>:</p> <blockquote> <p>My first thought was to look up the list of standardized “key usage flags”, which are defined here: <a href="">https://tools.ietf.org/html/rfc4880#section-5.2.3.21</a></p> </blockquote> <p>Looking at the quoted RFC, there are no “key usage flags” that explicitly cover the usage I intend with my password management subkey:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0x01 - This key may be used to certify other keys. </code></pre></div></div> <p>Almost certainly not, the password subkey should not be certifying other keys.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0x02 - This key may be used to sign data. </code></pre></div></div> <p>No, we don’t care for signing, just encrypting.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0x04 - This key may be used to encrypt communications. </code></pre></div></div> <p>For the password use case, this flag ought to be true. But this alone is ambiguous because there are other keys, like encrypted email, that would also have this bit set.</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0x08 - This key may be used to encrypt storage. </code></pre></div></div> <p>This is the most promising flag but the RFC does not standardize the distinction:</p> <blockquote> <p>Note however, that it is a thorny issue to determine what is “communications” and what is “storage”. This decision is left wholly up to the implementation; the authors of this document do not claim any special wisdom on the issue and realize that accepted opinion may change.</p> </blockquote> <p>In the 14 years since the publication of that RFC, it seems like implementations have not evolved a conventional distinction either. Here’s the <a href="https://github.com/gpg/gnupg/blob/4fcfac6feb2a6c2b14883ba406afc917e8d4be42/g10/getkey.c#L2448">GPG source code</a>:</p> <div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="cm">/* We do not distinguish between encrypting communications and encrypting storage. */</span> <span class="k">if</span> <span class="p">(</span><span class="n">flags</span> <span class="o">&amp;</span> <span class="p">(</span><span class="mh">0x04</span> <span class="o">|</span> <span class="mh">0x08</span><span class="p">))</span> <span class="p">{</span> <span class="n">key_usage</span> <span class="o">|=</span> <span class="n">PUBKEY_USAGE_ENC</span><span class="p">;</span> <span class="n">flags</span> <span class="o">&amp;=</span> <span class="o">~</span><span class="p">(</span><span class="mh">0x04</span> <span class="o">|</span> <span class="mh">0x08</span><span class="p">);</span> <span class="p">}</span> </code></pre></div></div> <p>Which only leaves us with the last defined key usage bits:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>0x10 - The private component of this key may have been split by a secret-sharing mechanism. 0x20 - This key may be used for authentication. 0x80 - The private component of this key may be in the possession of more than one person. </code></pre></div></div> <p>None of these are relevant to the encryption-for-passwords use case. Passwords are used for authentication and <code class="language-plaintext highlighter-rouge">0x20</code> mentions authentication, but the intent is for PGP subkeys that directly participate in the authentication scheme — like a PGP subkey that can also be an SSH key — instead of the indirect workflow of “subkey decrypts password then actor uses password to authenticate”.</p> <h1 id="subkey-notations-have-no-adoption">Subkey notations have no adoption</h1> <p>Going back to <a href="https://lists.gnupg.org/pipermail/gnupg-users/2011-December/043366.html">Daniel Kahn Gillmor’s mailing list response</a>, they suggest an alternative form of subkey metadata called “notations”:</p> <blockquote> <p>Instead, you could add a notation to the subkey signatures. <a href="">https://tools.ietf.org/html/rfc4880#section-5.2.3.16</a></p> <p>[…]</p> <p>You might want to discuss it with the (very low-traffic at the moment) working group: IETF OpenPGP Working Group <code class="language-plaintext highlighter-rouge">&lt;ietf-openpgp at imc.org&gt;</code></p> </blockquote> <p>To summarize the RFC: notations are a standardized mechanism to add arbitrary name/value octet sequences to a subkey. The RFC even mitigates name collisions, private use should have an <code class="language-plaintext highlighter-rouge">@</code> while standardized notation names have no <code class="language-plaintext highlighter-rouge">@</code> but need to be registered with IANA.</p> <p>Even though the RFC expends the energy to standardize notations, implementations and conventions haven’t really capitalized on this affordance. <a href="https://security.stackexchange.com/a/120662">This StackExchange answer notes</a>:</p> <blockquote> <p>Notations are rarely used in practice (actually I’ve never seen real usage, although there are few notation subpackets to be found in key server dumps). Example usage might be to add the location of an identity check during key signing, or the document types presented.</p> </blockquote> <p>As far as I can tell, there are no actual standardized notation names. The <a href="https://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-6">IANA registry for PGP notations</a> is empty.</p> <p>I did find this <a href="https://www.ietf.org/archive/id/draft-ietf-openpgp-rfc4880bis-10.html#section-5.2.3.17">IETF internet draft</a> that expands RFC 4880 to specify some standardized notation names and intended usage, but:</p> <ol> <li>None of the 10 new notation names would fit this purpose of marking an encryption key as not fit for general communications.</li> <li>The internet draft has expired and I don’t know if it’ll be picked up again and driven to consensus. Although it has been through 10 revisions and the expiry was only ~5 weeks ago, so clearly some people care.</li> </ol> <h1 id="user-ids-are-not-linked-to-subkeys">User IDs are not linked to subkeys</h1> <p>The final idea is to put this metadata in the comment field of a user ID linked to the <code class="language-plaintext highlighter-rouge">mainkey</code>. I’m guessing that this <a href="https://lists.gnupg.org/pipermail/gnupg-users/2013-November/048172.html">mailing list post is after similar goals</a> (though it’s phrased in <a href="https://xyproblem.info/">classic XY fashion</a>, so who knows):</p> <blockquote> <p>Is it possible to have subkeys with different comments than the main key? How?</p> </blockquote> <p>The mailing list question is based on a misunderstanding, user IDs can have arbitrary comments but <a href="https://lists.gnupg.org/pipermail/gnupg-users/2013-November/048176.html">they are not linked to subkeys in any way</a>:</p> <blockquote> <p>Both subkeys and user IDs are related to a mainkey. In this sense user IDs and subkeys are on the same level. There is no such thing as a subkey user ID or a user ID subkey. User IDs are just “names” for a mainkey. You can add and remove user IDs and subkeys. They do not affect the other group.</p> </blockquote> <p>So besides being unstandardized, user ID comments are simply the wrong tool for this purpose.</p> <h1 id="takeaways">Takeaways</h1> <p>Just generate a separate PGP <code class="language-plaintext highlighter-rouge">mainkey</code> for this specific purpose. Give it a distinct user ID for quick identification, I used <a href="https://support.google.com/a/users/answer/9308648">a plus sign on Gmail to mark the email address</a>. Consider if this <code class="language-plaintext highlighter-rouge">mainkey</code> even needs to be published on public keyservers, I did not bother since this key is for private use and does not represent a person.</p> <p>In May 2021, trying to use subkeys would be actively harmful. If the subkey were published alongside your existing <code class="language-plaintext highlighter-rouge">mainkey</code>, implementations would implicitly use it to encrypt communications intended for you. This adds additional awkwardness to the poor UX that PGP email already suffers.</p> <h1 id="changelog">Changelog</h1> <p>2021-10-30: <a href="https://davesteele.github.io/">Dave Steele</a> reached out over email and pointed out that GPG can indeed encrypt to an explicit subkey with an exclamation point syntax. <a href="https://gpgtools.tenderapp.com/discussions/problems/8919-force-subkey-for-signing">The earlier reference that claimed this couldn’t be done</a> has been removed.</p> <p>2021-05-09: Published.</p>Ronuk RavalI recently revisited how I was managing passwords but wanted to maintain the core structure of secrets encrypted via a PGP key. PGP is a good fit here, these secrets are linked to my identity as a person, as opposed to secrets linked to a specific machine or service. I already have an established PGP key, but this use case demands distributing decryption capabilities to at least my primary computer and mobile phone. My existing PGP key is already used for a hodge podge of purposes, so to limit scope of compromise, it makes sense to generate an encryption and decryption scheme for the specific purpose of securing my passwords. I thought I could simply generate a new PGP subkey tied to my main identity and this idea seems to have some colloquial support: Use one primary key for each identity you need, otherwise, use subkeys. […] Examples for using subkeys: You want to use multiple keys for multiple devices (so you won’t have to revoke your computer’s key if you lose your mobile) tl;dr: Don’t bother. The PGP ecosystem does not support encryption subkeys for a specific purpose. You should just generate an entirely separate PGP key for your use case. For me securing passwords, I’m not even bothering to publish this new key to keyservers. The rest of this blog post is dedicated to describing the various rabbit holes I explored before settling on this “don’t bother” conclusion.A blog begins…2021-04-18T00:00:00+00:002021-04-18T00:00:00+00:00https://zeroindexed.com/jekyll-begins<p>I’ve been putting off setting up a blog for far too long. There’s been a bunch of content worth talking about, but it’s been blocked on this grandiose ambition to rethink the medium of the digital written word. <a href="https://www.youtube.com/watch?v=7s664NsLeFM">If you wish to write a blog from scratch, you must first invent a whole new blogging engine</a>.</p> <p>Hopefully that’ll still happen. For now, let’s try low fidelity things and validate that I can even commit to the blogging thing. GitHub Pages. Jekyll. Minima. All content, zero <a href="http://www.catb.org/~esr/jargon/html/Y/yak-shaving.html">yaks to shave</a>.</p> <!--more--> <p>Besides the usual first blog post drivel, this post accomplishes two additional things:</p> <ol> <li>It demonstrates that Jekyll is properly configured to extract excerpts and put that content on the home page.</li> <li>It forms the starting point of a personal challenge. It’s 2021-04-18, let’s see how long and how many system transitions the “permalink” of <a href="https://zeroindexed.com/jekyll-begins">https://zeroindexed.com/jekyll-begins</a> can survive.</li> </ol> <h1 id="changelog">Changelog</h1> <p>2021-05-08: Added this changelog.</p> <p>2021-04-18: Published.</p>Ronuk RavalI’ve been putting off setting up a blog for far too long. There’s been a bunch of content worth talking about, but it’s been blocked on this grandiose ambition to rethink the medium of the digital written word. If you wish to write a blog from scratch, you must first invent a whole new blogging engine. Hopefully that’ll still happen. For now, let’s try low fidelity things and validate that I can even commit to the blogging thing. GitHub Pages. Jekyll. Minima. All content, zero yaks to shave.