A simple Python script for secret management
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
Karam Assany c4cc438533
Initial commit
1 year ago
LICENSE Initial commit 1 year ago
README.md Initial commit 1 year ago
secs.py Initial commit 1 year ago

README.md

secs

secs is a minimalist Python script for secret management. It utilizes GnuPG to symmetrically encrypt/decrypt the secret database, the rest is done by Python and its internal modules. So there is no external dependencies (aside from GnuPG.) It's just a script after all.

Prerequisites

WARNING: USE AT YOUR OWN RISK. THERE IS ZERO GUARANTEES ABOUT THE SECURITY OF THIS UTILITY. IT HAS NEVER BEEN TESTED NOR AUDITED BY SECURITY EXPERTS.

The current version of secs is 0.1, which is an alpha stage. Currently, secs was tested only on GNU/Linux. See the Final notes section in the end of this document to see how secs will look like in the beta release.

Requirements

  • GnuPG (available in the path as gpg)
  • Python 3.5 or later

Installation

# clone the repository
git clone --depth=1 https://codeberg.org/karam/secs

# install it either way
install secs/secs.py ~/.local/bin/secs
# or
sudo install secs/secs.py /usr/local/bin/secs

If your preferred Python executable does not exist at /usr/bin/env python3, then remember to edit the shebang line accordingly.

Usage

Technical overview

The secret database is technically a Python dictionary encoded as a string in a UTF-8 plain-text file that is symmetrically encrypted by gpg. Secrets can be referred to by their own tags; one tag can point to one secret at one time. It's preferable for tags to consist only of alphabetical and numeral characters (and underscores _); just to make them easy to pass as command line arguments.

First-time

secs requires an environment variable SECS_DB that points to the absolute path of the secret database. You can create a blank database by issuing:

SECS_DB=/path/to/database.db secs mkdatabase

Instead of passing SECS_DB every time, append it to your login .profile (or .bash_profile, .zprofile, etc depending on your shell):

echo 'export SECS_DB=/path/to/database.db' >> ~/.profile

Commands

# To get a brief help message, pass nothing
secs

# To add new secrets
secs add TAG1 [TAG2 ...]

# To get existing secrets
secs get TAG1 [TAG2 ...]

# To change existing secrets
secs set TAG1 [TAG2 ...]

# To delete existing secrets
secs del TAG1 [TAG2 ...]

# To create a new secret database (nothing should exist at the 'SECS_DB' path)
secs mkdatabase

# To list all tags, or tags matching the given 'REGEX'
secs ls [REGEX]

# To change the passphrase of the database
secs passwd

I/O

To make things clear:

  • Database path is passed as an environment variable.
  • Passphrases are passed from silent (secret) input.
  • Commands, tags and regexes are passed as command line arguments.
  • Secrets are passed from and to standard I/O.

Incremental backups

Whenever a change occurs on the database, a backup in the same directory of the database will be created. Backups are suffixed with their creation timestamp, so they will never get overwritten. This behavior is the default, you can disable it by passing a SECS_NOBACKUPS environment variable (no matter what it contains). If disabled, an old backup will be overwritten with a new one (so there is at least one backup whether incremental backups are enabled or not.)

Final notes

Be aware that each time you decrypt the secret database via secs, it is saved in plain-text into a temporary directory on your disk, this poses a security risk as it's possible to recover the decrypted database from the disk. This issue will be solved as soon as secs becomes well-integrated with GnuPG on the module level (so decrypted data will dealt with directly on RAM.)

Furthermore, a lock-and-unlock mechanism for secs should be implemented. As for now, issuing complicated commands like secs get $(secs ls) will require you to type the passphrase for each call of secs (twice in this case), which is kind of cumbersome and non-convenient. A lock-and-unlock mechanism can solve this by either implementing a system daemon or a built-in shell.

Also, pipelines that have secs on multiple sides (like secs get x | secs add y) will fail. This can be solved by implementing a lock-and-unlock mechanism as described above.

License

secs is licensed under the MIT (Expat) license.

Copyright (C) 2020 Karam Assany (karam.assany@tuta.io)