diff --git a/content/posts/20250628T131556--consolidating-secrets-in-pass__emacs_linux_security.md b/content/posts/20250628T131556--consolidating-secrets-in-pass__emacs_linux_security.md
new file mode 100644
index 0000000..50751bd
--- /dev/null
+++ b/content/posts/20250628T131556--consolidating-secrets-in-pass__emacs_linux_security.md
@@ -0,0 +1,416 @@
++++
+title = "Consolidating Secrets in Pass"
+author = ["Peter Tillemans"]
+date = 2025-06-28T13:15:00+02:00
+tags = ["emacs", "linux", "security"]
+categories = ["shell", "apps"]
+draft = false
+[taxonomies]
+ tags = ["emacs", "linux", "security"]
+ categories = ["shell", "apps"]
++++
+
+## Background {#background}
+
+Like a lot of people I've had a long history managing passwords and
+secrets over the years. From a little black book, over an Excel sheet,
+using a GPG encoded secrets file (works really well with Emacs gpg
+support), 1password (till they racked up their prices), lastpass (till
+they got bought by the Evil LogMeIn Corp), KeepassXC and lately [pass](https://passwordstore.org).
+
+I was perfectly happy with KeepassXC for a very long time, except for
+the command line integration. So I kept ending up with passwords in
+**.envrc** files in folders and excluded in the global **.gitignore** to avoid
+too many red cheeks. While this does keep secrets out of harms way
+mostly, it kept nagging that I had them in plain text in those
+files. In theory there is **keepassxc-cli** to query the passwords from
+the command line, but let's say the experience does not spark joy. It
+has no easy way to cache the password between calls and it is
+optimized for interactive use. (AFAICT, just the giant size of the
+command to type gives me dread).
+
+Some day I stumbled over **pass** and found that after setup I could just
+`pass snamellit/website` to get the password on stdout. I [wrote about
+the setup and emacs integration in a previous post](https://www.snamellit.com/blog/20240624t104859-secrets-management-using-unix-password-store-pass-linux-osx-sysadmin/). Since it
+leverage gpg, password caching is handled by the gpg-agent and my
+**.envrc** files quickly were purged of blasphemous secrets, replace by
+pure bliss:
+
+```shell
+export MY_SECRET=$(pass my/secret)
+export OTHER_SECRET=$(pass other/secret)
+```
+
+similarly in emacs I can consistently get my passwords and related
+info with:
+
+```elisp
+(org-gcal-client-id (auth-source-pass-get 'secret "snamellit/org-gcal-client"))
+(org-gcal-client-secret (auth-source-pass-get "id"
+"snamellit/org-gcal-client"))
+```
+
+When needed the **gpg-agent** will launch the appropriate pin-entry
+program whether in terminal or in the GUI and the caching will not
+force me to login several times when entering the folder.
+
+So I ended up with my interactive use covered by **KeepassXC** and
+automated use by **pass**.
+
+However, after some time I ended up with hundreds of secrets in
+**KeepassXC**, hundreds in **pass**, it is not always clear whether use is
+interactive or automated so confusion and duplication starts and
+things become harder to manage. In addition **KeepassXC** was using
+historically Dropbox to make it available on all my devices, recently
+migrated to Nextcloud, which has issues with dealing with conflicts
+which occasionally bite me in the behind. On the other hand **pass**
+secrets are stored encrypted in git where conflict punch you in the
+face. I prefer the latter. And started contemplating whether to move
+everything to pass.
+
+Thanks to the encouragement of SummerEmacs, one of the more
+enthusiastic SystemCrafters, ensuring the great experience in browsers
+and iOS mobile devices I had no more excuses to keep postponing it.
+
+
+## Preparation {#preparation}
+
+I started out with keeping my pass passwords as part of my
+dotfiles. This was convenient when they were few. However this is
+weird so this will attract weirdness when configuring all integrations
+I'll need.
+
+Also **pass** supports a **git** command to manage the password-store with git
+which is not really useful when it is part of something else. So the
+first order of the day is to move all secrets to a separate repository
+and update the **dotfiles** to check for presence and clone the repo if
+missing (and do a gently pull when it is).
+A quick visit to each of the machines in my machine park to apply this
+change.
+Everything still seems to be working.
+
+
+## Migration of the KeepassXC data {#migration-of-the-keepassxc-data}
+
+I used the [pass-import](https://github.com/roddhjav/pass-import) tool which adds in **import** command to pass which
+supports a crazy amount of password managers, including keepassxc. For
+keepassxc it need the **pykeepass**. If you're running on Arch, everything
+is a `yay -S` away. However on Ubuntu and its derivatives it is the
+usual slog we start to get accustomed to. It's all in the [pass-import
+README](https://github.com/roddhjav/pass-import) , note that on Ubunty the **pykeepass** library is available with
+`apt install python3-pykeepass`.
+
+Once it is installed I tried a dry run (with the `-d` flag) to see if
+basic functionality is working
+
+```shell
+pass import -a -d keepassxc ~/Nextcloud/Apps/Keepassxc/Passwords.kdbx
+Password for /home/pti/Nextcloud/Apps/Keepassxc/Passwords.kdbx:
+ w Data would be imported from keepassxc to pass
+ . Passwords imported from: /home/pti/Nextcloud/Apps/Keepassxc/Passwords.kdbx
+ . Passwords exported to: /home/pti/.password-store
+ . Number of password imported: 2035
+ . All data imported
+ w Weak password detected: eDGQqipE might be weak. Score 2 (100000001 guesses). This estimate is based on the sequence eDGQqipE(bruteforce)
+ w Weak password detected: eDGQqipE might be weak. Score 2 (100000001 guesses). This estimate is based on the sequence eDGQqipE(bruteforce)
+ w Weak password detected: eDGQqipE might be weak. Score 2 (100000001 guesses). This estimate is based on the sequence eDGQqipE(bruteforce)
+... large list of names of secrets
+
+```
+
+This asks for the password of the Keepass file and some remarks it
+has.
+
+This all looks reasonable. So we can try the import. Since the
+password-store is a git repo no real damage can be done to it (as it
+is safely pushed somewhere else where the import tool cannot touch it)
+and any damage done can be reverted....
+
+Now is a good time to check if the mooring lines of your laptop are
+properly secured as encrypting all the secrets will spin up the
+propellors if the number is large enough.
+
+I run it again without the `-d` flag and after several minutes the
+noise dies down and I am left with a lot of additional folders in my
+`~/.password-store` which match the grouping in KeepassXC. The files
+contain the secrets and the expected metadata. This looks good so I
+add/commit the things to complete the level.
+
+
+## Integration with iOS for my iPhone {#integration-with-ios-for-my-iphone}
+
+Let's start with the most scary one : the iPhone.
+
+Upon recommendation I had installed **passforios** which needs to be
+configured.
+
+Configuring the host, repo and username to use for the git repository
+is straightforward enough.
+
+I always use ssh to access my repos so we need to add an ssh keypair
+for this purpose. There is no support to generate key-pairs in
+passforios for reasons, so I have to do it externally and upload the
+key. A quick `ssh-keygen` , uploading the public key to the forge,
+allowing access to the repo and if I can get the private key on my
+phone we can access the repo.
+
+**passforios** has a nice feature to load ascii armored keys via a QR
+code. A bit digging surfaced the [asc-key-to-qr-code-gif tool](https://github.com/yishilin14/asc-key-to-qr-code-gif) which
+was made for this specific purpose. The ssh key is already in the
+appropriate format so this can be directly converted
+
+```shell
+./asc-to-gif.sh ~/.ssh/id-passforios ssh-pub.gif
+display ssh-pub.gif
+```
+
+Then go to the repository settings, press the circled i on the **SSH
+Key** button, select the ASCII-Armor Key and click to scan the QR
+code. Point the camera to the QR code on the screen and it should
+appear in the key field in the app.
+
+We have to repeat this 2 more times to get the private and public key
+for the password-store into the app. First exporting the keys
+
+```shell
+gpg --export -a 1234ABCD >gpg.pub
+gpg --export-secret-key -a 1234ABCD >gpg.key
+```
+
+converting to a gif, displaying them and scanning them in \*Settings ->
+PGP Key -> ASCII-Armor Key in the respective fields.
+
+If, after synching, you go now to the Passwords you should be greeted
+with a listing of all folders and keys and the secrets should be
+visible if made visible by tapping the eye icon.
+
+I needed to enable **passforios** as a source for autofill : Settings ->
+Passwords -> Autofill Passwords and slide the toggle for **Pass**. I also
+disabled the toggle for **Strongbox** which I was using for integration
+with the Keepass database.
+
+Now I see the option to select the secrets from the **passforios** app. It
+does not narrow down to the right key, but that is a problem for
+future me.
+
+Ok, the hard part is done. Or at least the most risky part, ... in my
+eyes... whatever. Moving on...
+
+
+## Integration with FireFox {#integration-with-firefox}
+
+Checking at the bottom of the [pass website](https://www.passwordstore.org/) we find that **passff** is the
+good stuff for integration with FireFox. From previous adventures with
+KeepassXC and NativeMessaging I assumed there had to be a host part to
+be installed too.
+
+Indeed we are directed to the [passff-host github repo](https://codeberg.org/PassFF/passff-host) to get an
+install-script which generates the native messaging json for the
+different browsers and a small executable python script which contains
+remarkable clean and no-dependency code. Similarly the install script
+is straightforward. I do not understand why it support half a dozen
+browser, mostly chrome based as for the life of me I cannot find an
+extension which uses this host program. So either I need bigger
+glasses or there is some knowledge beyond my grasp.
+
+Running the installer, installing the extension, restarting firefox
+for good luck and the extension appears and offers passwords on the
+sites I try.
+
+Out of curiosity I check the configuration in
+~.mozilla/native-messaging :
+
+```shell
+pti@tuxedo ~> ls .mozilla/native-messaging-hosts/
+org.keepassxc.keepassxc_browser.json passff.json passff.py*
+pti@tuxedo ~> cat .mozilla/native-messaging-hosts/passff.json
+{
+ "name": "passff",
+ "description": "Host for communicating with zx2c4 pass",
+ "path": "/home/pti/.mozilla/native-messaging-hosts/passff.py",
+ "type": "stdio",
+ "allowed_extensions": [ "passff@invicem.pro" ]
+}
+pti@tuxedo ~> cat .mozilla/native-messaging-hosts/passff.py
+#!/usr/bin/python3
+"""
+ Host application of the browser extension PassFF
+ that wraps around the zx2c4 pass script.
+"""
+
+import json
+...
+
+```
+
+Nothing out of the ordinary, the passff.py python is the same as in
+the repo. My old keepassxc extension support is still there.
+
+Firefox is installed natively on this machine, not with a flatpak
+which I assume will come with its own challenges.
+
+
+## Chromium Support {#chromium-support}
+
+Time to tackle the Chrome family. Chrome is required to put food on
+the table so we have to get that going eventually. But Chrome is
+distributed as a flatpak (or a snap but I am **NOT** going to deal with
+that), and I can install Chromium natively, and apparently native
+installs are **MUCH** better supported than the versions in wrappers so
+let's start with that one first.
+
+From the [pass website](https://www.passwordstore.org/) we find that **[browserpass](https://github.com/browserpass/browserpass-extension)** is the way to go for
+the chrome family. The browser extension installs from the usual
+places without drama and starts promptly complaining it cannot find
+the native host to talk to.
+
+The native host in question is from [the browsaerpass-native sister
+repo](https://github.com/browserpass/browserpass-native) . As usual for all distro's there are packages ready to install
+but because Ubuntu-derivative I can compile from source. Downloading
+the source for version 3.1.0 from the [releases page](https://github.com/browserpass/browserpass-native/releases). Again this repo
+refers to all browsers including firefox although I cannot for the
+life of me find a Firefox Extension supporting this host app.
+
+Then building and installing timelapse :
+
+```shell
+tar -xzvf ~/Downloads/browserpass-native-3.1.0.tar.gz
+cd browserpass-native-3.1.0
+ls
+less README.md
+PREFIX=/usr/local make configure
+sudo make PREFIX=/usr/local install
+which browserpass
+```
+
+which shows the executable lives at `/usr/local/bin/browserpass` and
+this totally went fine the first time (NOT!!!!).
+
+The `Makefile` has support to install the magic json to enable native
+messaging for the different browsers.
+
+```shell
+PREFIX=/usr/local make hosts-chromium-user
+PREFIX=/usr/local make hosts-chrome-user
+```
+
+The second invocation is a hail-mary because I already know the Chrome
+flatpak does not look in the same places and will require some
+additional finnagling
+
+For now focus on Chromium and check if the configuration looks
+reasonable:
+
+```shell
+pti@tuxedo ~> cd .config/chromium/NativeMessagingHosts/
+pti@tuxedo ~/.c/c/NativeMessagingHosts> ls
+com.github.browserpass.native.json@
+pti@tuxedo ~/.c/c/NativeMessagingHosts> cat com.github.browserpass.native.json
+{
+ "name": "com.github.browserpass.native",
+ "description": "Browserpass native component for the Chromium extension",
+ "path": "/usr/local/bin/browserpass",
+ "type": "stdio",
+ "allowed_origins": [
+ "chrome-extension://naepdomgkenhinolocfifgehidddafch/",
+ "chrome-extension://pjmbgaakjkbhpopmakjoedenlfdmcdgm/",
+ "chrome-extension://klfoddkbhleoaabpmiigbmpbjfljimgb/"
+ ]
+}
+```
+
+Cool, the executable is looked at where it is installed (this is not
+obvious, don't ask how I know). The rest looks also like how these
+things should look. Let's try...
+
+The extension settings page is no longer complaining the native host
+is missing and there are password entries visible. Checking with some
+website shows the password is injected. yay!.
+
+Level complete, ready for the final boss.
+
+
+## Enabling Chrome Support, now with more Flatpak! {#enabling-chrome-support-now-with-more-flatpak}
+
+Ok, we have a working chromium support so repo access, host app,
+native host configuration et al are proven working. We can only focus
+on jumping over the Flatpak Firewall...
+
+As a good cargo cultist I do a literature study and find that I should
+
+- find the config location of the flatpak app
+
+- use `flatpak-spawn` to spawn the native messaging host app
+
+- enable D-Bus Session socket access for chrome
+
+- Package up the calling of the host app in a single script to
+ configure in the json.
+
+ Not necessarily in that order....
+
+For the permission to access D-Bus Session start up **flatseal** from
+flathub, navigate to **com.google.Chrome** and enable the D-Bus Session
+socket. This should be possible with some additional cursing in the
+manifest file of Chrome. I cannot find decent reference documentation
+in a reasonable time, so **flatseal** it is.
+
+The configuration of the flatpak app is easy too, painful experience
+seared in my brain that flatpaks look in **~/.var/app/** folder so for
+Chrome this will be **~/.var/app/com.google.Chrome** . From the hail-mary
+install for chrome done above I know that it just creates a symbolic
+link to
+**/usr/local/lib/browserpass/hosts/chromium/com.github.browserpass.native**
+so we can start from there. We will have to edit that so copy it. We
+also need a wrapper to call the native host app
+
+```shell
+cd ~/.var/app/com.google.Chrome/config/google-chrome/NativeMessagingHosts
+cp /usr/local/lib/browserpass/hosts/chromium/com.github.browserpass.native
+ec browserpass.sh
+```
+
+Add the content of the wrapper
+
+```shell
+#!/bin/sh
+cd ~
+/usr/bin/flatpak-spawn --host /usr/local/bin/browserpass 2>/tmp/browserpass-error.log
+```
+
+I added the optional redirect of **stderr** to an error logfile because
+from experience I know nothing ever goes wrong if you enable error
+reporting beforehand.
+
+```shell
+chmod +x browserpass.sh
+pwd
+pwd | wl-copy
+ec com.github.browserpass.native.json
+```
+
+Installing the browserpass extension in Chrome after restarting it (I
+am not superstitious, just careful) and I can bask in the glory of
+seeing proposals for passwords when trying to log in. Most of the
+proposals are pretty garbage, but that is a problem for future me.
+
+
+## Conclusion {#conclusion}
+
+I have access to my password-store secrets on my phone, my browsers on laptop and
+desktop, and most importantly **Emacs**. Narrowing of the proposed secrets
+is, euhmmm, sub-optimal, but since it is sub-optimal in the same way
+on all platforms I assume that some TLC in the password-store and
+cleaning of the migrated secrets will fix that in time.
+
+In the process I gained much more confidence in configuring flatpak
+apps. I can decommission the keepassxc system including dealing with
+the sync conflicts (which was admittedly super easy with the merge
+database feature in KeepassXC). I no longer have to deal with giving
+the KeepassXC window a place on the desktop and autostarting it.
+
+I am a bit puzzled about the host-apps referring to supporting
+browsers for which no extensions are available. This probably might
+warrant some additional investigation.
+
+Big step forward