
    <h1 id="standard-unix-password-manager">Standard UNIX password
      manager</h1>
    <p>Password management is one of those computing problems you
      probably don't think about often, because modern computing usually
      has an obvious default solution built-in.</p>
    <p>A website prompts you for a password, and your browser auto-fills
      it in for you.</p>
    <p>Problem solved.</p>
    <p>However, not all browsers make it very easy to get to your
      passwords store, which makes it complex to migrate passwords to a
      new system without also migrating the rest of your user profile,
      or to share certain passwords between different users.</p>
    <p>There are several good open source options that offer
      alternatives to the obvious defaults, but as a user of Linux and
      UNIX, I love a minimal and stable solution when one is available.</p>
    <p>The <code>pass</code> command is a password manager that uses
      GPG encryption to keep your passwords safe, and it features
      several system integrations so you can use it seamlessly with your
      web browser of choice.</p>
    <h2 id="install-pass">Install pass</h2>
    <p>The <code>pass</code> command is provided by the <a
        href="https://www.passwordstore.org">PasswordStore</a> project.</p>
    <p>You can install it from your software repository or ports
      collection.</p>
    <p>For example, on Fedora:</p>
    <pre><code>
$ sudo dnf <span class="hljs-keyword">install</span> pass
</code></pre>
    <p>On Debian and similar:</p>
    <pre><code>
$ sudo apt <span class="hljs-keyword">install</span> pass
</code></pre>
    <p>Because the word <code>pass</code> is common, the name of the
      package may vary, depending on your distribution and operating
      system.</p>
    <p>For example, <code>pass</code> is available on Slackware and
      FreeBSD as <code>password-store</code>.</p>
    <p>The <code>pass</code> command is open source, so the source code
      is available at <a href="https://git.zx2c4.com/password-store">git.zx2c4.com/password-store</a>.</p>
    <h2 id="create-a-gpg-key">Create a GPG key</h2>
    <p>First, you must have a GPG key to use for encryption.</p>
    <p>You can use a key you already have, or create a new one just for
      your password store.</p>
    <p>To create a GPG key, use the <code>gpg</code> command along with
      the <code>--gen-key</code> option (if you already have a key you
      want to use for your password store, you can skip this step):</p>
    <pre><code>
$ gpg <span class="hljs-comment">--gen-key</span>
</code></pre>
    <p>Answer the prompts to generate a key.</p>
    <p>When prompted to provide values for <strong>Real name</strong>,
      <strong>Email</strong>, and <strong>Comment</strong>, you must
      provide a response for each one, even though GPG allows you to
      leave them empty.</p>
    <p>In my experience, <code>pass</code> fails to initialize when one
      of those values is empty.</p>
    <p>For example, here are my responses for purposes of this article:</p>
    <pre><code>
Real name: Tux

Emai<span class="hljs-variable">l:</span> tux@example.<span class="hljs-keyword">com</span>

Commen<span class="hljs-variable">t:</span> My <span class="hljs-keyword">first</span> key
</code></pre>
    <p>This information is combined, in a different order, to create a
      unique GPG ID.</p>
    <p>You can see your GPG key ID at any time:</p>
    <pre><code>
$ gpg --<span class="hljs-keyword">list</span>-secret-<span class="hljs-built_in">keys</span> | <span class="hljs-keyword">grep</span> uid

uid:     Tux (My <span class="hljs-keyword">first</span> key) tux@example.<span class="hljs-keyword">com</span>
</code></pre>
    <p>Other than that, it's safe to accept the default and recommended
      options for each prompt.</p>
    <p>In the end, you have a GPG key to serve as the master key for
      your password store.</p>
    <p>You must keep this key safe.</p>
    <p>Back it up, keep a copy of your GPG keyring on a secure device.</p>
    <p>Should you lose this key, you lose access to your password store.</p>
    <h2 id="initialize-a-password-store">Initialize a password store</h2>
    <p>Next, you must initialize a password store on your system.</p>
    <p>When you do, you create a hidden directory where your passwords
      are stored, and you define which GPG key to use to encrypt
      passwords.</p>
    <p>To initialize a password store, use the <code>pass init</code>
      command along with your unique GPG key ID.</p>
    <p>Using my example key:</p>
    <pre><code>
<span class="hljs-variable">$ </span>pass init <span class="hljs-string">"Tux (My first key) &lt;tux@example.com&gt;"</span>
</code></pre>
    <p>You can define more than one GPG key to use with your password
      store, should you intend to share passwords with another user or
      on another system using a different GPG key.</p>
    <h2 id="add-and-edit-passwords">Add and edit passwords</h2>
    <p>To add a password to your password store, use the <code>pass
        insert</code> command followed by the URL (or any string) you
      want <code>pass</code> to keep.</p>
    <pre><code>
$ pass insert example<span class="hljs-meta">.org</span>
</code></pre>
    <p>Enter the password at the prompt, and then again to confirm.</p>
    <p>Most websites require more than just a password, and so <code>pass</code>
      can manage additional data, like username, email, and any other
      field.</p>
    <p>To add extra data to a password file, use <code>pass edit</code>
      followed by the URL or string you saved the password as:</p>
    <pre><code>
$ pass edit example<span class="hljs-meta">.org</span>
</code></pre>
    <p>The first line of a password file must be the password itself.</p>
    <p>After that first line, however, you can add any additional data
      you want, in the format of the field name followed by a colon and
      then the value.</p>
    <p>For example, to save <code>tux</code> as the value of the <code>username</code>
      field on a website:</p>
    <pre><code>
myFakePassword123

<span class="hljs-symbol">username:</span> tux
</code></pre>
    <p>Some websites use an email address instead of a username:</p>
    <pre><code>
<span class="hljs-selector-tag">myFakePassword123</span>

<span class="hljs-selector-tag">email</span>: <span class="hljs-selector-tag">tux</span>@<span class="hljs-keyword">example</span>.<span class="hljs-keyword">com</span>
</code></pre>
    <p>A password file can contain any data you want, so you can also
      add important notes or one-time recovery codes, and anything else
      you might find useful:</p>
    <pre><code>
myFake;_;Password123
<span class="hljs-symbol">
email:</span> tux<span class="hljs-meta">@example</span>.com

recovery <span class="hljs-string">email:</span> tux<span class="hljs-meta">@example</span>.org

recovery <span class="hljs-string">code:</span> <span class="hljs-number">03</span>a5<span class="hljs-number">-1992</span>-ee12<span class="hljs-number">-238</span>c
<span class="hljs-symbol">
note:</span> This is your personal account, use company SSO at work
</code></pre>
    <h2 id="list-passwords">List passwords</h2>
    <p>To see all passwords in your password store:</p>
    <pre><code>
$ pass list

Password Store

├── <span class="hljs-built_in">example</span>.com

├── <span class="hljs-built_in">example</span>.org
</code></pre>
    <p>You can also search your password store:</p>
    <pre><code>
$ pass find bandcamp

Search Terms: bandcamp

└── www<span class="hljs-selector-class">.bandcamp</span><span class="hljs-selector-class">.com</span>
</code></pre>
    <h2 id="integrating-your-password-store">Integrating your password
      store</h2>
    <p>Your password store is perfectly usable from a terminal, but
      that's not the only way to use it.</p>
    <p>Using extensions, you can use <code>pass</code> as your web
      browser's password manager.</p>
    <p>There are several different applications that provide a bridge
      between <code>pass</code> and your browser.</p>
    <p>Most are listed in the <strong>CompatibleClients</strong>
      section of <a href="https://www.passwordstore.org">passwordstore.org</a>.</p>
    <p>I use <a href="https://codeberg.org/PassFF/passff-host">PassFF</a>,
      which provides a <a
        href="https://addons.mozilla.org/en-US/firefox/addon/passff/">Firefox
        extension</a>.</p>
    <p>For browsers based on Chromium, you can use <a
        href="https://github.com/browserpass/browserpass-native">Browserpass</a>
      with the <a
        href="https://github.com/browserpass/browserpass-extension">Browserpass
        extension</a>.</p>
    <p>In both cases, the browser extension requires a "host
      application", or a background bridge service to allow your browser
      to access the encrypted data in your password store.</p>
    <p>For PassFF, download the install script:</p>
    <pre><code>
$ wget https:<span class="hljs-regexp">//</span>codeberg.org<span class="hljs-regexp">/PassFF/</span>passff-host<span class="hljs-regexp">/releases/</span>download<span class="hljs-regexp">/latest/i</span>nstall_host_app.sh
</code></pre>
    <p>Review the script to confirm that it's just installing the host
      application, and then run it:</p>
    <pre><code>
$ bash ./install_host_app.<span class="hljs-keyword">sh</span> firefox

Python <span class="hljs-number">3</span> <span class="hljs-built_in">executable</span> located at /usr/bin/<span class="hljs-keyword">python3</span>

Pass <span class="hljs-built_in">executable</span> located at /usr/bin/pass

Installing Firefox host config

Native messaging host <span class="hljs-keyword">for</span> Firefox <span class="hljs-built_in">has</span> been installed <span class="hljs-keyword">to</span> /home/tux/.mozilla/native-messaging-hosts.
</code></pre>
    <p>Install the browser extension, and then restart your browser.</p>
    <p>When you navigate to a URL with an file in your password store, a
      <code>pass</code> icon appears in the relevant fields.</p>
    <p>Click the icon to complete the form.</p>
    <p>Alternately, a <code>pass</code> icon appears in your browser's
      extension tray, providing a menu for direct interaction with many
      <code>pass</code> functions (such as copying data directly to your
      system clipboard, or auto-filling only a specific field, and so
      on.)</p>
    <h2 id="password-management-like-unix">Password management like UNIX</h2>
    <p>The <code>pass</code> command is extensible, and there are some
      great add-ons for it.</p>
    <p>Here are some of my favourites:</p>
    <ul>
      <li>
        <p><a href="https://github.com/tadfisher/pass-otp#readme">pass-otp</a>:
          Add one-time password (OTP) functionality.</p>
      </li>
      <li>
        <p><a href="https://github.com/roddhjav/pass-update#readme">pass-update</a>:
          Add an easy workflow for updating passwords that you
          frequently change.</p>
      </li>
      <li>
        <p><a href="https://github.com/roddhjav/pass-import#readme">pass-import</a>:
          Import passwords from chrome, 1password, bitwarden,
          apple-keychain, gnome-keyring, keepass, lastpass, and many
          more (including <code>pass</code> itself, in the event you
          want to migrate a password store).</p>
      </li>
    </ul>
    <p>The <code>pass</code> command and the password store system is a
      comfortably UNIX-like password management solution.</p>
    <p>It stores your passwords as text files in a format that doesn't
      even require you to have <code>pass</code> installed for access.</p>
    <p>As long as you have your GPG key, you can access and use the data
      in your password store.</p>
    <p>You own your data not only in the sense that it's local, but you
      have ownership of how you interact with it.</p>
    <p>You can sync your password stores between different machines
      using rsync or syncthing, or even backup the store to cloud
      storage.</p>
    <p>It's encrypted, and only you have the key.</p>