Crates.io | knox |
lib.rs | knox |
version | 0.4.0 |
source | src |
created_at | 2019-03-23 11:31:40.630854 |
updated_at | 2020-05-04 19:06:14.39356 |
description | structured secret vault encrypted through GPG |
homepage | |
repository | https://github.com/apognu/knox |
max_upload_size | |
id | 123277 |
size | 111,109 |
A structured secret manager encrypted through GPG with TOTP capabilities.
Until this reaches 1.0.0, the Vault storage format is subject to breaking changes.
A vault is constituted of a _vault.meta file, at its root, containing the GPG identities used to encrypt the data as well as an index, mapping virtual secret paths to filesystem files. All filesystem paths in the vault are relative to this metadata file.
When a secret is created with a virtual path of one/two/three, a random UUID is generated, for instance, 2aef7bc6-856c-492d-aaee-07e0f2579812, and the secret's attributes will be stored in a file named 2a/2aef7bc6-856c-492d-aaee-07e0f2579812.
The mapping between virtual paths and filesystem paths is kept in the metadata file, and allows for retrieving data based on familiar user-defined paths. Hence, the metadata file is essential for using the vault and should be backed up along with the data. Secret files could still be manually decrypted and read, but you would lose the ability to refer to them through virtual paths.
The filesystem paths being random, and both the secret and metadata files being encrypted with your GPG public key, the filesystem does not give any information about what is stored inside the secrets.
All files are marshalled with Protocol Buffers and encrypted through gpg-agent, producing armored ciphertext.
When a vault is initialized, a local git repository is created in its directory, to record all operations.
This project is made of two distinct crates:
Knox can be installed through cargo
:
$ cargo install knox
As a library, you can add this stanza to your Cargo.yaml
:
[dependencies]
libknox = "^0.3"
The following command creates an empty vault and takes the GPG identity for which the vault will be encrypted.
$ knox init myidentity@example.com
INFO libknox::commands::init > vault initialized successfully
INFO knox::commands::init > local git repository initialized
By default, the vault will be created in $HOME/.knox
. You can change this path by setting the KNOX_PATH
environment variable.
A local git repository will also be created in your vault directory (see Git integration for more information). This behavior can be disabled by passing --no-git
to init
.
$ knox add dir/subdir/website.com username=apognu password=Str0ngP@ss
INFO libknox::commands::write > entry personal/website was successfully added to the vault
vault
is attribute-agnostic, there is no special handling of, for instance, the password
attribute. You can add any number of attributes to an entry.
One special kind of attribute is confidential attributes. They only differ in that they are not printed on the console by default, and they are input interactively. Any attribute set without a value will trigger the prompt and will never be printed without the -p
option.
$ knox add website.com username=apognu password=
Enter value for 'password':
INFO libknox::commands::write > entry personal/website was successfully added to the vault
One can generate random alphanumeric passwords with the attribute syntax attr=-
. By default, a random 16-character password will be generated for that attribute. Generated attributes will automatically be set as confidential.
The --symbols
option adds special characters into the mix.
$ knox add personal/website username=apognu password=-
One can generate passwords with a different size with the -l
/ --length
option.
An entire file can be embedded into an attribute with the syntax attr=@/path/to/file
. File attributes will never be printed on the console, and will require the use of -w
to be used.
$ knox add personal/ssh pubkey=@/home/apognu/.ssh/id_rsa.pub privkey=@/home/apognu/.ssh/id_rsa
INFO libknox::commands::write > entry personal/ssh was successfully added to the vault
$ knox show personal/ssh
๐ Knox ยป ssh ยป keys
privkey = <file content>
pubkey = <file content>
$ knox list
๐ Knox
ยป one
ยป two
/ subdir1
/ subdir2
ยป secret1
ยป secret2
ยป secret3
ยป secret4
$ knox list subdir1/subdir2
๐ Knox
/ subdir1
/ subdir2
ยป secret1
ยป secret2
ยป secret3
ยป secret4
You can filter the prefix for which to list secrets, for instance, vault list subdir1/subdir2
.
You can search for secret matching a substring:
$ knox search social
๐ Knox (search for social):
ยป personal/social/facebook
ยป personal/social/twitter
ยป personal/social/linkedin
$ knox show dir/subdir/website.com
๐ Knox / dir / subdir / website.com
password = <redacted>
username = apognu
url = http://example.com/login
The -p
option can be used to display the redacted attributes.
The -c
option can be used to copy one attribute to the clipboard. By default, the attribute named password
will be copied. If you would like to copy another attribute to your clipboard, use the -a
option.
When you use the -w
option in combination with showing a secret containing file attributes, all the file attributes of that secret will be written to files in a directory named after the secret path.
$ knox show my/secret/file
๐ Knox ยป my ยป secret ยป file
file = <file content>
$ knox show -w my/secret/file
By default, all file attributes are written to matching files. If you wish to restrict which attribute gets considered for writing, use the -a
option:
$ knox show -w -a file1 -a file2 my/secret/files
For file attributes, -s
(for --stdout
) can also be used to print the content of a single attribute to your standard output.
$ knox show -w -a privkey -s sshkeys/corporate | ssh-add -
The syntax for modifying an existing secret is exactly the same as the one used to create one, with one addition: an optional list of attributes to delete.
$ knox edit website.com -d url username=newlogin password=
INFO libknox::commands::write > entry website.com was successfully edited
This command will delete thre url
attribute from the secret, change the username
attribute to newlogin
and prompt for the value of the redacted attribute password
A secret can be renamed through the rename
command:
$ knox rename my/first/secret new/location/secret
INFO libknox::commands::write > entry my/first/secret was successfully renamed to new/location/secret
$ knox delete dir/subdir/website.com
INFO libknox::commands::delete > entry 'dir/subdir/website.com' was successfully deleted from the vault
Vault integrates Troy Hunt's Have I Been Pwned to check whether some of your passwords appear in a known data breach. For now, you can manually check every confidential attribute is a specific entry:
$ knox pwned my/super/password
INFO libknox::commands::pwned > Pwnage status for attributes at pwned/test
:: PWNED my/super/password:password
:: PWNED my/super/password:secure
:: PWNED my/super/password:apikey
The check is also performed for confidential attributes when adding or editing an entry. You can bypass this behavior by using the -f
/ --force
flag on those commands.
You may also omit the PATH
paramter to initiate a vault-wide check against the data breaches. This may take some time, but will check all confidential attributes in your vault:
$ knox pwned
INFO libknox::commands::pwned > checking for pwned secret across your vault
:: PWNED test/insecure/test1:password
:: PWNED test/insecure/test1:apikey
:: PWNED test/insecure/test2:password
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ 53/70
[...]
INFO knox::commands::pwned > 5 secrets were found in HIBP's database
When you initialize your vault, it is set up for one specific GPG identity. You may add and remove any GPG identity to your vault to allow other people to access it.
Warning: Check with your threat model if this is appropriate for you. When someone gets a copy of a vault encrypted with their GPG public key, there is no going back, they will be able to decrypt the content of that particular snapshot of the vault forever.
If you use a multi-identity vault, a single private key is sufficient to decrypt the vault, but all public keys are required to write to it.
When you add or remove an identity to or from the vault, all entries (including metadata) are reencrypted with the new set of public keys (as GPG recipients). This could take some time, depending on the size of your vault.
$ knox init myown@identity.com
INFO libknox::commands::init > vault initialized successfully at /vault
[...]
$ knox identities add myfriend@identity.com
INFO libknox::commands::identities > Writing metadata file...
:: re-encrypting entry company/secret1
:: re-encrypting entry personal/secret2
:: re-encrypting entry company/secret2
:: re-encrypting entry personal/secret1
:: re-encrypting entry personal/secret3
$ knox identities delete myfriend@identity.com
Every entry in your vault is able to store one TOTP configuration used to generate TOTP codes. First, configure the TOTP parameters (every parameter is optional except the secret, as a base32 string):
$ knox totp configure secure/website --secret abcdefghijklmnop --interval 30 --length 6 --hash sha1
INFO knox::commands::totp > the TOTP configuration for secure/website has been saved successfully
The TOTP will appear as a virtual redacted attribute on the entry, and will also be printed with a specific command:
$ knox show -p secure/website
๐ Knox / secure / website
username = apognu
password = password
@totp = 123456 (expires in 22s)
$ know totp show secure/website
๐ Knox / secure / website
TODO = 123456 (expires in 13s)
You can inspect existing TOTP configuration through the command knox totp inspect
, it will print it back to you.
Every time you edit your vault, either by adding, editing or deleting secrets, or changing identities, a git commit is created in your vault directory. No identifying information about your secret is ever stored in the commit messages, so as not to leak any insight into what you store in your vault.
You can manually set a remote and push your repository if you so desire:
$ knox git remote git@my.githost.com:passwords.git
INFO knox::commands::git > git remote URL set to 'git@my.githost.com:passwords.git'
$ knox git push
INFO knox::commands::git > vault modifications successfully pushed upstream
For now, the only supported authentication methods is through SSH keys provided by ssh-agent
.
The examples
directory contain an example showing how to use libknox
to manipulate vaults. You can run the example with:
$ cargo run --example simple