<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>hi, it&#39;s mike</title>
    <link>https://mike.puddingtime.org/tags/1password/</link>
    <description>Recent content on hi, it&#39;s mike</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>mike@puddingtime.org (mike)</managingEditor>
    <webMaster>mike@puddingtime.org (mike)</webMaster>
    <copyright>© 2026, mike</copyright>
    <lastBuildDate>Sun, 28 Jan 2024 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://mike.puddingtime.org/tags/1password/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Keeping secrets with 1Password&#39;s CLI tool</title>
      <link>https://mike.puddingtime.org/posts/2024-01-28-keeping-secrets-with-1password-s-cli-tool/</link>
      <pubDate>Sun, 28 Jan 2024 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2024-01-28-keeping-secrets-with-1password-s-cli-tool/</guid>
      <description>A couple of ways to securely reference your secrets in scripts and apps using 1Password&amp;rsquo;s CLI tool (and a detour into gpg-based approaches.)</description>
      <content:encoded><![CDATA[<p>I wrote the initial version of my <a href="/posts/2024-01-26-daily-notes/">linkding plugin for Newsboat</a> using <a href="https://github.com/bkeepers/dotenv">dotenv</a> to provide my Linkding API key. You just have a <kbd>.env</kbd> file in your home directory with a simple &ldquo;<kbd>KEY=VALUE</kbd>&rdquo; setup. Works fine for not hardcoding your secrets into scripts and reducing the chance you&rsquo;ll end up adding a credential to version control, but the secrets are sitting around unencrypted.</p>
<p>Now that I have it working at about the same level of reliability as the other plugins in the Newsboat repo I&rsquo;ll pull out the dependency on <kbd>dotenv</kbd> and just tell the would-be consumer &ldquo;get this credential into an environment variable, hardcode it, or do something else that feels safe to you.&rdquo;</p>
<p>For myself, I&rsquo;m weighing a couple of options because I&rsquo;d like to do a little better than having a bunch of credentials sitting around in the plain.</p>
<p>Over the years I&rsquo;ve handled this with mutt by combining gpg with mutt&rsquo;s <kbd>source</kbd> config command:</p>
<ol>
<li>
<p>Make a very minimal rc file in mutt&rsquo;s config syntax that sets your user and password:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">       set imap_user=you@example.com
</span></span><span class="line"><span class="cl">       set imap_pass=yourimappassword1234</span></span></code></pre></div>
</li>
<li>
<p>Encrypt that file with gpg:</p>
<p><kbd>gpg -r <a href="mailto:yourkey@example.com">yourkey@example.com</a> &ndash;encrypt passwordfile</kbd></p>
</li>
<li>
<p>Use mutt&rsquo;s <kbd>source</kbd> directive in your <kbd>muttrc</kbd> to decrypt the file on the fly and read in those two directives:</p>
<p><kbd>source &ldquo;gpg -d ~/.mutt/passwords.gpg |&quot;</kbd></p>
</li>
</ol>
<p>If you have gpg set up correctly, you&rsquo;ll get a key authentication prompt when you run mutt. The credentials are never stored in the plain on disk, and you&rsquo;ll get a gpg password prompt every now and then if you have other stuff going on, such as multiple accounts that each need to periodically source that config when you change between them. mutt&rsquo;s <kbd>source</kbd> is just &ldquo;do whatever is in this file,&rdquo; same as <kbd>zsh</kbd>&rsquo;s, so I eventually landed on a way to do the same thing in a shell environment:</p>
<p><kbd>$(gpg &ndash;decrypt ./setenv.sh.gpg)</kbd></p>
<p>That just decrypts <kbd>setenv.sh.gpg</kbd> and runs the commands inside, which can be just setting a bunch of environment variables in the current shell environment. The data is never decrypted to disk.</p>
<p>That seems like a good general solution that covers a lot of drive-by security scenarios.</p>
<p>In the process of working that out, I wondered about 1Password&rsquo;s CLI tool. The few times I saw it mentioned the demos were for secrets management, not retrieval, but I took another look at the docs and it does have some interesting provisions for getting your secrets out of 1Password from the CLI.</p>
<p>Basically, when you use the <kbd>op</kbd> command&rsquo;s <kbd>run</kbd> argument you can tell it to source in some environment variables from a <kbd>.env</kbd> file that uses <kbd>op</kbd>&rsquo;s internal URI scheme to pull credentials out of your vault. An example resource reference looks like this:</p>
<p><kbd>op://Personal/Linkding/password</kbd></p>
<p>If you put that in an <kbd>env</kbd> file with a variable assignment, the <kbd>op</kbd> command can source it and pass it along to a shell command. So:</p>
<p><kbd>op run &ndash;env-file=&quot;$HOME/.env&rdquo;  &ndash; ~/bin/linkding.rb</kbd></p>
<p>&hellip; reads from a file that looks something like this:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="nv">LINKDING_USER</span><span class="o">=</span><span class="s2">&#34;op://Personal/Linkding/username&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">LINKDING_TOKEN</span><span class="o">=</span><span class="s2">&#34;op://Personal/Linkding/credential&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">FRESHRSS_USER</span><span class="o">=</span><span class="s2">&#34;op://Personal/FreshRSS/username&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nv">FRESHRSS_PASS</span><span class="o">=</span><span class="s2">&#34;op://Personal/FreshRSS/credential&#34;</span></span></span></code></pre></div>
<p>&hellip; and supplies the <kbd>linkding</kbd> script with a value for this line:</p>
<p><kbd>token = ENV[&lsquo;LINKDING_TOKEN&rsquo;]</kbd></p>
<p>If you&rsquo;re already auth&rsquo;d into 1Password and you&rsquo;ve enabled integration between the CLI tool and the desktop app, then you don&rsquo;t have to do anything. If you need to re-auth your 1Password instance, you&rsquo;ll get a biometric prompt. If you&rsquo;re ssh&rsquo;d into a remote host where you wouldn&rsquo;t get the biometric prompt, you can bypass that by setting <kbd>OP_BIOMETRIC_UNLOCK_ENABLED=false</kbd> but you&rsquo;ll need to explicitly auth the 1Password CLI tool from the command line. It doesn&rsquo;t seem to just fail over to a CLI auth.</p>
<p>So, handled the 1Password way, your <kbd>.env</kbd> file could remain unencrypted, but you&rsquo;d probably be best off aliasing any scripts or commands you run where you want the <kbd>op</kbd> tool to interpolate your <kbd>.env</kbd> file.</p>
<p>It&rsquo;s a little more cumbersome but maybe there&rsquo;s benefit over the long haul from knowing that you just have to keep credentials in 1Password and can reference them elsewhere instead of maintaining an encrypted <kbd>.env</kbd> file. It&rsquo;s also nice to have a biometric prompt or system auth vs. using gpg keys, which require you to have another password on hand (at least until 1Password quits punting on a gpg agent to pair with the ssh one).</p>
<p>For now I&rsquo;ve only got enough stuff connected this way to use 1Password with FreshRSS and my Linkding plugin. Newsboat allows you to set your RSS service&rsquo;s password with output from a shell command, so I&rsquo;ve got that set to:</p>
<p><kbd>freshrss-passwordeval &ldquo;op read op://Personal/FreshRSS/credential&rdquo;</kbd></p>
<p>If I&rsquo;m auth&rsquo;d into 1Password, great: It just runs and sets the credential for NewsBoat. If I&rsquo;m not, great as well: It just runs and tosses up a biometric prompt before proceeding.</p>
<p>I&rsquo;m also using the env file pattern for Newsboat, for my bookmarking command:</p>
<p><kbd>bookmark-cmd &ldquo;op run &ndash;env-file=&quot;$HOME/.env&quot;  &ndash; ~/bin/linkding.rb&rdquo;</kbd></p>
<p>That&rsquo;s because I don&rsquo;t want to write my Linkding plugin to require any particular infrastructure. It just wants an environment variable, which is supplied by wrapping the script in the <kbd>op run</kbd> command with an <kbd>&ndash;env-file</kbd> switch. If someone wants to take the script and use another way to get the variable into their environment, or just decide to take their chances and hard-code it because they&rsquo;re comfortable with that risk, they can. If I ever stop using 1Password I can similarly just figure out a new secrets backend and may be able to avoid rewriting a bunch of utility scripts if I keep using this approach. If I want to use one of my scripts on a host where I don&rsquo;t have 1Password, well, there are other ways.</p>
<p><span class="underline"><span class="underline">Update:</span></span> I wondered about that mutt setup I have and ended up seeing what would happen if I replaced the whole &ldquo;load mutt, source a gpg-encrypted file&rdquo; thing with simple 1Password resource references. It works pretty well. If you&rsquo;re signed into 1Password, it just works. If you&rsquo;re not, you get a biometric prompt:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">imap_user</span><span class="o">=</span><span class="sb">`</span>op <span class="nb">read</span> op://Personal/MuttFastmail/imap_user<span class="sb">`</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">smtp_pass</span><span class="o">=</span><span class="sb">`</span>op <span class="nb">read</span> op://Personal/MuttFastmail/smtp_pass<span class="sb">`</span>
</span></span><span class="line"><span class="cl"><span class="nb">set</span> <span class="nv">imap_pass</span><span class="o">=</span><span class="sb">`</span>op <span class="nb">read</span> op://Personal/MuttFastmail/imap_pass<span class="sb">`</span></span></span></code></pre></div>
<p>Same caveats as with everything: If I ever end up wanting to use my mutt config on a machine I can&rsquo;t put 1Password on, I&rsquo;d need to go back to my old gpg file pattern.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2024-01-25</title>
      <link>https://mike.puddingtime.org/posts/2024-01-25-daily-notes/</link>
      <pubDate>Thu, 25 Jan 2024 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2024-01-25-daily-notes/</guid>
      <description>Applied empathy. GNOME Chrome profile launchers revisited. Fence day. The pruning saw.</description>
      <content:encoded><![CDATA[<h2 id="applied-empathy">Applied empathy</h2>
<p>I got an odd compliment last week: I learned that a few of my colleagues and I are considered &ldquo;unnaturally collaborative.&rdquo;</p>
<p>I won&rsquo;t go into a lot of detail about the surrounding context, but it came down to, &ldquo;we identified a potential source of conflict, one of us called a meeting, the other two showed up, we took turns talking, we arrived at rough consensus, and we trusted the convener to type up the notes (which they shared in advance) and send them upstairs.&rdquo;</p>
<ol>
<li>I think there&rsquo;s a philosophical notion that anything that exists in time in space is in nature, and is therefore natural. Including, my philosophy instructor said with a wry grin for probably the 113th time in his career, purple unicorns, which must exist because time and space are infinite and therefore must contain virtually anything we could conceive. Including three directors who bias toward positive collaboration.</li>
<li>If there are any moral defects to be found here, they are in the imaginations of people who think three collaborative directors are the equivalent of purple unicorns.</li>
</ol>
<p>Anyhow, I am honestly on the fence about whether it was a compliment or not. I once had a performance review downgraded because, my boss&rsquo;s boss explained, my &ldquo;how&rdquo; dimension was so good that it was actually a liability, and he demanded it be lowered from a &ldquo;5&rdquo; to a &ldquo;4&rdquo; to reflect the dangers it posed to me and others.</p>
<p>But I do have a second story from this week that has caused me to feel a little less smug about it all.</p>
<p>There is a process at work that everybody hates. It involves multiple layers of functional and administrative staff, a bad mix of people who are conditioned to be process-oriented close readers and people who are understandably determined to cut any corners they can. There are also three warring tools ecosystems.</p>
<p>I hate it because it involves things I have been involved with and fixed in my past, but I am too new and don&rsquo;t have enough standing or juice to get out and push, so while nobody is challenging my right to weigh in or make adjustments within my remit, I&rsquo;m in the territory of &ldquo;the little attitude thrusters you use in Lunar Lander&rdquo; vs. &ldquo;the warp nacelles of the Enterprise.&rdquo;</p>
<p>So I&rsquo;ve been making little adjustments here and there, identifying the places my own patch of process goes wrong most often, and making little adjustments. Including a few based on things I&rsquo;ve observed but haven&rsquo;t introspected, that I <em>thought</em> were helpful to the people who own that leg of the process.</p>
<p>Until today, when one of them did something slightly different from another one of them that seemed to be an utter refutation of all my proactive consideration for their needs.</p>
<p>So I broke down and asked what I was missing and they took a paragraph to expose me to a whole set of things that go wrong for them that aren&rsquo;t <em>exacerbated</em> by what I was doing, but that what I was doing wasn&rsquo;t <em>helping</em>; and how in other ways I was possibly slowing down another thing. Because I was being curious and helpful, but possibly not curious enough and maybe too helpful, at least in the wrong proportions at the wrong stages.</p>
<p>I&rsquo;m giving myself a 4/5.</p>
<p>My heart was in the right place, but that&rsquo;s table stakes.</p>
<h2 id="chrome-profile-launchers-revisited">Chrome profile launchers revisited</h2>
<p>A couple of weeks ago I wrote a post sharing how to <a href="/posts/2024-01-14-daily-notes/#making-chrome-profiles-available-from-gnome-launcher-and-junction">create GNOME launcher items for individual Chrome profiles</a>. It&rsquo;s a kind of cool thing to do if you want to just get straight to a given profile, and it works well with browser pickers like Junction or Browsers.</p>
<p>At some point, I noticed that one Chrome profile was ignoring my 1Password extension&rsquo;s preference to stay in sync with the 1Password desktop app, so I kept having to log in to 1Password over and over: Every time you close your last Chrome window (as with any Linux desktop app and unlike on a Mac), an unsynced 1Password extension decides (wisely, sanely) that your auth&rsquo;d session is over.</p>
<p>Years of Mac use have made it essentially impossible for me to leave a window open if I&rsquo;m not using it. Why would I? It&rsquo;s just visual clutter, and the app itself is sitting there on warm standby. So I kept geting logged out of 1Password and had to keep re-authing and it was unpleasant.</p>
<p>1Password has some <a href="https://support.1password.com/connect-1password-browser-app/">guidance on how to get the extension to sync with the desktop again</a>, and while I don&rsquo;t want to sound churlish it amounts to &ldquo;turn it off then turn it on again.&rdquo; As an IT person, I respect that, but it didn&rsquo;t do me any good. Removing and reinstalling didn&rsquo;t help either, and I didn&rsquo;t have a lot of confidence in that because the 1Password extension leaves some data behind when you remove it: Instead of needing your complete credentials (address, password, and the secret key), you just need the password when you reinstall.</p>
<p>So my last-ditch &ldquo;avoid filing a ticket at all costs&rdquo; play was to create a fresh Chrome profile and reinstall the plugin there, reasoning that the new profile&rsquo;s sandbox wouldn&rsquo;t have any legacy data in the form of cached stuff, or maybe a config file that changed between plugin versions and creates edge cases despite &ldquo;mostly working.&rdquo;</p>
<p>I turned off sync for the new profile, set up 1Password, then turned sync on. It worked as expected, even when all my other stuff got pulled in.</p>
<p>I flipped back over to the original Chrome instance giving me the problems and it was still stuck.</p>
<p>So, do I want to log back in to 1Password upwards of three dozen times a day, retrain myself to never close the last Chrome window, or just call it a day on getting fancy with profile launchers? Maybe another option is to point the launcher at the directory for the new, working profile, but as I sat here at 6 in the morning screwing around with Chrome profiles I re-remembered that over-optimization is a thing:</p>
<p>I wanted to save a few keystrokes here and there so I over-optimized a collection of things that I&rsquo;ve observed in the past are individually complex and inconsistent, only a few of which are built with even one of the other components in mind. Something is eventually going to get weird in all that. And I don&rsquo;t even like Chrome. I use it for work because we&rsquo;re a Google shop and I don&rsquo;t care if the data Google is harvesting reveals that I spend an ungodly amount of time in an invoicing system, a contract management system, and JIRA. There is no use case for using Chrome with a personal Google account. Firefox is fine for that.</p>
<p>So, lesson learned. Chrome is just &ldquo;the work browser,&rdquo; and I don&rsquo;t have any other profiles. Done and done.</p>
<h2 id="storm-stuff">Storm stuff</h2>
<p>We got off pretty light with the recent ice storm unpleasantness: Overnight without power, then a few downed branches and the death knell for a fence we&rsquo;d hoped would hold out until spring, or at least fall onto our side of the yard. But it didn&rsquo;t. It fell into the neighbor&rsquo;s yard so we hauled away the part that couldn&rsquo;t be propped back up and went looking for contractors.</p>
<p>I don&rsquo;t know if there&rsquo;s a secret to Angie&rsquo;s List, but I&rsquo;ve never cracked it. I put in a request, try to specify that email is going to be the best way to reach me, get hammered with phone calls (many of which are just hangups), and never feel like I end up with much choice.</p>
<p>This time around I got steered onto Yelp by a search engine, which then steered me into its contractor finder. Wow. Vastly different experience: A half-dozen emails before the morning was over, incredibly high responsiveness, and offers to come out and do estimates within the next day or two. I thought the project would be sitting until February or March, but it looks like today is New Fence Day.</p>
<p>To deal with the branches I ended up getting a Ryobi pruning saw to go with all my other 18v Ryobi stuff. I eyed larger chainsaws, but that just wasn&rsquo;t the job at hand, storage is at a premium, and there&rsquo;s not a foreseeable need given what&rsquo;s on the property.</p>
<p>The pruning saw is great. I don&rsquo;t see using it a ton, but it shares a battery with several other things, it&rsquo;s very quiet, light, and compact, and it strikes a nice balance between &ldquo;still obviously a dangerous tool&rdquo; and &ldquo;accessible.&rdquo; Meaning, it&rsquo;s easy to use and handle, but you&rsquo;re still very clear after looking at it that it could fuck you up.</p>
<p>As I slapped the battery in and put on my eye protection, I remembered to pause and tell myself the micro-fiction I tell myself whenever I&rsquo;m around power tools:</p>
<blockquote>
<p>He approached the saw with the confidence of a middle-aged man who once took a shop class in junior high.</p>
</blockquote>
<p>That&rsquo;s not a completely accurate statement of the situation.</p>
<p>I did once take a shop class in junior high, but my bone-deep caution around tools was learned on the floor of an RV factory where there was no grumpy shop teacher yelling if you even looked distracted. Ask me to share my &ldquo;the guy with the sheet of fiberglass, a table saw, no push stick, and no guard&rdquo; story. But even that experience was a long time ago. Better to just pretend like I know a bit more than my fictional character, and way less than I actually do.</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
