pass - the standard unix password manager

Vorwort und Installation

pass bezeichnet sich selbst als der Standardpasswort-Manager für Unix, was etwas irreführend ist, da er kein Bestandteil von Posix oder einer ähnlichen Spezifikation ist; das ändert aber nichts daran das er der Unix-Philosophie entsprechen will und das auch tut. Im Gegensatz zu anderen Passwortmanagern erstellt bzw. legt pass die Passwörter in Dateien ab, die mit GnuPG verschlüsselt werden; per Default ist das ~/.password-store.

Die Installation von pass ist relativ simpel; entweder man verwendet den Paketmanager seines Systems oder klont das Repo und kompiliert die Sourcen. Das ist mit folgenden zwei Kommandos erledigt:

$ git clone https://git.zx2c4.com/password-store
$ sudo make install
$ git clone https://git.zx2c4.com/password-store

Per Default installiert das pass nach /usr; wer den Pfad ändern will, muss lediglich das Makefile anpassen und PREFIX ändern.

Optionen

Die Optionen/Parameter von pass sind folgende

pass init [–path=unterverzeichnis] gpg-id
Damit wird ein neues Passwortverzeichnis erstellt, in dem dann die einzelnen Dateien gespeichert werden. Mit --path= kann man auch ein anderes Verzeichnis angeben.
pass ls [unterverzeichnis]
Hiermit kann man sich die gespeicherten Passwörter anzeigen lassen.
pass find
Mit find sucht man nach den Namen der Passwörter
pass [show] [–clip(=zeilennummer)] pass
Damit kann man sich die Passwörter anzeigen lassen oder sie direkt in das Clipboard kopieren. Darin bleiben sie allerdings nur für 45 Sekunden bevor sie daraus gelöscht werden.
pass grep
Mit grep kann man in den entschlüsselten Passwortdateien suchen.
pass insert [–echo,-e | –multiline,-m] [–force,-f] passwortname
So kann man entweder ein neues Passwort hinzufügen oder auf die Konsole ausgeben lassen.
pass edit pass
Damit kann man das Passwort in einem Editor bearbeiten
pass generate [–no-symbols,-n] [–clip,-c] [–in-place,-i | –force,-f] passwortname [passwortlänge]
Die Standardlänge der generierten Passwörter beträgt 25 Zeichen. --no-symbols schließt Symbole aus, --clip schickt es direkt ins Clipboard, --in-place überschreibt lediglich die erste Zeile mit einem Passwort und --force sollte klar sein.
pass rm [–recursive,-r] [–force,-f] passwortname
Damit werden Passwörter gelöscht
pass mv [–force,-f] alt neu
So können Passwörter verschoben oder umbenannt werden.
pass cp [–force,-f] alt neu
Wie bei pass mv, nur das sie diesmal nur kopiert werden.
pass git git-command
Wenn die Passwörter in einem Git-Repo abgelegt werden, kann man so darauf zugreifen bzw. sie so bearbeiten.
pass [help | version]
Das sollte klar sein.

Vorbereitung

Bevor man pass nutzen kann, muss einige Sachen erledigen. Zuerst muss man einen GPG-Key erstellen; das erledigt man mit gpg --gen-key. Das dort angegebene Passwort ist das Masterpasswort! Wenn man das nicht mehr weiß, hat man die Arschkarte gezogen. Man kann auch einen bereits vorhandenen Key verwenden, aber wegen der Übersichtlichkeit verwende ich einen neuen Key.
Wenn man gpg --gen-key eingibt, wird man aufgefordert einige Informationen anzugeben wie z. B. den Realnamen, die Emailadresse, .. Hier kann man die “echten” Daten eingeben oder sich welche ausdenken. Wenn das erledigt ist, beendet man das ganze mit O für Okay, was dann auch den Key generiert. Danach erhält man folgende Ausgabe:

pub   ed25519 2026-08-12 [SC] [expires: 2029-08-11]
      646FA7404EEB7765743EBCD481F148F61E0A9CD0 
uid                      Pass Word <fo@ob.ar>
sub   cv25519 2026-08-12 [E] [expires: 2029-08-11]

Per Default läuft der Key nach einiger Zeit ab; wer das nicht will, kann das auch abstellen. Das geht mit

> gpg --edit-key 646FA7404EEB7765743EBCD481F148F61E0A9CD0

Jetzt reicht ein expire, gefolgt von 0 (Null), welches man mit y bestätigt und abschließend mit save speichert. Ist das geschehen, kann man anfangen mit pass zu arbeiten.

Zuerst muss man pass initialisieren. Wieso das ein Git-Repo ist/wird, kommt später.

> pass init 646FA7404EEB7765743EBCD481F148F61E0A9CD0
mkdir: created directory '/home/dope/.password-store/'
Password store initialized for 646FA7404EEB7765743EBCD481F148F61E0A9CD0
> pass git init 
Initialized empty Git repository in /home/dope/.password-store/.git/
[main (root-commit) ba7442d] Add current contents of password store.
 Author: Christian Schneider <fo@ob.ar>
 1 file changed, 1 insertion(+)
 create mode 100644 .gpg-id
[main d38317c] Configure git repository for gpg file diff.
 Author: Christian Schneider <fo@ob.ar>
 1 file changed, 1 insertion(+)
 create mode 100644 .gitattributes

Erste Schritte mit pass

Nachdem pass grundlegend einsatzbereit ist, kann man anfangen ihn dafür zu nutzen, wofür er da ist. Dazu fügen wir mal ein Passwort hinzu. Will man z. B. sein Passwort für Codeberg hinzufügen, reicht ein pass insert codeberg. Das ‘codeberg’ ist lediglich der Nick für das Passwort, damit man weiß das man darin das Passwort für Codeberg abgelegt hat.

> pass insert codeberg
Enter password for codeberg: 
Retype password for codeberg: 
[main d7c0e7a] Add given password for codeberg to store.
 Author: Christian Schneider <fo@ob.ar>
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 codeberg.gpg

Das Passwort das man hier eingeben muss, ist das Passwort welches man bei Codeberg benutzt; also das, welches gespeichert werden soll und nicht das von pass selbst. Wer - wie ich - schlecht im erstellen/ausdenken von Passwörtern ist, kann auch das pass überlassen.

❯ pass generate Github
[main cf5f910] Add generated password for Github.
 Author: Christian Schneider <fo@ob.ar>
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 Github.gpg
The generated password for Github is:
]YG/dst9&"nEp7%t]1c&;_});

Das erstellte Passwort in Zeile 7 muss man dann selbstverständlich auch als Loginpasswort bei GitHub verwenden.

Passwörter organisieren

Per Default legt pass für jedes erstellte Passwort eine Datei an, was ziemlich unübersichtlich werden kann. Wenn man pass ls eingibt, erhält man jetzt folgende Ausgabe:

> pass ls
Password Store
├── Github
└── codeberg

Spätestens wenn man Passwörter für mehrere Mailaccounts speichern will, verliert man schnell den Überblick. Aber auch dafür stellt pass eine Lösung bereit.

> pass insert Repos/github
Enter password for Repos/github: 
Retype password for Repos/github: 
[main 1eb0a57] Add given password for Repos/github to store.
 Author: Christian Schneider <fo@ob.ar>
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 Repos/github.gpg
❯ pass insert Repos/codeberg
Enter password for Repos/codeberg: 
Retype password for Repos/codeberg: 
[main c6c6fc1] Add given password for Repos/codeberg to store.
 Author: Christian Schneider <fo@ob.ar>
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 Repos/codeberg.gpg

Wenn man jetzt die gespeicherten Passwörter abruft, sieht es wie folgt aus:

❯ pass ls
Password Store
└── Repos
    ├── codeberg
    └── github

Wenn man aber mehrere Accounts bei GitHub hat, kann das wiederum auch unübersichtlich werden. Eine Alternative ist, das man seinen Benutzernamen angibt, aber den kann dann jeder sehen wenn man das Repo auch bei GitHub ablegt. Die bessere Option ist, das man Metadaten angibt. Dazu reicht ein pass edit Repos/github und es wird der Editor geöffnet; in der Zeile unter dem Passwort gibt man dann einfach email: arbeit@foo.bar ein. Jetzt hat man einen Anhalt wonach man suchen kann. Das geschieht dann mit folgendem Kommando

> pass grep arbeit
Repos/github:
email: arbeit@foo.bar

Passwörter wieder herstellen

Auch das ist kein Problem, da pass ja Git nutzt. Zuerst löschen wir jetzt mit pass rm Repos/codeberg und wir bekommen folgendes zu sehen:

pass rm Repos/codeberg
Are you sure you would like to delete Repos/codeberg? [y/N] y
removed '/home/dope/.password-store/Repos/codeberg.gpg'
[main 58a160c] Remove Repos/codeberg from store.
 Author: Christian Schneider <fo@ob.ar>
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 Repos/codeberg.gpg

Da wir jetzt Git zur Verfügung haben, können wir das auch nutzen. Die Anwendung ist exakt die gleiche wie bei Git selbst, nur das pass vorangestellt wird. Zuerst schauen wir im Log nach:

> pass git log
commit 58a160c9cfd6db5397c908418d3d8059afff9014 (HEAD -> main)
Author: Christian Schneider <fo@ob.ar>
Date:   Thu Aug 13 21:28:35 2026 +0200

     Remove Repos/codeberg from store.
[...]

Jetzt kommt git revert ins Spiel; dazu reicht ein pass git revert HEAD mit abschließendem Abspeichern und siehe da..

> pass ls
Password Store
└── Repos
    ├── codeberg
    └── github

pass in Verbindung mit einem remote Git-Repo

Wenn man die verschlüsselten Passwörter auf einem remote Git-Repo speichert, hat das den Vorteil, das man sie von anderen Hosts aus clonen und nutzen kann. Dazu werden die vorhandenen Git-Kommandos genutzt, denen man pass voranstellt.

> pass git remote add origin https://codeberg.org/Grumpycrash/pwd-store.git
> pass git push origin main

Wenn man das Repo jetzt von einem anderem Host aus geclont hat und sich die Passwörter ansehen will, bekommt man folgendes zu sehen

gpg: public key decryption failed: No secrect key
gpg: decryption failed: No secrect key

Um das zu ändern, muss man auf dem Host, auf dem die GPG-Keys erstellt wurden, diese exportieren; und zwar sowohl den public wie auch den secret Key.

# Anstelle der ID kann man auch die Emailadresse angeben
> gpg --output public.pgp --armor --export 646FA7404EEB7765743EBCD481F148F61E0A9CD0
# Jetzt noch den privaten Key exportieren
> gpg --output private.pgp --armor --export-secret-keys 646FA7404EEB7765743EBCD481F148F61E0A9CD0
# Jetzt wird man normalerweise aufgefordert, das Passwort für den Key einzugeben

Diese beiden Daten muss man nun auf den Host kopieren, von dem aus man pass nutzen will und diese dann importieren. Das geschieht mit folgenden Kommandos

> gpg --import private.pgp
# Auch hier kommt jetzt die Aufforderung zur Eingabe des Passworts.
> gpg --import public.pgp

Jetzt sollte man sich mit pass show Repos/codeberg die Passwörter anzeigen lassen können.

Trustlevel erhöhen

Will man auf dem neuen Host Passwörter hinzufügen bzw. ändern, muss man das Trustlevel anpassen. Das geschieht mit folgendem Kommando:

> gpg --edit-key 646FA7404EEB7765743EBCD481F148F61E0A9CD0
gpg (GnuPG) 2.4.9; Copyright (C) 2025 g10 Code GmbH
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Secret key is available.

sec  ed25519/81F148F61E0A9CD0
     created: 2026-08-12  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/2664790A0F8028CC
     created: 2026-08-12  expires: 2029-08-11  usage: E   
[ultimate] (1). Pass Word <fo@ob.ar>

gpg> gpg> trust
sec  ed25519/81F148F61E0A9CD0
     created: 2026-08-12  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/2664790A0F8028CC
     created: 2026-08-12  expires: 2029-08-11  usage: E   
[ultimate] (1). Pass Word <fo@ob.ar>

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

sec  ed25519/81F148F61E0A9CD0
     created: 2026-08-12  expires: never       usage: SC  
     trust: ultimate      validity: ultimate
ssb  cv25519/2664790A0F8028CC
     created: 2026-08-12  expires: 2029-08-11  usage: E   
[ultimate] (1). Pass Word <fo@ob.ar>

gpg> save
Key not changed so no update needed.

Nachwort

Die Passwörter, URLs und Emailadressen die ich hier verwendet habe, existieren nicht und werden somit auch nicht genutzt. Man kann sich also die Mühe sparen diese cracken zu wollen ;)
Sollte noch irgend etwas unklar sein oder sich Fehler eingeschlichen haben, dann kontaktiert mich einfach via Mail und ich kümmere mich darum.