Install
Bootstrap
Section titled “Bootstrap”Run on any new machine:
curl dotkit.run/sh | shOr with wget:
wget -qO- dotkit.run/sh | shPass options using sh -s --:
curl -fsSL dotkit.run/sh | sh -s -- --username yourname --defaultsOptions
Section titled “Options”| Option | Description |
|---|---|
-d, --defaults | Skip all prompts. Use defaults. |
-u, --username NAME | Clone NAME/dotkit from GitHub. |
-r, --repo REPO | Repo as user/repo, full URL, or local path. Mutually exclusive with --username. |
-p, --profile NAME | Profile to apply. Skips selection prompt. |
-t, --target DIR | Where to clone the repo. Default: ~/dotkit. |
--no-sudo | Do not use sudo at any point. |
--cli PATH | Use a local CLI directory or tarball instead of downloading. |
--pat TOKEN | GitHub PAT for private repos. Could instead be interactive or DOTKIT_PAT env var. See below. |
--dry-run | Print what would happen. No system changes. |
Common examples
Section titled “Common examples”Skip prompts, use a specific profile:
curl -fsSL dotkit.run/sh | sh -s -- --username yourname --profile work --defaultsClone to a custom location:
curl -fsSL dotkit.run/sh | sh -s -- --username yourname --target ~/dotfilesUse a full URL (GitHub, GitLab, self-hosted):
curl -fsSL dotkit.run/sh | sh -s -- --repo https://github.com/yourname/dotkitUse a local repo already on disk:
curl -fsSL dotkit.run/sh | sh -s -- --repo ~/dotfiles --profile workPreview without changing anything:
curl -fsSL dotkit.run/sh | sh -s -- --username yourname --dry-runPrivate repos
Section titled “Private repos”By default, the installer will prompt for a GitHub personal access token (PAT) if it needs to access a private repository. That would be the most secure way to provide the token, as it won’t be stored in shell history or visible in the process list. However, you can also provide the token non-interactively with the --pat flag or DOTKIT_PAT environment variable for convenience. Please read the caution section for security considerations.
DOTKIT_PAT=ghp_xxx curl -fsSL dotkit.run/sh | sh -s -- --repo yourname/dotkitSSH keys
Section titled “SSH keys”The installer can decrypt and install SSH keys stored as age-encrypted files in a private GitHub repo. SSH key setup runs before the repo is cloned, so your keys are ready for private dotkit repo access.
To decrypt the keys, someone needs both the GitHub PAT and the age passphrase. The PAT alone gives repo access but the keys remain encrypted. Store both in a password manager. Enable 2FA on your GitHub account.
Required repo structure
Section titled “Required repo structure”Your private ssh-keys repo must contain age binaries and your encrypted key files:
your-ssh-keys-repo/ age/ darwin-arm64/ age age-plugin-batchpass darwin-amd64/ age age-plugin-batchpass linux-amd64/ age age-plugin-batchpass linux-arm64/ age age-plugin-batchpass id_ed25519.age id_ed25519.pub.age id_rsa.ageThe age/ folder provides the binaries you used to encrypt the keys (this way you won’t ever be missing them). The installer downloads the right one for the current platform.
Creating a PAT
Section titled “Creating a PAT”Go to GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens and generate a new token.
- Name: something like
ssh-keys-read - Resource owner: your account
- Repository access: select only your ssh-keys repo
- Permissions: Contents: Read-only
The token is shown only once. Save it to a password manager.
Encrypting your keys
Section titled “Encrypting your keys”All files must use the same passphrase. The installer reads it once and uses it for every .age file.
-
Create a private GitHub repo with the structure above.
-
Encrypt all keys in
~/.ssh/at once:Terminal window cd ~/.sshprintf "age passphrase: "; read -r AGE_PASSPHRASE; export AGE_PASSPHRASEfor f in *; do[ -f "$f" ] || continuecase "$f" in *.age|*.age.bak.*) continue ;; esacage -e -j batchpass -o "$f.age" "$f"echo "Encrypted: $f"done -
Verify all files decrypt correctly before pushing:
Terminal window for f in *.age; do[ -f "$f" ] || continueoriginal="${f%.age}"[ -f "$original" ] || continueage -d -j batchpass "$f" | diff - "$original" \&& echo "OK: $f" || echo "FAIL: $f"done -
Commit the
.agefiles to your private repo. Never commit the plaintext keys.
During bootstrap
Section titled “During bootstrap”When the installer runs, it:
- Prompts for your ssh-keys repo (
owner/repoorhttps://github.com/owner/repo) - Prompts for a GitHub PAT to access the private repo (hidden input)
- Downloads the
agebinary andage-plugin-batchpassfor your platform from the repo - Downloads the
.agefiles to~/.ssh/ - Prompts for the age passphrase (hidden input)
- Decrypts keys in place with
chmod 600and removes the.agefiles
Default locations
Section titled “Default locations”| Path | Description |
|---|---|
~/.local/bin/ | CLI scripts |
~/.local/share/dotkit/ | State files (active profile, exported env vars) |
~/dotkit | Default clone location |