Skip to content

Private (encrypted) files

Pol Rivero edited this page Apr 11, 2025 · 10 revisions

⚠️ Disclaimer ⚠️

The doot crypt functionality relies on git-crypt internally, which has the following limitations:

  • File names, commit messages, symlink targets, gitlinks, and other metadata are NOT encrypted, only file contents.
  • It does NOT hide when a file does or doesn't change, the length of a file, or the fact that two files are identical.
  • It does NOT support revoking access to an encrypted repository which was previously granted. This applies to both multi-user GPG mode (there's no del-gpg-user command) and also symmetric key mode (there's no support for rotating the key). See issue.
  • Encrypted files are not compressible. A small change to a big encrypted file requires git to store the entire changed file instead of just the diff.
  • Similarly, line-specific git operations won't work, such as line history (git blame) or committing only some lines/hunks of the file (git add --patch).
  • Of course, once you unlock the repository, your dotfiles are stored locally in plaintext (files are only encrypted when pushing to the remote). If your machine has multiple users, make sure to apply file permissions accordingly.
  • For very small encrypted files (< 25 bytes), sometimes git diff doesn't show changes properly.

If your dotfiles repository contains the file passwords/github.txt, anyone with read access will know: 1. that you have a GitHub account and 2. the length of that password. You should never store passwords on your public dotfiles, even if they are encrypted. If your scripts need to use a password, consider reading it from an external file, and store that file in a password manager.

Please read git-crypt documentation and make sure that your private files contain .doot-crypt in the filename before committing them. I am in no way responsible for any damages that may occur due to the use of this tool.

How to use

Set up for the first time

  1. Run doot crypt init to initialize the repository for using encryption.

  2. Run doot crypt export-key <output_file> to output the decryption key to a file. Make sure to store it safely, you won't be able to unlock your private files if you lose it.

  3. Then, to encrypt a file or directory, just add .doot-crypt anywhere in its name before committing it. This extension will not be included in the created symlink. For example, secrets.doot-crypt.json will be applied as secrets.json.
    You can also pass the --crypt flag to the doot add command to automatically append this extension when copying the file.
    Adding .doot-crypt to the name of a directory will encrypt all files inside it.

Tip

The exclude_files, include_files and implicit_dot_ignore configs refer to the filename in the dotfiles directory, not the name of the installed symlink. Therefore, you must also add the .doot-crypt extension in those rules, if needed.

Examples

All of these files will be encrypted when uploaded to the remote because they contain .doot-crypt. For simplicity, these examples assume implicit_dot=false.

Path (relative to dotfiles repo) Created symlink
secret.doot-crypt ~/secret
secret.txt.doot-crypt ~/secret.txt
secret.doot-crypt.txt ~/secret.txt
secrets.doot-crypt/key.txt ~/secrets/key.txt
secrets.doot-crypt.d/key.txt ~/secrets.d/key.txt
config/secrets.doot-crypt/passwords/github.doot-crypt.txt ~/config/secrets/passwords/github.txt

Unlocking after cloning the repository

Anyone who clones the repository will only have access to the non-private files. Private files will remain encrypted (and doot install won't symlink them) until you unlock them with:

doot crypt unlock <key_file> # The key you exported when setting up the repository

If later you want to undo this action, you can re-encrypt the files with doot crypt lock.

Advanced: using GPG keys

Warning

For a typical dotfiles directory, I recommend using symmetric encryption instead of GPG. Follow these instructions only if your use case requires it.

If your repository has multiple collaborators that should have access to the private files, and you prefer to use GPG instead of providing them with the symmetric key, do the following:

  1. Run doot crypt init to initialize the repository as usual.

  2. Acquire the public keys of you and your collaborators. Consult the GPG manual for instructions on how to create keys, if needed.

  3. From your repository, run doot crypt add-gpg-user <user_id>, where user_id is a key ID, full fingerprint, email address, or anything else that uniquely identifies a public key to GPG. This will commit some changes to your repository.

  4. Make sure to store your private key securely, as you will need it in order to decrypt the files.

  5. To decrypt the files after cloning the repository, make sure your machine has the appropriate private key installed and run doot crypt unlock (without additional arguments).

Clone this wiki locally