Secrets Vault

Vaults are saved to a local directory. You can back up or sync this folder as needed.

Exporting a vault

Export a vault to a portable .axovault file, encrypted with a passphrase or age recipient key:

ap vault export [options]
Option Description
--vault <key> Vault to export. Shows a selection prompt if not given.
--export-path <path> Output file path. Defaults to <vault-key>.axovault in the current directory.

Encryption options (mutually exclusive; you will be prompted for a passphrase if none are given):

Option Description
--passphrase <passphrase> Encrypt with a passphrase.
--recipient <name> Encrypt to a managed age recipient stored in the keychain (by name).
--recipient-key <age1...> Encrypt to an age public key.

Importing a vault

Import a vault from an export file:

ap vault import <path> [vault-key] [options]
Argument / Option Description
<path> Path to the export file.
[vault-key] Key to assign to the imported vault. Optional; overrides the key stored in the export file.
--passphrase <passphrase> Decrypt with a passphrase. You will be prompted if not provided.
--identity <name> Decrypt with an age identity stored in the keychain.
--identity-file <path> Decrypt with an age identity file containing an AGE-SECRET-KEY-1... key.

Vault Spec

EncryptedVault is the on-disk representation of a vault. All item metadata and credential values are encrypted; the vault can be loaded from disk without unlocking, but its contents are inaccessible until the file key is decrypted.

The design uses envelope encryption: a per-vault AES-256 file key is wrapped by the device's Secure Enclave, and all vault data is encrypted with AES-256-GCM using context-specific AAD to bind encrypted items to their location in the encrypted vault.

The encrypted vault contains three kinds of individually encrypted blobs: item metadata, credential metadata, and credential values.

{
  "id": "<uuid>",
  "name": "My Vault",
  "file_key": "base64-encoded-wrapped-aes-key",
  "items": {
    "<uuid>": {
      "metadata": "base64(nonce || ciphertext)",
      "credentials": {
        "<uuid>": {
          "metadata": "base64(nonce || ciphertext)",
          "value": "base64(nonce || ciphertext)"
        }
      }
    }
  }
}

For exported vaults, the file key is unwrapped and re-wrapped with age. The encrypted blobs are unchanged.