$ git clone -q https://github.com/biox/pa.git
$ cd pa/contrib
$ ls -1 -p
pa-bemenu
pa-completion.bash
pa-completion.fish
pa-dmenu
pa-fuzzel
pa-pass
pa-rekey
pa-rofi
pa-ssg
pa-urn
pa-wmenu
$ nl -b a -s ' ' -w 3 pa-urn
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
#!/bin/sh

usage() {
    printf %s "\
  pa-urn

  commands:
    [c]lose [file] - Archive password store into file.
    [o]pen  [file] - Extract file into password store.
"
}

create_tar() {
    if command -v pax >/dev/null 2>&1; then
        pax -x ustar -w "./$1"
    else
        tar c "./$1"
    fi
}

extract_tar() {
    if command -v pax >/dev/null 2>&1; then
        pax -r
    else
        tar x
    fi
}

die() {
    printf '%s: %s.\n' "$(basename "$0")" "$1" >&2
    exit 1
}

set -o pipefail

age=$(command -v age || command -v rage) ||
    die "age not found, install per https://age-encryption.org"

basedir=${XDG_DATA_HOME:=$HOME/.local/share}/pa
: "${PA_DIR:=$basedir/passwords}"

dir=$(realpath "$PA_DIR") ||
    die "couldn't get path to password directory"

name=$(basename "$dir")
if [ "$2" ]; then
    urn=$(realpath -- "$2") ||
        die "couldn't get path to file '$2'"
else
    urn=$(pwd)/$name.tar.age ||
        die "couldn't get working directory"
fi

cd "$(dirname "$dir")" ||
    die "couldn't change to parent of password directory"

case $1 in
c*)
    { create_tar "$name" | $age -R "$basedir/recipients" -o "$urn"; } &&
        printf '%s\n' "store has been archived into $urn"
    ;;
o*)
    [ -f "$urn" ] ||
        die "file '$urn' doesn't exist"

    { $age --decrypt -i "$basedir/identities" "$urn" | extract_tar; } &&
        printf '%s\n' "file has been extracted into $PA_DIR"
    ;;
*) usage ;;
esac