README.md (24129B)
1 [](https://casuallymaintained.tech/) 2 3 # pashage 4 5 Yet Another Opinionated Re-engineering of the Unix Password Store 6 7 Core objectives: 8 9 - same interface and similar feature set 10 as [pass](https://www.passwordstore.org/) 11 - simplicity, understandability, and hackability, from using POSIX shell, 12 like [pash](https://github.com/dylanaraps/pash) 13 - [age](https://age-encryption.org) as encryption backend, 14 like [passage](https://github.com/FiloSottile/passage) 15 - validation using [shellcheck](https://www.shellcheck.net/) 16 and [shellspec tests](https://shellspec.info/) 17 18 Portability is not a core objective, but a nice side-effect of using 19 basic POSIX shell, and it is embraced when possible. 20 21 Security is not branded as a core objective, because the author does not 22 have the clout to declare anything secure, and you should probably not 23 trust random READMEs anyway. 24 However the simplicity should help you assess whether this password store 25 is a worthwhile trade-off for _your_ threat model. 26 27 For the reference, the author has views [similar to those of Filippo 28 Valsorda](https://words.filippo.io/dispatches/passage/) and considers 29 the password store shell script to be about as critical as the rest 30 of her computer, and relies mostly on age to provide secure encryption 31 at rest and on a [YubiKey](https://www.yubico.com/) to gatekeep decryption. 32 33 ## Licencing 34 35 This project was written from scratch, and every character of the script 36 was typed with my fingers. 37 However I looked deeply into pass, passage, and pash code bases. 38 I don't know whether that's enough to make it a derivative work covered 39 by the GPL, so to be on the safe side I'm using GPL v2+ too. 40 41 ## Differences with `pass` 42 43 ### Behavior Differences 44 45 - Not using a terminal does not imply `--force`, instead `pashage` asks for 46 a confirming `y` on a standard input line. 47 48 - When copying a secret to the clipboard, the script keeps running while 49 waiting for the automatic clearing. This provides a user-facing cue that 50 the secret may still be the clipboard and allows to clear the clipboard 51 earlier. 52 53 - The commands `copy`, `edit`, `insert`, `list`, `move`, and `show` 54 accept multiple arguments to operate on many secrets at once. 55 56 - The commands `copy` and `move` also operate on unencrypted files in the 57 password store. 58 59 - The `edit` command does not warn a about using `/tmp` rather than 60 `/dev/shm`, because the warning does not seem actionable and quickly 61 becomes ignored noise. 62 63 - The `edit` command uses `$VISUAL` rather than `$EDITOR` when it set and 64 the terminal is not dumb. 65 66 - The `find` command search-pattern is a regular expression rather than 67 a glob. 68 69 - The `find` command matches against the secret names without 70 extension (`.age` or `.gpg`). 71 72 - The `init` command is redesigned to accommodate `age` backend. 73 I didn't really understand the original `init` command, so I'm not sure 74 how different it is; but now it installs `.age-recipients` and re-encrypts. 75 76 - The `insert` command makes the user try again when entering mismatching 77 passwords. 78 79 ### New Features and Extensions 80 81 - The commands `copy` and `move` have new flags to control re-encryption 82 (always, never, ask for each file). 83 84 - The `find` and `list` commands have a new flag to output a 85 machine-readable list of entries (e.g. for completion or wrappers). 86 87 - The `generate` command has a new command-line argument to specify 88 explicitly the character set. 89 90 - The `generate` command optionally asks for confirmation before storing 91 the generated secret (e.g. for iterative attempts against stupid password 92 rules). 93 94 - The `generate` command optionally asks for extra lines to append after 95 the generated secret (e.g. for username, login page, or others comments). 96 97 - The `init` command has new flags to control re-encryption (never or 98 ask for each file). 99 100 - The new `gitconfig` command configures an existing store repository to 101 decrypt before `diff`. 102 103 - The new `random` command leverages password generation without touching 104 the password store. 105 106 - The new `reencrypt` command re-encrypts secrets in-place. 107 108 ## Roadmap 109 110 The following features are currently under consideration: 111 112 - v1.0.0: 113 + completion for various shells 114 + better logic for recursivity in re-encryption 115 - v1.1.0: 116 + partial display of secrets on standard output 117 + successive clipboard copy of several lines from a single decryption 118 (e.g. username then password) 119 - maybe/later: 120 + rewriting of git history to purge old cyphertexts 121 + OTP support 122 + extension support 123 124 ## Dependencies 125 126 Required dependencies: 127 128 - POSIX-compliant shell, including POSIX-compliant utilities `[`, `basename`, 129 `cat`, `cp`, `dd`, `diff`, `dirname`, `echo`, `find`, `grep`, `head`, `mkdir`, 130 `mktemp`, `mv`, `printf`, `rm`, `stty`, `tail`, `tr`, and `true`; 131 - [age](https://age-encryption.org/) encryption tool. 132 133 Optional dependencies: 134 135 - [feh](https://feh.finalrewind.org/) 136 to display QR-codes graphically 137 - [git](https://git-scm.com/) 138 to track storage revision and replicate it 139 - [GnuPG](https://gnupg.org/) 140 to display GnuPG-encrypted password-store secrets 141 - [GraphicsMagick](http://www.graphicsmagick.org/) 142 to display QR-codes graphically 143 - [ImageMagick](https://imagemagick.org/) 144 to display QR-codes graphically 145 - [openssl](https://www.openssl.org/) 146 to encode and decode base-64 when interacting with clipboard 147 - [qrencode](https://github.com/fukuchi/libqrencode) 148 to generate QR-codes 149 - [wl-clipboard](https://github.com/bugaevc/wl-clipboard) 150 to copy and paste on Wayland 151 - [xclip](https://github.com/astrand/xclip) 152 to copy and paste on X11 153 154 ## Manual 155 156 **pashage** is a _password manager_, which means it manages a database of 157 encrypted secrets, including encrypting externally-provided new secrets, 158 generating and encrypting random strings, and decrypting and displaying 159 stored secrets. 160 161 It aims to be simple and composable, but its reliance on Unix philosophy 162 and customs might make steep learning curve for users outside of this 163 culture. 164 165 It is used through a shell command, denoted as `pashage` in this document, 166 immediately followed by a subcommand and its arguments. When no subcommand 167 is specified, _list_ or _show_ is implicitly assumed. 168 169 The database is optionally versioned using [git](https://git-scm.com/) 170 to help with history audit and synchronization. It should be noted that 171 this prevents re-encryption from erasing old cyphertext, leaving the secret 172 vulnerable to compromised encryption keys. 173 174 The cryptography is done by [age](https://age-encryption.org/) external 175 command. It decrypts using the _identity_ file given in the environment, 176 and crypts using a list of _recipients_ per subfolder, defaulting to the 177 parent _recipient_ list or the _identity_. 178 179 ## Command Reference 180 181 Here is an alphabetical list of all subcommands and aliases: 182 183 - `--help`: alias for _help_ 184 - `--version`: alias for _version_ 185 - `-h`: alias for _help_ 186 - `copy` 187 - `cp`: alias for _copy_ 188 - `delete` 189 - `edit` 190 - `find` 191 - `gen`: alias for _generate_ 192 - `generate` 193 - `git` 194 - `gitconfig` 195 - `grep` 196 - `help` 197 - `init` 198 - `insert` 199 - `list` 200 - `ls`: alias for _list_ 201 - `move` 202 - `mv`: alias for _move_ 203 - `random` 204 - `re-encrypt`: alias for _reencrypt_ 205 - `reencrypt` 206 - `remove`: alias for _delete_ 207 - `rm`: alias for _delete_ 208 - `show` 209 - `version` 210 211 ### copy 212 213 Syntax: 214 215 ``` 216 pashage copy [--reencrypt,-e | --interactive,-i | --keep,-k ] 217 [--force,-f] old-path ... new-path 218 ``` 219 220 This subcommand copies secrets and recursively copies subfolders, 221 using the same positional argument scheme as `cp(1)`. 222 By default it asks before overwriting an existing secret and it re-encrypts 223 the secret when the destination has a different _recipient_ list. 224 225 Flags: 226 - `-e` or `--reencrypt`: always re-encrypt secrets 227 - `-f` or `--force`: overwrite existing secrets without asking 228 - `-i` or `--interactive`: asks whether to re-encrypt or not for each secret 229 - `-k` or `--keep`: never re-encrypt secrets 230 231 Environment: 232 - `PASHAGE_AGE`: external command to use instead of `age` 233 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 234 - `PASHAGE_IDENTITIES_FILE`: _identity_ file to use instead of 235 `~/.passage/identities` 236 - `PASSAGE_AGE`: external command to use instead of `age` when 237 `PASHAGE_AGE` is unset 238 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 239 when `PASHAGE_DIR` is unset 240 - `PASSAGE_IDENTITIES_FILE`: _identity_ file to use instead of 241 `~/.passage/identities` when `PASHAGE_IDENTITIES_FILE` is unset 242 - `PASSWORD_STORE_DIR`: database directory to use instead of 243 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 244 245 ### delete 246 247 Syntax: 248 249 ``` 250 pashage delete [--recursive,-r] [--force,-f] pass-name ... 251 ``` 252 253 This subcommand deletes secrets from the database. By default it skips 254 subfolders and asks for confirmation for each secret. 255 256 Flags: 257 - `-f` or `--force`: delete without asking for confirmation 258 - `-r` or `--recursive`: recursively delete all secrets in given subfolders 259 260 Environment: 261 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 262 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 263 when `PASHAGE_DIR` is unset 264 - `PASSWORD_STORE_DIR`: database directory to use instead of 265 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 266 267 ### edit 268 269 Syntax: 270 271 ``` 272 pashage edit pass-name ... 273 ``` 274 275 This subcommand starts an interactive editor to update the secrets. 276 277 Environment: 278 - `EDITOR`: editor command to use instead of `vi` when `VISUAL` is not set 279 - `PASHAGE_AGE`: external command to use instead of `age` 280 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 281 - `PASHAGE_IDENTITIES_FILE`: _identity_ file to use instead of 282 `~/.passage/identities` 283 - `PASSAGE_AGE`: external command to use instead of `age` when 284 `PASHAGE_AGE` is unset 285 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 286 when `PASHAGE_DIR` is unset 287 - `PASSAGE_IDENTITIES_FILE`: _identity_ file to use instead of 288 `~/.passage/identities` when `PASHAGE_IDENTITIES_FILE` is unset 289 - `PASSWORD_STORE_DIR`: database directory to use instead of 290 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 291 - `TMPDIR`: temporary directory for the decrypted file to use instead of 292 `/tmp` when `/dev/shm` is not available 293 - `VISUAL`: editor command to use instead of `vi` 294 295 ### find 296 297 Syntax: 298 299 ``` 300 pashage find [--raw,-r] [GREP_OPTIONS] regex 301 ``` 302 303 This subcommand lists as a tree the secrets whose name match the given 304 regular expression, using the corresponding `grep(1)` options. 305 306 Flags: 307 - `-r` or `--raw`: display the results as a raw list of secrets, 308 rather than a tree 309 310 Environment: 311 - `CLICOLOR`: when set to a non-empty value, use ANSI escape sequences to 312 color the output 313 - `LC_CTYPE`: when it contains `UTF`, the tree is displayed using Unicode 314 graphic characters instead of ASCII 315 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 316 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 317 when `PASHAGE_DIR` is unset 318 - `PASSWORD_STORE_DIR`: database directory to use instead of 319 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 320 321 ### generate 322 323 Syntax: 324 325 ``` 326 pashage generate [--no-symbols,-n] [--clip,-c | --qrcode,-q] 327 [--in-place,-i | --force,-f] [--multiline,-m] 328 [--try,-t] pass-name [pass-length [character-set]] 329 ``` 330 331 This subcommand generates a new secret from `/dev/urandom`, stores it in 332 the database, and by default displays it on the standard output and asks 333 for confirmation before overwriting an existing secret. 334 335 Flags: 336 - `-c` or `--clip`: paste the secret into the clipboard instead of using 337 the standard output 338 - `-f` or `--force`: replace existing secrets without asking 339 - `-i` or `--in-place`: when the secret already exists, replace only its 340 first line and re-use the following lines 341 - `-m` or `--multiline`: read lines from standard input to append after the 342 generated data into the secret file 343 - `-n` or `--no-symbols`: generate a secret using only alphanumeric 344 characters 345 - `-q` or `--qrcode`: display the secret as a QR-code instead of using the 346 standard output 347 - `-t` or `--try`: display the secret and ask for confirmation before 348 storing it into the database 349 350 Environment: 351 - `CLICOLOR`: when set to a non-empty value, use ANSI escape sequences to 352 color the output 353 - `PASHAGE_AGE`: external command to use instead of `age` 354 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 355 - `PASHAGE_IDENTITIES_FILE`: _identity_ file to use instead of 356 `~/.passage/identities` 357 - `PASSAGE_AGE`: external command to use instead of `age` when 358 `PASHAGE_AGE` is unset 359 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 360 when `PASHAGE_DIR` is unset 361 - `PASSAGE_IDENTITIES_FILE`: _identity_ file to use instead of 362 `~/.passage/identities` when `PASHAGE_IDENTITIES_FILE` is unset 363 - `PASSWORD_STORE_CHARACTER_SET_NO_SYMBOLS`: default character set to use 364 with `tr(1)` when `-n` is specified, instead of `[:alnum:]` 365 - `PASSWORD_STORE_CHARACTER_SET`: default character set to use with `tr(1)` 366 when `-n` is not specified, instead of `[:punct:][:alnum:]` 367 - `PASSWORD_STORE_CLIP_TIME`: number of second before clearing the 368 clipboard when `-c` is used, instead of 45 369 - `PASSWORD_STORE_DIR`: database directory to use instead of 370 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 371 - `PASSWORD_STORE_GENERATED_LENGTH`: number of characters in the generated 372 secret when not explicitly given, instead of 25 373 - `PASSWORD_STORE_X_SELECTION`: selection to use when `-c` and `xclip` are 374 used, instead of `clipboard` 375 376 ### git 377 378 Syntax: 379 380 ``` 381 pashage git git-command-args ... 382 ``` 383 384 This subcommand invokes `git` in the database repository. 385 Only `git init` and `git clone` are accepted when there is no underlying 386 repository. 387 388 Environment: 389 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 390 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 391 when `PASHAGE_DIR` is unset 392 - `PASSWORD_STORE_DIR`: database directory to use instead of 393 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 394 395 ### gitconfig 396 397 Syntax: 398 399 ``` 400 pashage gitconfig 401 ``` 402 403 This subcommand configures the underlying repository to automatically 404 decrypt secrets to display differences. 405 406 Environment: 407 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 408 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 409 when `PASHAGE_DIR` is unset 410 - `PASSWORD_STORE_DIR`: database directory to use instead of 411 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 412 413 ### grep 414 415 Syntax: 416 417 ``` 418 pashage grep [GREP_OPTIONS] search-regex 419 ``` 420 421 This subcommand successively decrypts all the secrets in the store and 422 filter them through `grep(1)` using the given options, and outputs all the 423 matching lines and the corresponding secret. 424 425 Environment: 426 - `CLICOLOR`: when set to a non-empty value, use ANSI escape sequences to 427 color the output 428 - `PASHAGE_AGE`: external command to use instead of `age` 429 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 430 - `PASHAGE_IDENTITIES_FILE`: _identity_ file to use instead of 431 `~/.passage/identities` 432 - `PASSAGE_AGE`: external command to use instead of `age` when 433 `PASHAGE_AGE` is unset 434 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 435 when `PASHAGE_DIR` is unset 436 - `PASSAGE_IDENTITIES_FILE`: _identity_ file to use instead of 437 `~/.passage/identities` when `PASHAGE_IDENTITIES_FILE` is unset 438 - `PASSWORD_STORE_DIR`: database directory to use instead of 439 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 440 441 ### help 442 443 Syntax: 444 445 ``` 446 pashage help 447 ``` 448 449 This subcommand displays on the standard output the version and help text, 450 including all subcommands and flags and a brief description. 451 452 This subcommand is not affected by the environment. 453 454 ### init 455 456 Syntax: 457 458 ``` 459 pashage init [--interactive,-i | --keep,-k ] 460 [--path=subfolder,-p subfolder] age-recipient ... 461 ``` 462 463 This subcommand initializes an age _recipient_ list, by default of the root 464 of the password store, and re-encrypts all the affected secrets. 465 When the _recipient_ list is a single empty string, the _recipient_ list is 466 instead removed, falling back to a parent _recipient_ list or ultimately to 467 the age _identity_. 468 469 Flags: 470 - `-i` or `--interactive`: ask for each secret whether to re-encrypt it 471 or not 472 - `-k` or `--keep`: do not re-encrypt any secret 473 - `-p` or `--path`: operate on the _recipient_ list in the given subfolder 474 instead of the root of the password store 475 476 Environment: 477 - `PASHAGE_AGE`: external command to use instead of `age` 478 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 479 - `PASHAGE_IDENTITIES_FILE`: _identity_ file to use instead of 480 `~/.passage/identities` 481 - `PASSAGE_AGE`: external command to use instead of `age` when 482 `PASHAGE_AGE` is unset 483 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 484 when `PASHAGE_DIR` is unset 485 - `PASSAGE_IDENTITIES_FILE`: _identity_ file to use instead of 486 `~/.passage/identities` when `PASHAGE_IDENTITIES_FILE` is unset 487 - `PASSWORD_STORE_DIR`: database directory to use instead of 488 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 489 490 ### insert 491 492 Syntax: 493 494 ``` 495 pashage insert [--echo,-e | --multiline,-m] [--force,-f] pass-name ... 496 ``` 497 498 This subcommand adds new secrets in the database, using the provided data 499 from the standard input. By default asks before overwriting an existing 500 secret, and it reads a single secret line after turning off the console 501 echo, and reads it a second time for confirmation. 502 503 Flags: 504 - `-e` or `--echo`: read a single line once without manipulating the 505 standard input 506 - `-m` or `--multiline`: read an arbitrary amount of lines from the standard 507 input, without trying to manipulate the console, until the end of input 508 or a blank line is entered 509 - `-f` or `--force`: overwrite an existing secret without asking 510 511 Environment: 512 - `PASHAGE_AGE`: external command to use instead of `age` 513 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 514 - `PASHAGE_IDENTITIES_FILE`: _identity_ file to use instead of 515 `~/.passage/identities` 516 - `PASSAGE_AGE`: external command to use instead of `age` when 517 `PASHAGE_AGE` is unset 518 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 519 when `PASHAGE_DIR` is unset 520 - `PASSAGE_IDENTITIES_FILE`: _identity_ file to use instead of 521 `~/.passage/identities` when `PASHAGE_IDENTITIES_FILE` is unset 522 - `PASSWORD_STORE_DIR`: database directory to use instead of 523 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 524 525 ### list 526 527 Syntax: 528 529 ``` 530 pashage [list] [--raw,-r] [subfolder ...] 531 ``` 532 533 This subcommand displays the given subfolders as a tree or a raw list, 534 or the whole store when no subfolder is specified. 535 536 Note that when a secret is given instead of a subfolder, the _show_ command 537 will be used instead, without any warning or error. 538 539 Flags: 540 - `-r` or `--raw`: display the results as a raw list of secrets 541 542 Environment: 543 - `CLICOLOR`: when set to a non-empty value, use ANSI escape sequences to 544 color the output 545 - `LC_CTYPE`: when it contains `UTF`, the tree is displayed using Unicode 546 graphic characters instead of ASCII 547 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 548 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 549 when `PASHAGE_DIR` is unset 550 - `PASSWORD_STORE_DIR`: database directory to use instead of 551 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 552 553 ### move 554 555 Syntax: 556 557 ``` 558 pashage move [--reencrypt,-e | --interactive,-i | --keep,-k ] 559 [--force,-f] old-path ... new-path 560 ``` 561 562 This subcommand moves or renames secrets and subfolders recursively, 563 using the same positional argument scheme as `mv(1)`. 564 By default it asks before overwriting an existing secret and it re-encrypts 565 the secret when the destination has a different _recipient_ list. 566 567 Flags: 568 - `-e` or `--reencrypt`: always re-encrypt secrets 569 - `-f` or `--force`: overwrite existing secrets without asking 570 - `-i` or `--interactive`: asks whether to re-encrypt or not for each secret 571 - `-k` or `--keep`: never re-encrypt secrets 572 573 Environment: 574 - `PASHAGE_AGE`: external command to use instead of `age` 575 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 576 - `PASHAGE_IDENTITIES_FILE`: _identity_ file to use instead of 577 `~/.passage/identities` 578 - `PASSAGE_AGE`: external command to use instead of `age` when 579 `PASHAGE_AGE` is unset 580 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 581 when `PASHAGE_DIR` is unset 582 - `PASSAGE_IDENTITIES_FILE`: _identity_ file to use instead of 583 `~/.passage/identities` when `PASHAGE_IDENTITIES_FILE` is unset 584 - `PASSWORD_STORE_DIR`: database directory to use instead of 585 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 586 587 ### random 588 589 Syntax: 590 591 ``` 592 pashage random [pass-length [character-set]] 593 ``` 594 595 This subcommand generates a new secret, like the _generate_ subcommand, 596 then directly displays on the standard output without storing it. 597 598 Environment: 599 - `PASSWORD_STORE_CHARACTER_SET`: character set to use with `tr(1)` when 600 `character-set` is not specified, instead of `[:punct:][:alnum:]` 601 - `PASSWORD_STORE_GENERATED_LENGTH`: number of characters in the generated 602 secret when not explicitly given, instead of 25 603 604 ### reencrypt 605 606 Syntax: 607 608 ``` 609 pashage reencrypt [--deep,-d] [--interactive,-i] pass-name|subfolder ... 610 ``` 611 612 This subcommand re-encrypts in place the given secrets, and all the secrets 613 recursively in the given subfolders. 614 615 Flags: 616 - `-d` or `--deep`: re-encrypt subfolders with their own recipient list 617 - `-i` or `--interactive`: asks whether to re-encrypt or not for each secret 618 619 Environment: 620 - `PASHAGE_AGE`: external command to use instead of `age` 621 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 622 - `PASHAGE_IDENTITIES_FILE`: _identity_ file to use instead of 623 `~/.passage/identities` 624 - `PASSAGE_AGE`: external command to use instead of `age` when 625 `PASHAGE_AGE` is unset 626 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 627 when `PASHAGE_DIR` is unset 628 - `PASSAGE_IDENTITIES_FILE`: _identity_ file to use instead of 629 `~/.passage/identities` when `PASHAGE_IDENTITIES_FILE` is unset 630 - `PASSWORD_STORE_DIR`: database directory to use instead of 631 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 632 633 ### show 634 635 Syntax: 636 637 ``` 638 pashage [show] [--clip[=line-number],-c[line-number] | 639 --qrcode[=line-number],-q[line-number]] pass-name ... 640 ``` 641 642 This subcommand decrypts the given secrets and by default displays the 643 whole text on the standard output. 644 645 Note that when a subfolder is given instead of a secret, the _list_ command 646 will be used instead, without any warning or error. 647 648 Flags: 649 - `-c` or `--clip`: paste the given line (by default the first line) of the 650 secret into the clipboard instead of using the standard output 651 - `-q` or `--qrcode`: display the given line (by default the first line) of 652 the secret as a QR-code instead of using the standard output 653 654 Environment: 655 - `PASHAGE_AGE`: external command to use instead of `age` 656 - `PASHAGE_DIR`: database directory to use instead of `~/.passage/store` 657 - `PASHAGE_IDENTITIES_FILE`: _identity_ file to use instead of 658 `~/.passage/identities` 659 - `PASSAGE_AGE`: external command to use instead of `age` when 660 `PASHAGE_AGE` is unset 661 - `PASSAGE_DIR`: database directory to use instead of `~/.passage/store` 662 when `PASHAGE_DIR` is unset 663 - `PASSAGE_IDENTITIES_FILE`: _identity_ file to use instead of 664 `~/.passage/identities` when `PASHAGE_IDENTITIES_FILE` is unset 665 - `PASSWORD_STORE_DIR`: database directory to use instead of 666 `~/.passage/store` when both `PASHAGE_DIR` and `PASSAGE_DIR` are unset 667 668 ### version 669 670 Syntax: 671 672 ``` 673 pashage version 674 ``` 675 676 This subcommand displays on the standard output the version and author 677 list. 678 679 This subcommand is not affected by the environment.