Skip to content

privage is a terminal based password manager and general file encryption tool

License

Notifications You must be signed in to change notification settings

revelaction/privage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

381 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

kind

Go Reference Test Integration Test golangci-lint Go Report Card Coverage sloc deps GitHub Release GitHub Release

privage is a terminal based password manager and general file encryption tool that relies on age for encryption. Optionally it uses a yubikey for encryption of the age key.

The main goal of privage is to have your secrets (credentials and other files) securely backed up in untrusted 3-party locations whitout revealing any secret information (not even the file name) to those 3-party services.

WARNING: The author is not a cryptographer, and the code has not been reviewed. Use at your own risk.

You may want to use privage if:

  • You want to keep your encrypted credentials and other secrets files in a directory (maybe managed by a revision control system (ex: git))
  • You want to have backups of this directory in untrusted 3 party services (github, gitlab, bitbucket)
  • You do not want to leak any information (not even the name of the files) in case of a breach of those 3 party services, which you otherwise should always assume. privage guarantees not leaking information because it also encrypts the metadata of the files.
  • You want to have one encrypted file per credential or secret file.
  • You trust the computer running privage. privage uses unencrypted age keys, following the reasoning here. privage supports yubikeys to encrypt the age secret key.

Contents

Features

  • privage uses the golang age API for encryption of files.
  • privage can use a yubikey (PIV smart card) to encrypt the age secret key. See Yubikey
  • privage uses categories to allow classification of the encrypted files.
  • Encrypted files do not reveal any metadata. privage encrypted files names are hashes of the file name and the category. See design
  • privage encrypts any kind of file, not only credentials/passwords.
  • privage can easily (with one command) change the secret key and reencode all the files with the new key. See rotate
  • privage tries to be simple: it does not wrap git or your editor: Use git to control your files and use your preferred editor to edit credentials files.
  • Powerful command completion. All commands have completion. See Bash Completion

Installation

Pre-built binaries for multiple platforms (Linux, macOS, Windows, FreeBSD) and architectures (amd64, arm64, arm) are available on the releases page.

Build

If your system has a supported version of Go, you can build from source.

Dependencies

sudo apt-get -y install pkg-config libpcsclite-dev libpcsclite1 pcscd pcsc-tools build-essential pkg-config

privage

 go install github.com/revelaction/privage/cmd...@v0.24.0

Build without Yubikey support

If you do not need Yubikey support and want to avoid the dependency on piv-go (which requires CGO and PCSC libraries), you can build privage with the noyubikey tag:

go build -tags noyubikey ./cmd/privage

This will produce a binary that does not require libpcsclite-dev and can be built with CGO_ENABLED=0. Attempting to use Yubikey-related features in such a build will result in an error message.

Migration from v0.30.0 or older

Version v0.30.0 was the last version that allowed the .age suffix for encrypted files. Starting from v0.31.0, privage strictly enforces the .privage extension.

If you are migrating from an older version, you must rename your existing .age files to .privage. You can use the following command in your secrets directory:

find . -maxdepth 1 -name "*.age" -type f -exec sh -c 'mv "$1" "${1%.age}.privage"' _ {} \;

If you use git, you also need to update your .gitignore file to replace !*.age with !*.privage and run git add . to stage the renamed files.

Usage

Initialize a directory for your credentials and other encrypted files

Create a directory to contain your encrypted credentials and other secret files. This directory can be backed up to untrusted 3-party services.

mkdir /home/user/mysecrets
cd /home/user/mysecrets
git init

Now run privage init:

privage init
๐Ÿ”‘ Generated age key file `/home/user/mysecrets/privage-key.txt` โœ”๏ธ
๐Ÿ“’ Generated `/home/user/mysecrets/.gitignore` file โœ”๏ธ
๐Ÿ“‘ Generated config file .privage.conf โœ”๏ธ

The init command does three things:

  1. it creates a secret key file named privage-key.txt (if no one is found in the system). The key is a standard unencrypted age key or a Yubikey
    encrypted age key.

  2. it creates a .gitignore file to make sure that only encrypted (.privage) files are stored in the directory. The file content is:

     # Ignore everything
     *
    
     # But not these files...
     !.gitignore
     !*.privage
    
  3. it creates a .privage.conf file in your home directory. The config file contains references to the secret key and the path to the encrypted files. These references allows privage to be used in any directory of your computer.

To create a encrypted age secret key with a yubikey, add the flag --piv-slot, -p with the yubikey slot that will be used to encrypt/decrypt the age key.

privage init -p 86
๐Ÿ”‘ Generated encrypted age key file `/home/user/src/privage/privage-key.txt` with PIV slot 86 โœ”๏ธ
๐Ÿ“’ Generated `/home/user/src/privage/.gitignore` file โœ”๏ธ
๐Ÿ“‘ Generated config file .privage.conf โœ”๏ธ

Stateless usage (automation)

The init command is optional and primarily serves to set up a convenient environment. For automation or usage within scripts, privage can be used statelessly by explicitly providing the age key and the directory path using flags:

  • -k, --key: Path to the age secret key file.
  • -r, --repository: Path to the directory containing the .privage files.

This allows you to use privage without a configuration file:

privage -k /path/to/key.txt -r /path/to/secrets list

Create a credentials file

In privage, credentials are structured text (.toml files), that can contain not only passwords, but any other data associated with a website, like API keys, 2-factor backup codes, etc.

To add a barebone credentials file (that you can later edit), use the command add, specifying a category (for credential files it should always be credential) and a label (any string that good describes the website, f.ex. somewebsite.com@loginname).

privage add credential somewebsite.com@loginname
An encrypted file was saved for ๐Ÿ“– somewebsite.com@loginname  ๐Ÿ”–credential

privage will generate a random password, put the password (among other fields) in a .toml file and encrypt that file under the category 'credential'.

It is recommended to use some naming convention for the credentials label, like <url>@loginname

You can now list the encrypted file with:

ls -al

drwxrwxr-x  3 user user 4096 Sep 26 18:27 .
drwxr-xr-x 29 user user 4096 Sep 25 21:43 ..
-rw-rw-r--  1 user user  347 Sep 26 18:27 66ceb74807d0fd997566360b22ecbda1590ec35fbd3dd0ce88e15311a4e53faf.privage
drwxrwxr-x  7 user user 4096 Sep 26 18:16 .git
-rw-------  1 user user    0 Sep 26 18:21 .gitignore
-rw-------  1 user user  189 Sep 26 18:21 privage-key.txt

That long age file is the encrypted credential file. The label (somewebsite.com@loginname) and the category (credential) were encrypted along with the credential information.

Encrypt any file

privage can encrypt any file. You can use any category and label.

For example, to encrypt the file secret-plan.doc under the category work:

privage add work secret-plan.doc

List the encrypted files

To list the encrypted files, use list:

privage list
Found 2 total encrypted tracked files.

        ๐Ÿ“– somewebsite.com@loginname  ๐Ÿ”–credential
        ๐Ÿ’ผ secret-plan.doc ๐Ÿ”–work

To list only encrypted files corresponding to the category credential:

privage list credential
Found 1 files matching your category 'credential' of a total of 2 tracked files.

        ๐Ÿ“– somewebsite.com@loginname  ๐Ÿ”–credential

The list command accepts a string for matching the labels and categories:

privage list somew
Found 1 files with name matching 'somew':

    ๐Ÿ“– somewebsite.com@loginname  ๐Ÿ”–credential

Copy the password to the clipboard

The command clipboard copies the credential password to the clipboard

privage clipboard somewebsite.com@loginname 
The password for `somewebsite.com@loginname` is in the clipboard

Use the flag -d (--delete) to empty the clipboard.

privage clipboard -d 

Show the contents of a credentials file

The command show presents in the terminal the login and the password of a credential file:

privage show somewebsite.com@loginname

    Login:๐Ÿ‘ค loginname
    Password:๐Ÿ”‘ ad81h4b54*)(y73

If the file is not a credential file, privage will ask you to use cat.

Show a specific field of a credentials file

You can provide a second argument to show to print only the value of a specific TOML field. This is particularly useful for automation and shell scripts (e.g., to retrieve an API key).

privage show somewebsite.com@loginname api_key

Supported field names (like login, password, api_key, url, etc.) can be autocompleted by pressing [TAB].

Cat the contents of an encrypted file

The command cat prints the decrypted contents of an encrypted file to the terminal (standard output). This is useful for piping to other commands or viewing the raw content of a file (including the full content of credential files).

privage cat somewebsite.com@loginname
#
login = "loginname"
password = "ad8Q1hD4b54*)(y73"

email = ""
url = "somewebsite.com"
...

Or for regular files:

privage cat secret-plan.doc

Decrypt a file for manual edition

Use decrypt to decrypt the contents of a file:

privage decrypt somewebsite.com@loginname
The file somewebsite.com@loginname was decrypted in the directory /home/user/mysecrets.

(Use "privage reencrypt --force" to reencrypt all decrypted files)
(Use "privage reencrypt --clean" to reencrypt all decrypted files and after that delete them)

decrypt will write a decrypted file in the same directory. In the case of credentials files, the decrypted file is a .toml file. You can use now your favorite editor to change the password, user, email and other predefined fields.

vim somewebsite.com@loginname

After manually changing the file, you have to reencrypt the file...

Reencrypt edited files

Use the reencrypt command to reencrypt all files that were decrypted and are present in the directory:

โคท privage reencrypt
Found the following files to be reencrypted:

๐Ÿ“– somewebsite.com@me  ๐Ÿ”–credential

(Use "privage reencrypt --force" to reencrypt all files)
(Use "privage reencrypt --clean" to reencrypt and also delete the decrypted files)

Without flags, reencrypt will only show (dry-run) the files that will be reencrypted. Use the flag -f or -c to force the reencryption.

Delete an encrypted file

the command delete deletes an encrypted file:

privage delete somewebsite.com@loginname

Get information about the configuration

โคท privage status

๐Ÿ”‘ Found age key file privage-key.txt in /home/user/mysecrets/privage-key.txt โœ”๏ธ
๐Ÿ“‚ The directory of the encripted files is /home/user/mysecrets โœ”๏ธ
๐Ÿ“‘ Found config file .privage.conf in /home/user/.privage.conf โœ”๏ธ

     The configuration file /home/user/.privage.conf is up to date

๐Ÿ”  Found 13 encrypted files for the age key /home/user/mysecrets/privage-key.txt

Rotate

The rotate command will create a new age secret key and reencrypt all files with this new key. With the flag --clean, it will also delete the encrypted files with the old key, and will rename both old and new keys.

To generate a new age key and reencrypt all the files:

privage rotate

You can add the flag --clean to delete the old key encrypted files, and swap the secret key file names.

privage rotate --clean

To generate a yubikey encrypted age secret key, use the flag --piv-slot, -p, to provide the yubikey slot that holds the key. See possible values.

# f. ex: use the 0x86 slot of the yubikey 5 
privage rotate -p 86 --clean

Design

The content of a privage encrypted file is the byte concatenation of two age encrypted payloads:

The first encrypted payload (the header) contains the file name and a category (plus a version of the header). This encrypted payload is padded to 512 bytes.

The second encrypted payload contains the file contents.

privage uses a flat directory structure: all encrypted .privage files are stored directly in the same directory. Subdirectories are not supported and are ignored during scanning.

When listing the encrypted files, privage scans all encrypted files, retrieves the encrypted header payload and decrypts it, presenting the header.

When writing the encrypted file, privage hashes the header and the public age key, and uses the hash as name of the encrypted file. Encrypted privage file names look like this:

425020f87e753ebe4dba67a872de04b7ce7350a63af9f74c1b7c4d633b41573c.privage
5e107b8e3b57411d5661d05e54f755408dd12c831a6b63e8033885c211da1317.privage

Bash Completion

privage has builtin bash autocompletion. You can enable completion commands by putting the following bash snippet in your .bashrc file:

if command -v privage >/dev/null; then
    source <(privage bash)
fi

Command line options

โคท privage help
Usage: privage [global options] command [command options] [arguments...]

Commands:
  init       Add a .gitignore, age/yubikey key file to the current directory. Add a config file in the home directory.
  key        Decrypt the age private key with the PIV key defined in the .privage.conf file.
  status     Provide information about the current configuration.
  add        Add a new encrypted file.
  delete     Delete an encrypted file.
  list       list metadata of all/some encrypted files.
  show       Show the contents the an encripted file.
  cat        Print the full contents of an encrypted file to stdout.
  clipboard  Copy the credential password to the clipboard
  decrypt    Decrypt a file and write its content in a file named after the label
  reencrypt  Reencrypt all decrypted files that are already encrypted. (default is dry-run)
  rotate     Create a new age key and reencrypt every file with the new key
  bash       Dump bash complete script.
  version    Show version information
  help       Show help for a command.

Global Options:
  -h, --help             Show help for privage
  -c, -conf string       Use file as privage configuration file
  -k, -key string        Use file path for private key
  -p, -piv-slot string   The PIV slot for decryption of the age key
  -r, -repository string Use file path as path for the encrypted files

Version: v0.31.1, commit b15c5a6, yubikey enabled

About

privage is a terminal based password manager and general file encryption tool

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages