============= Configuration ============= .. contents:: 1 Recipient resolution ---------------------- nimvault resolves the GPG recipient through a 3-tier chain. The first non-empty value wins: 1. **CLI flag**: ``--recipient KEY`` (or ``-r KEY``) 2. **Environment variable**: ``NIMVAULT_GPG_RECIPIENT`` 3. **Config file**: ``.vault/config`` in the git repository root If none are set, nimvault exits with an error. .. image:: ../images/recipient_resolution.svg 2 Config file format -------------------- ``.vault/config`` uses a simple key-value format: .. code:: ini # Lines starting with # are comments recipient = 9CCCE36402CB49A6 root = repo Whitespace around the ``=`` is ignored. Recognized keys: ``recipient`` GPG key ID for encryption (required). ``root`` Base directory for path resolution. When set to ``repo``, paths are stored relative to the repository root. When set to a relative path, it is resolved against the repository root. When absent, paths use ``~/`` prefix for portability. ``wrap`` Repeatable. ``:[,...]`` -- which recipients may open the entries matching a path pattern. See below. ``backend`` ``gpg`` (default) or ``age``. Also ``NIMVAULT_BACKEND``. ``identity`` Age identity file. Also ``NIMVAULT_AGE_IDENTITY``. ``signer`` ``gpg`` (default for the GPG backend), ``ssh`` (default for age), or ``none``. ``sign_key`` SSH private key used to sign the manifest when ``signer = ssh``. ``allowed_signers`` SSH allowed-signers file used to verify that signature. ``signer_identity`` Principal to match inside ``allowed_signers``. 3 Per-path recipients --------------------- Not every machine should read every secret. A ``wrap`` rule maps a path pattern to the recipients allowed to open those entries: .. code:: ini recipient = LAPTOPKEY # Specific rules first: the first match decides. wrap = ~/.ssh/**:LAPTOPKEY wrap = ~/.gnupg/**:LAPTOPKEY wrap = **:LAPTOPKEY,BUILDBOXKEY Order in the file is precedence, so the narrow rules go above the general one. An entry matching no rule uses ``recipient``, which is why a config with no ``wrap`` lines behaves exactly as it did before rules existed. 3.1 How it works ~~~~~~~~~~~~~~~~ Each entry's payload is encrypted under its own data key (see the manifest reference). The data keys are grouped by recipient set, and each group is written to its own ``.vault/keys..gpg`` encrypted to that group alone. A machine decrypts the group files its key opens and no others, so it can read exactly the entries meant for it. ``unseal`` on such a machine restores what it can read. ``check`` needs no key at all, so vault integrity is verifiable from anywhere. Patterns: ``\*`` matches within one path segment, ``\*\*`` spans separators, and a pattern ending in ``/`` covers everything beneath it. Patterns are anchored at both ends, so ``~/x/*`` does not match ``~/x/deep/one``. 3.2 Changing the rules ~~~~~~~~~~~~~~~~~~~~~~ Editing ``wrap`` rules does not move anything by itself. Run ``nimvault rotate``: it recomputes each entry's group and rewrites the key files, leaving payloads untouched. An entry that moved group has its key written to the new group's file and dropped from the old one. 3.3 A prerequisite worth stating ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Groups are only worth anything when the machines hold **different** keys. If every machine shares one private key, every machine can open every group and the split is decoration. Give each machine its own key and exchange public keys before relying on this. 3.4 Break-glass recovery ~~~~~~~~~~~~~~~~~~~~~~~~ Because a group takes several recipients, an offline key -- generated once, printed or kept on removable media, never on any machine -- can be added to the general rule. It then opens the vault if every machine is lost, without a threshold scheme or any additional machinery. 4 GPG key ID ------------ The recipient value is any string GPG accepts as a recipient identifier: - Long key ID: ``9CCCE36402CB49A6`` - Fingerprint: ``ABCD1234...`` - Email: ``user@example.com`` Long key IDs are recommended for unambiguous matching. 4.1 Finding your key ID ~~~~~~~~~~~~~~~~~~~~~~~ .. code:: bash gpg --list-keys --keyid-format long # pub rsa4096/9CCCE36402CB49A6 2024-01-01 [SC] # ^^^^^^^^^^^^^^^^ this is the key ID