137 lines
6.4 KiB
Markdown
137 lines
6.4 KiB
Markdown
# architecture
|
|
|
|
* `secret vault` allows you to change 'vaults'. vaults are just a universe
|
|
of secrets (and a single associated long-term key). you can have multiple
|
|
vaults, each with its own long-term key and secrets. this is useful for
|
|
separating work and personal secrets, or for separating different projects
|
|
with different long-term keys.
|
|
|
|
* `secret vault list`
|
|
* `secret vault create <name>` creates a new profile
|
|
* `secret vault select <name>` selects (switches to) a profile
|
|
|
|
the first and initial vault is titled `default`.
|
|
|
|
* `secret init` initializes a new vault and imports a user-provided BIP39
|
|
mnemonic phrase. The user must provide their own mnemonic phrase. The
|
|
long-term keypair is derived from this mnemonic. The long-term keypair is
|
|
used to encrypt and decrypt secrets. The long-term keypair is stored in the
|
|
vault. The private key for the vault is encrypted to a short-term keypair.
|
|
The short-term keypair private key is encrypted to a passphrase.
|
|
|
|
Use `secret generate mnemonic` to create a new BIP39 mnemonic phrase if you
|
|
need one.
|
|
|
|
if there is already a vault, `secret init` exits with an error.
|
|
|
|
* `secret import [vaultname]` will derive a long-term key pair from a bip32 seed
|
|
phrase and import it into the named vault. if no vault name is specified,
|
|
`default` is used. if the named vault already exists, it exits with
|
|
an error.
|
|
|
|
first:
|
|
|
|
* the long term key pair will be derived in memory
|
|
* a random short term (unlock) key pair will be derived in memory
|
|
|
|
then:
|
|
|
|
* the long term key pair public key will be written to disk
|
|
* the short term key pair public key will be written to disk
|
|
* the long term key pair private key will be encrypted to the short term
|
|
public key and written to disk
|
|
* the short term key pair private key will be encrypted to a passphrase
|
|
and written to disk
|
|
|
|
* `secret enroll sep` creates a short-term keypair inside the secure enclave
|
|
of a macOS device. it will then use one of your existing short-term
|
|
keypairs to decrypt the long-term keypair, re-encrypt it to the secure
|
|
enclave short-term keypair, and write it to disk. it requires an existing
|
|
vault, and errors otherwise.
|
|
|
|
* short-term keypairs are called 'unlock keys'.
|
|
|
|
* `secret add <secret>` adds a secret to the vault. this will generate a
|
|
keypair (secret-specific key) and encrypt the private portion of the
|
|
secret-specific key (called an 'unlock key') to the long-term keypair and
|
|
write it to disk. if the secret already exists it will not overwrite, but
|
|
will exit with an error, unless `--force`/`-f` is used. the secret
|
|
identifier is [a-z0-9\.\-\_\/]+ and is used as a storage directory name.
|
|
slashes are converted to % signs.
|
|
|
|
in a future version, overwriting a secret will cause the current secret to
|
|
get moved to a timestamped history archive.
|
|
|
|
* `secret get <secret>` retrieves a secret from the vault. this will use an
|
|
unlock keypair to decrypt the long-term keypair in memory, then use the
|
|
long-term keypair to decrypt the secret-specific keypair, which is then
|
|
used to decrypt the secret. the secret is then returned in plaintext on
|
|
stdout.
|
|
|
|
* `secret keys list` lists the short-term keypairs in the current vault.
|
|
this will show the public keys of the short-term keypairs and their
|
|
creation dates, as well as any flags (such as `hsm`). their identifiers
|
|
are a metahash of the public key data using the sha256 algorithm.
|
|
|
|
* `secret keys rm <keyid>` removes a short-term keypair from the vault. this will
|
|
remove the short-term keypair from the vault, and remove the long-term
|
|
keypair from the short-term keypair.
|
|
|
|
* `secret keys add pgp <pgp keyid>` adds a new short-term keypair to the vault.
|
|
this will generate a new short-term keypair and encrypt it to a given gpg
|
|
key, to allow unlocking a vault with an existing gpg key, for people who
|
|
use yubikeys or other gpg keys with an agent. the new short-term keypair
|
|
is randomly generated, the public key stored, and the private key encrypted
|
|
to the gpg key and stored.
|
|
|
|
* `secret key select <keyid>` selects a short-term keypair to use for
|
|
`secret get` operations.
|
|
|
|
# file layout
|
|
|
|
$BASE = ~/.config/berlin.sneak.pkg.secret (on linux per XDG)
|
|
$BASE = ~/Library/Application Support/berlin.sneak.pkg.secret (on macOS)
|
|
|
|
$BASE/configuration.json
|
|
$BASE/currentvault -> $BASE/vaults.d/default (symlink)
|
|
$BASE/vaults.d/default/
|
|
$BASE/vaults.d/default/vault-metadata.json
|
|
$BASE/vaults.d/default/pub.age
|
|
$BASE/vaults.d/default/current-unlock-key -> $BASE/vaults.d/default/unlock.d/passphrase (symlink)
|
|
$BASE/vaults.d/default/unlock.d/passphrase/unlock-metadata.json
|
|
$BASE/vaults.d/default/unlock.d/passphrase/pub.age
|
|
$BASE/vaults.d/default/unlock.d/passphrase/priv.age
|
|
$BASE/vaults.d/default/unlock.d/passphrase/longterm.age # long-term keypair, encrypted to this short-term keypair
|
|
$BASE/vaults.d/default/unlock.d/sep/unlock-metadata.json
|
|
$BASE/vaults.d/default/unlock.d/sep/pub.age
|
|
$BASE/vaults.d/default/unlock.d/sep/priv.age
|
|
$BASE/vaults.d/default/unlock.d/sep/longterm.age # long-term keypair, encrypted to this short-term keypair
|
|
$BASE/vaults.d/default/unlock.d/pgp/unlock-metadata.json
|
|
$BASE/vaults.d/default/unlock.d/pgp/pub.age
|
|
$BASE/vaults.d/default/unlock.d/pgp/priv.asc
|
|
$BASE/vaults.d/default/unlock.d/pgp/longterm.age # long-term keypair, encrypted to this short-term keypair
|
|
$BASE/vaults.d/default/secrets.d/my-tinder-password/value.age
|
|
$BASE/vaults.d/default/secrets.d/my-tinder-password/pub.age
|
|
$BASE/vaults.d/default/secrets.d/my-tinder-password/priv.age # secret-specific key, encrypted to long-term key
|
|
$BASE/vaults.d/default/secrets.d/my-tinder-password/secret-metadata.json
|
|
$BASE/vaults.d/default/secrets.d/mail%berlin.sneak.secrets.imaplogin/value.age
|
|
$BASE/vaults.d/default/secrets.d/mail%berlin.sneak.secrets.imaplogin/pub.age
|
|
$BASE/vaults.d/default/secrets.d/mail%berlin.sneak.secrets.imaplogin/priv.age
|
|
$BASE/vaults.d/default/secrets.d/mail%berlin.sneak.secrets.imaplogin/secret-metadata.json
|
|
|
|
# example configuration.json
|
|
|
|
`json
|
|
{
|
|
"$id": "https://berlin.sneak.pkg.secret/configuration.json",
|
|
"$schema": "https://berlin.sneak.pkg.secret/configuration.schema.json",
|
|
"version": 1,
|
|
"configuration": {
|
|
"createdAt": "2025-01-01T00:00:00Z",
|
|
"requireAuth": false,
|
|
"pubKey": "<public key of the long-term keypair>",
|
|
"pubKeyFingerprint": "<fingerprint of the long-term keypair>"
|
|
}
|
|
}
|
|
`
|