My personal dotfiles managed by chezmoi. Motto: "One Config to Rule Them All."
- Bitwarden Account: You need a Bitwarden account with the following items:
- Secure Notes:
ssh-key-master-ed25519andssh-key-server-ed25519(Private Keys).- Each item must have a custom field named exactly
public_keycontaining the full SSH public key string (e.g.,ssh-ed25519 AAAA... user@host). This field is read byauthorized_keys.tmplto populate~/.ssh/authorized_keyson machines that accept SSH connections. Without it,authorized_keyswill be empty.
- Each item must have a custom field named exactly
- Password:
tailscale-auth-key(One-off key). Generate a new key for each new machine setup. Enable "Pre-approved" so devices auto-authorize.
- Secure Notes:
- Internet: Required for package downloads.
The script automatically installs chezmoi, bitwarden-cli, git, tailscale, and provisions keys.
- Option A: Interactive (Prompts for secrets):
irm https://raw.githubusercontent.com/vovanphu/arx/master/install.ps1 | iex
- Option B: Automated (Zero-touch, will auto-delete
.env):@("BW_EMAIL=user@mail.com", "BW_PASSWORD=pass", "ROLE=centaur", "HOSTNAME=chiron", "USER_NAME='vovanphu'", "EMAIL_ADDRESS='vovanphu1012@gmail.com'") | Set-Content .env; irm https://raw.githubusercontent.com/vovanphu/arx/master/install.ps1 | iex
- Option C: Direct Environment Injection (No temporary files):
$env:BW_EMAIL="user@mail.com"; $env:BW_PASSWORD="pass"; $env:ROLE="centaur"; $env:HOSTNAME="chiron"; $env:USER_NAME="vovanphu"; $env:EMAIL_ADDRESS="vovanphu1012@gmail.com"; irm https://raw.githubusercontent.com/vovanphu/arx/master/install.ps1 | iex
Handles dependency checks, Bitwarden authentication, and SSH agent reuse.
- Option A: Interactive:
bash -c "$(curl -fsSL https://raw.githubusercontent.com/vovanphu/arx/master/install.sh)" - Option B: Automated (Zero-touch, will auto-delete
.env):echo "BW_EMAIL=user@mail.com" > .env; echo "BW_PASSWORD=pass" >> .env; echo "ROLE=centaur" >> .env; echo "USER_NAME='vovanphu'" >> .env; bash -c "$(curl -fsSL https://raw.githubusercontent.com/vovanphu/arx/master/install.sh)"
- Option C: Direct Environment Injection (No temporary files):
export BW_EMAIL="user@mail.com" BW_PASSWORD="pass" ROLE="centaur" USER_NAME="vovanphu" EMAIL_ADDRESS="vovanphu1012@gmail.com" && bash -c "$(curl -fsSL https://raw.githubusercontent.com/vovanphu/arx/master/install.sh)"
We use a Mythological Role System to categorize machines. The system uses capability-based configuration instead of hardcoded role checks.
All 10 roles are centrally defined with capabilities in .chezmoi.yaml.tmpl. Each role has 5 capabilities:
has_master_key- Gets master SSH keyhas_server_key- Gets server SSH keyreceives_ssh- Has authorized_keys configuredis_server- Server-specific configuration (headless, limited shell history)install_desktop_tools- Installs GUI applications
| Role | Core Concept | Typical Use Case | Capabilities |
|---|---|---|---|
centaur |
The Wise Commander | Laptop/Mac. Admin, Management. | π Master Key, π₯οΈ Desktop |
chimera |
The Hybrid Beast | Windows Workstation + WSL. | π Master + Server Keys, π SSH, π₯οΈ Desktop |
griffin |
The Guardian | Portable Debit/KVM Lab. | π Server Key, π SSH, π₯οΈ Desktop |
hydra |
The Undying Cluster | Proxmox Host. | π Server Key, π SSH, π§ Server |
cyclops |
The Strong | General Purpose Server. | π Server Key, π SSH, π§ Server |
kraken |
The Deep Storage | Database Server. | π Server Key, π SSH, π§ Server |
cerberus |
The Guardian Gate | Security/Firewall Server. | π Server Key, π SSH, π§ Server |
golem |
The Builder | CI/CD Server. | π Server Key, π SSH, π§ Server |
minion |
The Worker | Compute Node. | π Server Key, π SSH, π§ Server |
siren |
The Watchful | Monitoring Server. | π Server Key, π SSH, π§ Server |
π Full Documentation: See ROLES.md for detailed role definitions, how to add new roles, and template usage examples.
- π― Centralized Role Taxonomy: Single source of truth for all role definitions in
.chezmoi.yaml.tmpl - π§ Capability-Based Templates: Templates use capabilities (e.g.,
.has_master_key) instead of hardcoded roles - π¦ Centralized Packages: All software definitions live in
packages.yaml, separating data from installation scripts - π File-Based Merge Logic: SSH merge scripts detect files, not roles (works for any role without code changes)
- π Automated Secrets: Pulls SSH Keys directly from Bitwarden (
ssh-key-master-ed25519->~/.ssh/id_ed25519_dotfiles_master) - π‘οΈ Namespaced Keys: Uses explicit filenames to avoid conflicts with system defaults
- πΎ Smart Backup: Automatically backs up
~/.sshbefore deployment (timestamped:~/.ssh.backup.YYYYMMDD_HHMMSS) - π Intelligent Merge: Preserves old SSH keys and custom config entries when re-installing
- π§Ή Backup Retention: Automatically keeps only 3 most recent backups (prevents disk bloat)
- π Session Cleanup: Clears
BW_SESSIONafter installation (both success and error paths) - πͺ Windows Admin Fix: Auto-configures
C:\ProgramData\ssh\administrators_authorized_keysfor admin accounts - π§ Local Overrides: Supports
~/.ssh/config.localfor custom SSH hosts not managed by dotfiles
- π·οΈ Mythological Name Pools: Curated lists of names (e.g.,
chiron,polyphemus) for each role - π Zero-Touch Tailscale: Automatically authenticates via Bitwarden and configures MagicDNS
- π Hostname Sync: Detects mismatch between config and OS hostname, prompting for safe rename
- β Safety First: Soft-fails if Bitwarden is unreachable, validates session before template rendering
- πͺ Windows: Auto-starts
ssh-agent, handlesbw login/unlock/sync - π§ WSL: Implements Socket Reuse so all terminal tabs share one
ssh-agentsession - π Self-Healing: Automatically derives SSH public keys (
.pub) whenever private keys change - π¨ GUI Ready: Automatically installs FiraCode Nerd Font on Windows and Linux (workstation roles)
- π Unified Shell: Starship prompt & aliases consistent across PowerShell and Bash
- πΎ Persistent tmux:
tmux-resurrect+tmux-continuumon every machine with tmux (cloned without TPM). Auto-saves session snapshots every 15 min; auto-restore is off β restore on demand, then list & attach
- β 100% Platform Parity: Identical behavior on Linux and Windows (verified via SSH_FLOW_REVIEW.md)
- π― Zero Hardcoded Roles: All templates use capability checks (maintainable, no copy-paste errors)
- π Comprehensive Testing: Full SSH flow review with security audit trail
Prefix: C-a (Ctrl+a, thαΊ£ ra, rα»i bαΊ₯m phΓm tiαΊΏp theo).
Session
| Command | Action |
|---|---|
tmux |
New session (auto name) |
tmux new -s <name> |
New session with name |
tmux ls |
List sessions |
tmux a |
Attach to last session |
tmux a -t <name> |
Attach to named session |
prefix + d |
Detach (session stays alive) |
Window (tab)
| Key | Action |
|---|---|
prefix + c |
New window |
prefix + , |
Rename window |
prefix + n / p |
Next / previous window |
prefix + 0..9 |
Jump to window by number |
prefix + w |
List windows (j/k to navigate) |
prefix + & |
Close window |
Pane (split)
| Key | Action |
|---|---|
prefix + | |
Vertical split |
prefix + - |
Horizontal split |
Alt + h/j/k/l |
Move between panes (no prefix) |
prefix + H/J/K/L |
Resize pane |
prefix + z |
Zoom pane (toggle fullscreen) |
prefix + x |
Close pane |
Copy mode β enter with prefix + [, exit with q
| Key | Action |
|---|---|
h/j/k/l |
Navigate |
C-u / C-d |
Page up / down |
/ |
Search |
v |
Begin selection |
y |
Copy and exit |
prefix + ] |
Paste |
Other
| Key | Action |
|---|---|
prefix + r |
Reload ~/.tmux.conf |
prefix + $ |
Rename session |
prefix + ? |
List all keybindings |
prefix + . |
Change window index number |
prefix + :move-window -t <n> |
Move window to position n (999 = end) |
Persistence (resurrect + continuum)
Sessions, windows, panes (and pane contents) survive a reboot. Snapshots are saved automatically every 15 min, but nothing is restored automatically β you bring sessions back only when you want them, then list and attach as usual.
| Key | Action |
|---|---|
prefix + C-s |
Save snapshot now |
prefix + C-r |
Restore last snapshot |
# after a reboot / fresh login
tmux a 2>/dev/null || tmux # start a tmux server
# prefix + C-r # restore the saved sessions
tmux ls # list what came back
tmux a -t <name> # attach to onePlugins are cloned to ~/.tmux/plugins automatically by chezmoi apply (no
TPM) on every machine that has tmux.
Typical SSH workflow
ssh cyclops
tmux a || tmux new -s work # attach or create
# work across multiple windows/panes
# disconnect or lose connection
ssh cyclops
tmux a # everything still thereThe system remembers your choices in ~/.config/chezmoi/chezmoi.toml. To force a fresh start:
- Linux:
rm ~/.config/chezmoi/chezmoi.toml - Windows:
Remove-Item $env:USERPROFILE\.config\chezmoi\chezmoi.toml
If you need to configure SSH for a Windows VM or a new target machine, refer to the following guide:
Then run the install script again.
- ROLES.md - Complete role taxonomy, capabilities, and how to add new roles
- SSH_FLOW_REVIEW.md - Comprehensive SSH flow review with security audit
- docs/ssh-windows-setup.md - Install OpenSSH Server on Windows
- β BW_SESSION Cleanup: Automatically cleared after installation (both success and error paths)
- β Session Validation: Pre-check Bitwarden session before template rendering (Linux + Windows)
- β Backup Retention: Keeps only 3 most recent SSH backups (prevents unlimited disk usage)
- β Centralized Role Taxonomy: Single source of truth eliminates inconsistencies
- β Capability-Based Templates: No more hardcoded role checks (easier maintenance)
- β File-Based Merge: SSH merge scripts work for ANY role without code changes
- β
Near-Complete Platform Parity: Verified functional equivalence on Linux and Windows
β οΈ Note: Environment variable cleanup has minor timing differences between platforms due to process model differences (Bashtrapvs PowerShell scope). Both methods are secure but behavior is not byte-identical.
Consistency Score: 92% β 98% β (platform limitations acknowledged) Security Issues: 3 β 0 β Platform Parity: 10/12 β 13/13 β (functional equivalence achieved)
- DRY Violation β Role Lists x3: Role capabilities are defined in
roles:(L67-140), then manually duplicated inroles_with_*groups (L154-166), then duplicated again inhas_*checks (L171-175). Adding a new role requires updating 3 places β error-prone. - Hardcoded Role Checks in Scripts:
run_once_install-packages.sh.tmplhardcodes workstation roles (centaur || chimera || griffin) instead of using the.is_workstationcapability. Same pattern at lines 38, 80, 140.
- SSH Key Add Logic Bug:
dot_bashrc.tmplL84-85 checksssh-add -lexit code to decide whether to add key. Exit 0 = "has any identity" (not necessarily the right one). Should check by key fingerprint instead. - PowerShell SSH Agent:
powershell_profile.ps1.tmplL32 βGet-Service ssh-agentthrows if service doesn't exist. Needs-ErrorAction SilentlyContinue. - Tailscale Fallback Download:
run_once_install-packages.ps1.tmplL79-89 downloads and executes.exewithout checksum verification. - Error Handling: Package installation failures only warn, don't fail the script. Consider stricter error handling.
- SSH Agent: Add wait/retry loop to ensure service is ready before adding keys.
- Duplicate Comment:
dot_bashrc.tmplL63-64 has twoSSH Agent Auto-Loadcomments. - Redundant Git Alias:
dot_gitconfig.tmpldefinesst = statuswhich overlaps with shell aliasst = "git status". - Trailing Blank Lines:
run_once_install-packages.ps1.tmplhas 5 trailing blank lines (L118-122).