IJHack / QtPass

QtPass is a multi-platform GUI for pass, the standard unix password manager.
https://qtpass.org/
GNU General Public License v3.0
1.03k stars 162 forks source link

support `PASSWORD_STORE_SIGNING_KEY` with profiles #624

Closed unDocUMeantIt closed 1 year ago

unDocUMeantIt commented 1 year ago

Is your feature request related to a problem? Please describe.

we are evaluating the use of pass/QtPass in a team and are trying to figure out a trust model that would not force all team members to learn how to use git. the encryption with defined OpenPGP keys per unit, like pass/QtPass are offering, is exactly what we would like to use, since we are already using OpenPGP anyway. but IIUC, everyone with access to the password store could add key IDs to any .gpg-id files.

Describe the solution you'd like

in the pass docs, the environment variable PASSWORD_STORE_SIGNING_KEY is listed with the description:

If this environment variable is set, then all .gpg-id files and non-system extension files must be signed using a detached signature using the GPG key specified by the full 40 character upper-case fingerprint in this variable. If multiple fingerprints are specified, each separated by a whitespace character, then signatures must match at least one. The init command will keep signatures of .gpg-id files up to date.

QtPass already supports profiles to switch between password stores, which is a neat feature. unfortunately, it currently doesn't seem to supprt setting the PASSWORD_STORE_SIGNING_KEY variable. i think this would need to be set independently per profile to be really useful, i.e. add a "select signing keys" button in a new row next to the profle path.

Describe alternatives you've considered

it's not really an alternative, but we are discussing limiting the write access to the password store to designated admins to mitigate the potential damage. we would like to combine this with the signing of .gpg-id files.

shemeshg commented 1 year ago

Hi

I'm not QtPass developer, but as far as my experience from building pass GUI (native c++ still under development). Signing is not protection, and should be used to state the who changed,

It is possible to get this info from the git log however signing ensure that the person who claim to be really is.

To protect the passworstore you'll have to

  1. authorize it at the remote github
  2. Put the .gpgid in protected parent folder, and let pass look for it up the tree from a git's submodule. This will not prevent malicious user to add it's own corrupted .gpgid
    unless you can screen only .gpg extension files with .gitignore or git server side hook.

    Actually, you can do it all easily with server side hook without parent git repository. just look into your remote hooks folder at the server for examples

  3. The signer should not be per with profiles, but identify the user who actually did the change.
  4. pass does not offer any protection against tempering the encrypted data, or corrupting it (even when used with age,tomb etc... once you have remote and local access to the file system.

Did I understood you question correctly?

unDocUMeantIt commented 1 year ago

what you are mentioning is something different, i.e. the signing of git commits, which is a feature of git itself, independently from pass.

the PASSWORD_STORE_SIGNING_KEY environment variable, however, is a feature of pass. when used, pass init can generate a .gpg-id.sig file for each .gpg-id file and later check the integrity of a given .gpg-id file by validating that signature. this is independent of git, you can use it on a flat file system.

these features are perhaps less interesting when all you do is managing your own passwords. but when working in a team, there should be more control over the public keys defined in .gpg-id files.

in the meantime, we have written a bash script that does the job for us. we might release it once it's tested more.

shemeshg commented 1 year ago

I see, you mean

The verification

verify_file() {
    [[ -n "$PASSWORD_STORE_SIGNING_KEY" ]] || return 0
    [[ -f "$1.sig" ]] || die "Signature for $1 does not exist."

    local fingerprints fingerprint found=0
    fingerprints="$($GPG "${PASSWORD_STORE_GPG_OPTS_ARRAY[@]}" --verify --status-fd=1 "$1.sig" "$1" 2>/dev/null | sed -n 's/\[GNUPG:\] VALIDSIG \([A-F0-9]\{40\}\) .* \([A-F0-9]\{40\}\)$/\1\n\2/p')"

    for fingerprint in $PASSWORD_STORE_SIGNING_KEY; do
        [[ $fingerprint =~ ^[A-F0-9]{40}$ ]] || continue
        [[ $fingerprints == *$fingerprint* ]] && { found=1; break; }

I think I understand

$PASSWORD_STORE_SIGNING_KEY is the one every user declares locally as the "manager" of the .gpg_id.(the one I trust with authorizations)

and this must be defined for every local user.

The problem, is that it was expected to be specific for every repository. And for that you need something like pyenv that set the environment correctly when entering folder.

The way you managed to solve it was as bash script that read and set this from somewhere, based on PASSWORD_STORE_DIR

This is certainly where QtPass shines because it utilize all pass util features (unlike native implementation like pass simple prs or gopass

Personally, I would prefer to prevent tempering with the .pgp_id at the lowest level (no matter if the frontend respect this parameter or not)

See: ruby implementation for that in github server and client hook

https://git-scm.com/book/en/v2/Customizing-Git-An-Example-Git-Enforced-Policy

timegrid commented 1 year ago

To enable the pass signature check in qtpass, the envvar can be set via PASSWORD_STORE_SIGNING_KEY=123 qtpass. If the signature is invalid, the following error is visible in the qtpass gui:

gpg: all values passed to '--default-key' ignored
Signature for [...]/.gpg-id is invalid.

Unfortunately profile selection via command line parameter does not work reliably here, otherwise as a workaround you could have provided scripts to restart qtpass with the right signing key id and store set.

unDocUMeantIt commented 1 year ago

in the meantime, we have written a bash script that does the job for us. we might release it once it's tested more.

we've just released our script, hope it's useful for others: https://github.com/C3S/passtore