pashage

Yet Another Opinionated Re-engineering of the Unix Password Store
git clone https://git.instinctive.eu/pashage.git
Log | Files | Refs | README | LICENSE

pashage.1 (11575B)


      1 .Dd November 2, 2025
      2 .Dt PASHAGE 1
      3 .Os
      4 .Sh NAME
      5 .Nm pashage
      6 .Nd simple and portable password store for the Unix shell
      7 .Sh SYNOPSIS
      8 .Nm
      9 .Op Ar COMMAND
     10 .Op Ar OPTIONS
     11 .Op Ar ARGS
     12 .Sh DESCRIPTION
     13 .Nm
     14 is a
     15 .Em password manager ,
     16 which means it manages a database of encrypted secrets, including encrypting
     17 externally-provided new secrets, generating and encrypting random strings, and
     18 decrypting and displaying stored secrets.
     19 .Pp
     20 It aims to be simple and composable, but its reliance on Unix philosophy
     21 and customs might make steep learning curve for users outside of this
     22 culture.
     23 .Pp
     24 The
     25 .Nm
     26 utility provides commands for query and management of the password store.
     27 When no command is specified,
     28 .Cm list
     29 or
     30 .Cm show
     31 is implicitly assumed.
     32 .Pp
     33 The database is optionally versioned using
     34 .Xr git 1
     35 to help with history audit and synchronization.
     36 It should be noted that this prevents re-encryption from erasing old
     37 cyphertext, leaving the secret vulnerable to compromised encryption keys.
     38 .Pp
     39 The cryptography is done by
     40 .Xr age 1
     41 external command.
     42 It decrypts using the
     43 .Em identity
     44 file given in the environment, and crypts using a list of
     45 .Em recipients
     46 per subfolder, defaulting to the parent
     47 .Em recipient
     48 list or the
     49 .Em identity .
     50 .Sh COMMANDS
     51 .Ss copy
     52 .Nm
     53 .Cm copy
     54 .Op Fl e,--reencrypt | Fl i,--interactive | Fl k,--keep
     55 .Op Fl f,--force
     56 .Ar old-path ... new-path
     57 .Pp
     58 This subcommand copies secrets and recursively copies subfolders,
     59 using the same positional argument scheme as
     60 .Xr cp 1 .
     61 By default it asks before overwriting an existing secret and it re-encrypts
     62 the secret when the destination has a different
     63 .Em recipient
     64 list.
     65 .Pp
     66 The options are as follows:
     67 .Bl -tag -compact -width \-i,--interactive
     68 .It Fl e,--reencrypt
     69 always re-encrypt secrets
     70 .It Fl f,--force
     71 overwrite existing secrets without asking
     72 .It Fl i,--interactive
     73 asks whether to re-encrypt or not for each secret
     74 .It Fl k,--keep
     75 never re-encrypt secrets
     76 .El
     77 .Ss delete
     78 .Nm
     79 .Cm delete
     80 .Op Fl r,--recursive
     81 .Op Fl f,--force
     82 .Ar pass-name
     83 .Ar ...
     84 .Pp
     85 This subcommand deletes secrets from the database.
     86 By default it skips subfolders and asks for confirmation for each secret.
     87 .Pp
     88 The options are as follows:
     89 .Bl -tag -compact -width \-r,--recursive
     90 .It Fl f,--force
     91 delete without asking for confirmation
     92 .It Fl r,--recursive
     93 recursively delete all secrets in given subfolders
     94 .El
     95 .Ss edit
     96 .Nm
     97 .Cm edit
     98 .Ar pass-name
     99 .Ar ...
    100 .Pp
    101 This subcommand starts an interactive editor to update the secrets.
    102 .Ss find
    103 .Nm
    104 .Cm find
    105 .Op Fl r,--raw
    106 .Op Ar GREP_OPTIONS
    107 .Ar regex
    108 .Pp
    109 This subcommand lists as a tree the secrets whose name match the given
    110 regular expression, using the corresponding
    111 .Xr grep 1
    112 options.
    113 .Pp
    114 The options are as follows:
    115 .Bl -tag -compact -width \-i,--interactive
    116 .It Fl r,--raw
    117 display the results as a raw list of secrets, rather than a tree
    118 .El
    119 .Ss generate
    120 .Nm
    121 .Cm generate
    122 .Op Fl n,--no-symbols
    123 .Op Fl c,--clip | Fl q,--qrcode
    124 .Op Fl i,--in-place | Fl f,--force
    125 .Op Fl m,--multiline
    126 .Op Fl t,--try
    127 .Ar pass-name
    128 .Op Ar pass-length Op Ar character-set
    129 .Pp
    130 This subcommand generates a new secret from
    131 .Pa /dev/urandom ,
    132 stores it in the database, and by default displays it on the standard output
    133 and asks
    134 for confirmation before overwriting an existing secret.
    135 .Pp
    136 The options are as follows:
    137 .Bl -tag -compact -width \-n,--no-symbols
    138 .It Fl c,--clip
    139 paste the secret into the clipboard instead of using the standard output
    140 .It Fl f,--force
    141 replace existing secrets without asking
    142 .It Fl i,--in-place
    143 when the secret already exists, replace only its first line and re-use the
    144 following lines
    145 .It Fl m,--multiline
    146 read lines from standard input to append after the generated data into the secret
    147 file
    148 .It Fl n,--no-symbols
    149 generate a secret using only alphanumeric characters
    150 .It Fl q,--qrcode
    151 display the secret as a QR-code instead of using the standard output
    152 .It Fl t,--try
    153 display the secret and ask for confirmation before storing it into the database
    154 .El
    155 .Ss git
    156 .Nm
    157 .Cm git git-command-args ...
    158 .Pp
    159 This subcommand invokes
    160 .Xr git 1
    161 in the database repository.
    162 Only
    163 .Cm git init
    164 and
    165 .Cm git clone
    166 are accepted when there is no underlying repository.
    167 .Ss gitconfig
    168 .Nm
    169 .Cm gitconfig
    170 .Pp
    171 This subcommand configures the underlying repository to automatically
    172 decrypt secrets to display differences.
    173 .Ss grep
    174 .Nm
    175 .Cm grep
    176 .Op Ar GREP_OPTIONS
    177 .Ar search-regex
    178 .Pp
    179 This subcommand successively decrypts all the secrets in the store and
    180 filter them through
    181 .Xr grep 1
    182 using the given options, and outputs all the matching lines and the
    183 corresponding secret.
    184 .Ss help
    185 .Nm
    186 .Cm help
    187 .Pp
    188 This subcommand displays on the standard output the version and help text,
    189 including all subcommands and flags and a brief description.
    190 .Ss init
    191 .Nm
    192 .Cm init
    193 .Op Fl i,--interactive | Fl k,--keep
    194 .Op Fl p,--path Ar subfolder
    195 .Ar age-recipient
    196 .Ar ...
    197 .Pp
    198 This subcommand initializes an age
    199 .Em recipient
    200 list, by default of the root of the password store, and re-encrypts all the
    201 affected secrets.
    202 When the
    203 .Ar age-recipient
    204 list is a single empty string, the
    205 .Em recipient
    206 list is instead removed, falling back to a parent
    207 .Em recipient
    208 list or ultimately to the age
    209 .Em identity .
    210 .Pp
    211 The options are as follows:
    212 .Bl -tag -compact -width \-i,--interactive
    213 .It Fl i,--interactive
    214 ask for each secret whether to re-encrypt it or not
    215 .It Fl k,--keep
    216 do not re-encrypt any secret
    217 .It Fl p,--path
    218 operate on the
    219 .Em recipient
    220 list in the given subfolder instead of the root of the password store
    221 .El
    222 .Ss insert
    223 .Nm
    224 .Cm insert
    225 .Op Fl e,--echo | Fl m,--multiline
    226 .Op Fl f,--force
    227 .Ar pass-name
    228 .Ar ...
    229 .Pp
    230 This subcommand adds new secrets in the database, using the provided data
    231 from the standard input.
    232 By default asks before overwriting an existing secret, and it reads a single
    233 secret line after turning off the console echo, and reads it a second time for
    234 confirmation.
    235 .Pp
    236 The options are as follows:
    237 .Bl -tag -compact -width \-m,--multiline
    238 .It Fl e,--echo
    239 read a single line once without manipulating the standard input
    240 .It Fl m,--multiline
    241 read an arbitrary amount of lines from the standard input, without trying to
    242 manipulate the console, until the end of input or a blank line is entered
    243 .It Fl f,--force
    244 overwrite an existing secret without asking
    245 .El
    246 .Ss list
    247 .Nm
    248 .Op Cm list
    249 .Op r,--raw
    250 .Op Ar subfolder ...
    251 .Pp
    252 This subcommand displays the given subfolders as a tree or as a raw list, or
    253 the whole store when no subfolder is specified.
    254 .Pp
    255 Note that when a secret is given instead of a subfolder, the
    256 .Cm show
    257 command will be used instead, without any warning or error.
    258 .Pp
    259 The options are as follows:
    260 .Bl -tag -compact -width \-i,--interactive
    261 .It Fl r,--raw
    262 display the results as a raw list of secrets.
    263 .El
    264 .Ss move
    265 .Nm
    266 .Cm move
    267 .Op Fl e,--reencrypt | Fl i,--interactive | Fl k,--keep
    268 .Op Fl f,--force
    269 .Ar old-path ... new-path
    270 .Pp
    271 This subcommand moves or renames secrets and subfolders recursively,
    272 using the same positional argument scheme as
    273 .Xr mv 1 .
    274 By default it asks before overwriting an existing secret and it re-encrypts
    275 the secret when the destination has a different
    276 .Em recipient
    277 list.
    278 .Pp
    279 The options are as follows:
    280 .Bl -tag -compact -width \-i,--interactive
    281 .It Fl e,--reencrypt
    282 always re-encrypt secrets
    283 .It Fl f,--force
    284 overwrite existing secrets without asking
    285 .It Fl i,--interactive
    286 asks whether to re-encrypt or not for each secret
    287 .It Fl k,--keep
    288 never re-encrypt secrets
    289 .El
    290 .Ss random
    291 .Nm
    292 .Cm random
    293 .Op Ar pass-length Op Ar character-set
    294 .Pp
    295 This subcommand generates a new secret, like the
    296 .Cm generate
    297 subcommand, then directly displays on the standard output without storing it.
    298 .Ss reencrypt
    299 .Nm
    300 .Cm reencrypt
    301 .Op Fl i,--interactive
    302 .Ar pass-name|subfolder
    303 .Ar ...
    304 .Pp
    305 This subcommand re-encrypts in place the given secrets, and all the secrets
    306 recursively in the given subfolders.
    307 .Pp
    308 The options are as follows:
    309 .Bl -tag -compact -width \-i,--interactive
    310 .It Fl i,--interactive
    311 asks whether to re-encrypt or not for each secret
    312 .El
    313 .Ss show
    314 .Nm
    315 .Op Cm show
    316 .Oo
    317 .Fl c,--clip Op Ar line-number |
    318 .Fl q,--qrcode Ar line-number
    319 .Oc
    320 .Ar pass-name
    321 .Ar ...
    322 .Pp
    323 This subcommand decrypts the given secrets and by default displays the
    324 whole text on the standard output.
    325 .Pp
    326 Note that when a subfolder is given instead of a secret, the
    327 .Cm list
    328 command will be used instead, without any warning or error.
    329 .Pp
    330 The options are as follows:
    331 .Bl -tag -compact -width \-q,--qrcode
    332 .It Fl c,--clip
    333 paste the given line (by default the first line) of the secret into the
    334 clipboard instead of using the standard output
    335 .It Fl q,--qrcode
    336 display the given line (by default the first line) of the secret as a QR-code
    337 instead of using the standard output
    338 .El
    339 .Ss version
    340 .Nm
    341 .Cm version
    342 .Pp
    343 This subcommand displays on the standard output the version and author
    344 list.
    345 .Sh ENVIRONMENT
    346 The following environment variables affect the execution of
    347 .Nm :
    348 .\" The largest symbol is actually PASSWORD_STORE_CHARACTER_SET_NO_SYMBOLS
    349 .\" but that compresses the second columns way too much.
    350 .Bl -tag -width XXXXXXXX
    351 .It Ev CLICOLOR
    352 when set to a non-empty value, use ANSI escape sequences to color the output
    353 .It Ev EDITOR
    354 editor command to use instead of
    355 .Xr vi 1
    356 when
    357 .Ev VISUAL
    358 is not set
    359 .It Ev LC_CTYPE
    360 when it contains
    361 .Qq UTF ,
    362 the tree is displayed using Unicode graphic characters instead of ASCII
    363 .It Ev PASHAGE_AGE
    364 external command to use instead of
    365 .Xr age 1
    366 .It Ev PASHAGE_DIR
    367 database directory to use instead of
    368 .Pa ~/.passage/store
    369 .It Ev PASHAGE_IDENTITIES_FILE
    370 .Em identity
    371 file to use instead of
    372 .Pa ~/.passage/identities
    373 .It Ev PASSAGE_AGE
    374 external command to use instead of
    375 .Xr age 1
    376 when
    377 .Ev PASHAGE_AGE
    378 is unset
    379 .It Ev PASSAGE_DIR
    380 database directory to use instead of
    381 .Pa ~/.passage/store
    382 when
    383 .Ev PASHAGE_DIR
    384 is unset
    385 .It Ev PASSAGE_IDENTITIES_FILE
    386 .Em identity
    387 file to use instead of
    388 .Pa ~/.passage/identities
    389 when
    390 .Ev PASHAGE_IDENTITIES_FILE
    391 is unset
    392 .It Ev PASSWORD_STORE_CHARACTER_SET_NO_SYMBOLS
    393 default character set to use with
    394 .Xr tr 1
    395 when
    396 .Fl n
    397 is specified, instead of
    398 .Qq [:alnum:]
    399 .It Ev PASSWORD_STORE_CHARACTER_SET
    400 character set to use with
    401 .Xr tr 1
    402 when no character set requirement is specified for the
    403 .Cm generate
    404 or
    405 .Cm random
    406 commands, instead of
    407 .Qq [:punct:][:alnum:]
    408 .It Ev PASSWORD_STORE_CLIP_TIME
    409 number of second before clearing the clipboard when
    410 .Fl c
    411 is used, instead of 45
    412 .It Ev PASSWORD_STORE_DIR
    413 database directory to use instead of
    414 .Pa ~/.passage/store
    415 when both
    416 .Ev PASHAGE_DIR
    417 and
    418 .Ev PASSAGE_DIR
    419 are unset
    420 .It Ev PASSWORD_STORE_GENERATED_LENGTH
    421 number of characters in the generated secret when not explicitly given,
    422 instead of 25
    423 .It Ev PASSWORD_STORE_X_SELECTION
    424 selection to use when
    425 .Fl c
    426 and
    427 .Xr xclip 1
    428 are used, instead of
    429 .Qq clipboard
    430 .It Ev TMPDIR
    431 temporary directory for the decrypted file to use instead of
    432 .Pa /tmp
    433 when
    434 .Pa /dev/shm
    435 is not available
    436 .It Ev VISUAL
    437 editor command to use instead of
    438 .Xr vi 1
    439 .El
    440 .Sh FILES
    441 Most paths used by
    442 .Nm
    443 can be configured through environment variables.
    444 Here are the defaults:
    445 .Bl -tag -width XXXXXXXX
    446 .It Pa ~/.passage/identities
    447 .Xr age 1
    448 .Em identities
    449 to use for decryption
    450 .It Pa ~/.passage/store/
    451 Root directory of the password store
    452 .It Pa /dev/shm/
    453 Temporary directory
    454 .Pq when available
    455 .It Pa /dev/urandom
    456 Source of entropy
    457 .It Pa /tmp
    458 Temporary directory
    459 .Po
    460 when
    461 .Pa /dev/sdm
    462 is not available
    463 .Pc
    464 .El
    465 .Sh SEE ALSO
    466 .Xr age 1 ,
    467 .Xr git 1 ,
    468 .Xr tr 1 ,
    469 .Xr vi 1 ,
    470 .Xr xclip 1 .
    471 .Sh AUTHORS
    472 .Nm
    473 was written by
    474 .An Natasha Kerensikova ,
    475 based on earlier work by:
    476 .An Jason A. Donenfeld
    477 .Pq password-store
    478 .An Filippo Valsorda
    479 .Pq passage
    480 .An Dylan Araps
    481 .Pq pash