sysfig can track sensitive files locally — recording their hash without ever pushing the content to the remote git repository.
Two modes are available:
| Flag | Content stored | Git branch | Sync locally | Push to remote |
|---|---|---|---|---|
--local |
full copy in ~/.sysfig/repo.git |
local/<path> |
✅ yes | ❌ never |
--hash-only |
hash only — no content | none | ❌ skipped | ❌ never |
Use --local when you want full local git history (diffs, logs, undo) but the
file must never leave this machine — e.g. WireGuard private keys, VPN configs,
machine-specific credentials.
Use --hash-only when even local storage is too sensitive — you only need to
know whether the file has changed, not what it contains.
# Local-only — full content in local repo, never pushed:
sysfig track --local /etc/wireguard/wg0.conf
# Hash-only — only the hash recorded, no content stored anywhere:
sysfig track --hash-only /etc/ssh/sshd_config
# --local and --hash-only are mutually exclusive.Output for --local:
Tracking /etc/wireguard/wg0.conf
✓ ID: 0b5aac93
✓ Repo: etc/wireguard/wg0.conf
✓ Hash: ed36fd92...
✓ Mode: local-only (never pushed to remote)
Output for --hash-only:
Tracking /etc/ssh/sshd_config
✓ ID: a26787d2
✓ Repo: etc/ssh/sshd_config
✓ Hash: f063ab5c...
✓ Mode: hash-only (integrity monitoring, no content stored)
sysfig status shows dim mode tags next to local/hash-only entries:
PATH HASH STATUS
────────────────────────────────────────────────────────────────────────────
/etc/wireguard/wg0.conf 0b5aac93 SYNCED local
/etc/ssh/sshd_config a26787d2 SYNCED hash
After tampering:
/etc/wireguard/wg0.conf 0b5aac93 DIRTY local
/etc/ssh/sshd_config a26787d2 TAMPERED hash
DIRTY— content changed on disk (local-only file; can be synced locally)TAMPERED— hash-only file drifted from its recorded hash; no content was stored, so drift means something external modified the file
--local files behave like normal tracked files for all local operations.
You can sync them with a commit message to build a local audit trail:
# After rotating VPN keys:
sysfig sync /etc/wireguard/wg0.conf -m "rotated VPN keys 2026-03-22"
# View the local history:
sysfig log /etc/wireguard/wg0.confExample log output:
* cd3ed88 2026-03-22 12:54 tmp/lab-wg/wg0.conf rotated VPN keys 2026-03-22 (local/etc/wireguard/wg0.conf)
The branch name starts with local/ — this prefix ensures the branch is never
included in sysfig push or bundle exports.
sysfig diff and sysfig show also work on local-only files.
--hash-only files are always skipped by sync — there is no content to commit.
sysfig audit checks all local-only and hash-only files and exits with:
| Exit code | Meaning |
|---|---|
0 |
all checked files are clean |
1 |
one or more files are TAMPERED or DIRTY |
2 |
error (could not read state or hash a file) |
# Check all local/hash-only files (default):
sysfig audit
# Check only hash-only files:
sysfig audit --hash-only
# Check only local-only files:
sysfig audit --local
# Check every tracked file (not just local/hash-only):
sysfig audit --all
# Silent — exit code only, no output (for scripts/timers):
sysfig audit --quietExample output when drift is found:
DIRTY /etc/wireguard/wg0.conf
TAMPERED /etc/ssh/sshd_config
Audit: 2/2 file(s) drifted
Install the provided unit and timer files from contrib/systemd/:
cp contrib/systemd/sysfig-audit.service ~/.config/systemd/user/
cp contrib/systemd/sysfig-audit.timer ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now sysfig-audit.timerThe timer runs sysfig audit --quiet every hour and 5 minutes after boot.
If any file has drifted, the service unit exits with code 1 — systemd marks it
failed, which is visible in:
systemctl --user status sysfig-audit.service
journalctl --user -u sysfig-audit.serviceTo react to drift (e.g. send a desktop notification or email), uncomment the
OnFailure= line in sysfig-audit.service and point it at a notify service.
| Action | --local file |
--hash-only file |
|---|---|---|
sysfig track |
stages content in local local/ branch |
records hash only; nothing staged |
sysfig sync |
commits to local local/<path> branch |
skipped — no content |
sysfig push |
never included | never included |
| bundle export | never included | never included |
sysfig status |
SYNCED / DIRTY + local tag |
SYNCED / TAMPERED + hash tag |
sysfig audit |
included by default | included by default |
sysfig diff |
works (local repo copy) | not applicable |
sysfig log |
shows local commit history | not applicable |
sysfig apply |
writes file from local repo | not applicable |
local/*branches exist only in~/.sysfig/repo.giton this machine. They are excluded from bothgit push(refspec filter) and bundle creation (git bundle createonly bundlestrack/*andmanifest).- If
~/.sysfig/repo.gitis on an encrypted partition, local-only content is protected at rest without any additional flags. --hash-onlyprovides tamper detection with zero local content exposure — even if~/.sysfig/is compromised, no file content is recoverable from it.