From a39ac67aeb8fb17b35d82cd075bd0461177cf73f Mon Sep 17 00:00:00 2001 From: "Berk D. Demir" Date: Sun, 19 Oct 2025 15:31:35 -0700 Subject: [PATCH] _1password-gui: update-sources.py use Sequoia instead of GnuPG r-ryantm update environment fails to go through GnuPG backed PGP signature verification due to various intricacies of GnuPG's IPC requirements to do rather basic things. See: https://nixpkgs-update-logs.nix-community.org/_1password-gui-beta/2025-08-20.log Switch from GnuPG to Sequoia, and use `sq` CLI tool for a more minimalistic signature verification. This change also simplifies trust anchor key acquisition to downloading directly from 1Password's HTTPS service, instead of fetching by key id from a PGP Key Server. Testing: % for pkg in _1password-gui{,-beta}; do nix-shell ~nixpkgs/maintainers/scripts/update.nix --argstr commit true --argstr skip-prompt true --argstr commit true --argstr package ${pkg} done Going to be running update for following packages: - 1password-8.11.11 Running update for: Preparing worktree (new branch 'update-tmp_manrfba') Updating files: 100% (49124/49124), done. HEAD is now at 1c8e629a6193 _1password-gui: update-sources.py use Sequoia Enqueuing group of 1 packages - 1password-8.11.11: UPDATING ... [master 6228d7811fce] _1password-gui: 8.11.11 -> 8.11.14 Date: Sun Oct 19 22:42:25 2025 +0000 1 file changed, 10 insertions(+), 10 deletions(-) Deleted branch update-tmp_manrfba (was 6228d7811fce). Packages updated! Going to be running update for following packages: - 1password-8.11.14-19.BETA Running update for: Preparing worktree (new branch 'update-tmpezi_89b8') Updating files: 100% (49124/49124), done. HEAD is now at 6228d7811fce _1password-gui: 8.11.11 -> 8.11.14 Enqueuing group of 1 packages - 1password-8.11.14-19.BETA: UPDATING ... [master cd5f65a2f240] _1password-gui-beta: 8.11.14-19.BETA -> 8.11.16-30.BETA Date: Sun Oct 19 22:43:03 2025 +0000 1 file changed, 10 insertions(+), 10 deletions(-) Deleted branch update-tmpezi_89b8 (was cd5f65a2f240). Packages updated! --- .../_1/_1password-gui/update-sources.py | 51 +++++++++---------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/pkgs/by-name/_1/_1password-gui/update-sources.py b/pkgs/by-name/_1/_1password-gui/update-sources.py index c0e9bbb08803..bdf257cb1664 100755 --- a/pkgs/by-name/_1/_1password-gui/update-sources.py +++ b/pkgs/by-name/_1/_1password-gui/update-sources.py @@ -1,5 +1,5 @@ #!/usr/bin/env nix-shell -#!nix-shell -i python3 -p python3 gnupg +#!nix-shell -i python3 -p python3 sequoia-sq import json import os import shutil @@ -9,8 +9,7 @@ import tempfile from collections import OrderedDict DOWNLOADS_BASE_URL = "https://downloads.1password.com" -OP_PGP_KEYID = "3FEF9748469ADBE15DA7CA80AC2D62742012EA22" - +OP_PGP_KEY_URL = "https://downloads.1password.com/linux/keys/1password.asc" class Sources(OrderedDict): def __init__(self): @@ -21,43 +20,39 @@ class Sources(OrderedDict): with open("sources.json", "w") as fp: print(json.dumps(self, indent=2), file=fp) -class GPG: + +class PGP: def __new__(cls): if not hasattr(cls, "_instance"): cls._instance = super().__new__(cls) return cls._instance def __init__(self): - if hasattr(self, "gnupghome"): + if hasattr(self, "signer_file"): return - self.gpg = shutil.which("gpg") - self.gpgv = shutil.which("gpgv") - self.gnupghome = tempfile.mkdtemp(prefix="1password-gui-gnupghome.") - self.env = {"GNUPGHOME": self.gnupghome} - self._run( - self.gpg, - "--no-default-keyring", - "--keyring", - "trustedkeys.kbx", - "--keyserver", - "keyserver.ubuntu.com", - "--receive-keys", - OP_PGP_KEYID, - ) + self.sq = shutil.which("sq") + if (self.sq is None): + raise SystemExit(f"sequoia sq not found") - def __del__(self): - shutil.rmtree(self.gnupghome) + self.signer_file, _ = nix_store_prefetch(OP_PGP_KEY_URL) + + def verify(self, sig, tarball): + args = [ + self.sq, + "--batch", + "--home=none", + "verify", + f"--signer-file={self.signer_file}", + f"--signature-file={sig}", + tarball + ] - def _run(self, *args): try: - subprocess.run(args, env=self.env, check=True, capture_output=True) + subprocess.run(args, check=True, capture_output=True) except subprocess.CalledProcessError as cpe: print(cpe.stderr, file=sys.stderr) - raise SystemExit(f"gpg error: {cpe.cmd}") - - def verify(self, sigfile, datafile): - return self._run(self.gpgv, sigfile, datafile) + raise SystemExit(f"sq error: {cpe.cmd}") def nix_store_prefetch(url): @@ -89,7 +84,7 @@ def download(channel, os, version, arch): # Linux release tarballs come with detached PGP signatures. if os == "linux": store_path_sig, _ = nix_store_prefetch(url + ".sig") - GPG().verify(store_path_sig, store_path_tarball) + PGP().verify(store_path_sig, store_path_tarball) return url, hash