Skip to content

feat(/dotfiles-sync): privacy gate for SSH fragments + 1P-backup check#72

Merged
tieubao merged 1 commit into
mainfrom
feat/sync-ssh-privacy-gate
May 4, 2026
Merged

feat(/dotfiles-sync): privacy gate for SSH fragments + 1P-backup check#72
tieubao merged 1 commit into
mainfrom
feat/sync-ssh-privacy-gate

Conversation

@tieubao
Copy link
Copy Markdown
Member

@tieubao tieubao commented May 4, 2026

Summary

The /dotfiles-sync command was the upstream cause of PR #69's leak. New SSH fragments were classified as core/local/skip with no privacy review, so mac-mini-danang got committed plaintext to a public repo.

This PR closes the loop: privacy gate at detection time, four-way classification, and a notify-only check for *.local fragments that lack a 1P Secure Note backup.

What changed

Area Before After
Detection Lists fragment names only Tags each [clean] or [private] using a heuristic (.ts.net FQDN, IP in HostName, multi-segment internal hostnames, non-standard SSH port, purpose-revealing identity files)
Classification core / local / skip (3-way) core / local / private / skip (4-way). private → rename to *.local, create op://Vault/SSH config: <name>/notesPlain. Flagged-private must never go to core.
Backup status SSH keys only Adds parallel check for ~/.ssh/config.d/*.local fragments without a 1P Secure Note. Drops OP_SERVICE_ACCOUNT_TOKEN per S-49 so the lookup sees the full vault list.
Action table "Track SSH configs → chezmoi add" Same row gains a verification guard; new row "Back up SSH fragment privately" with the literal op item create command
Report host1, host2, ... host1 [clean] / host2 [⚠ private]

Mirror parity preserved between .claude/commands/dotfiles-sync.md (project) and home/dot_claude/commands/dotfiles-sync.md (user, deployed via chezmoi).

Heuristic smoke test

Tested on three synthetic fragments locally:

Fragment Verdict
Host github / HostName github.com / Port 22 clean ✓
Host mini / HostName mac-mini-danang / IdentityFile ~/.ssh/id_ed25519 private ✓
Host weirdvps / HostName 45.32.53.122 / Port 52847 / IdentityFile id_ed25519_trading_vps private ✓

Test plan

  • Mirror parity (/usr/bin/diff returns 0)
  • Heuristic regex compiles in grep -E (no PCRE lookaheads — earlier draft had (?!22$) and was fixed before commit)
  • Three-fragment smoke test passes
  • Real-world: next /dotfiles-sync invocation correctly flags any new SSH fragment

🤖 Generated with Claude Code

The /dotfiles-sync command was the upstream cause of PR #69's leak: SSH
fragments were classified as core/local/skip with no privacy review, so
mac-mini-danang got committed plaintext to a public repo.

- Detection now tags each new SSH fragment [clean] or [private] using a
  heuristic (Tailscale .ts.net FQDN, IP in HostName, multi-segment internal
  hostnames, non-standard SSH port, purpose-revealing identity-file names).
- Classification expanded to four-way: core / local / private / skip.
  The 'private' route renames to *.local (gitignored) and creates a 1P
  Secure Note titled 'SSH config: <name>'. Flagged-private fragments must
  never go to core.
- New notify-only check: scan ~/.ssh/config.d/*.local for fragments without
  a matching 1P Secure Note. Drops OP_SERVICE_ACCOUNT_TOKEN per S-49 so the
  lookup sees the user's full vault list.
- Action table gains "Back up SSH fragment privately" with the literal
  op item create command. Existing "Track SSH configs" row warns to verify
  no infra fingerprint first.
- Mirror parity preserved between .claude/commands/ and home/dot_claude/commands/.

Smoke-tested on three synthetic fragments (clean / private hostname / private
port): all classified correctly.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@tieubao tieubao merged commit 164eaeb into main May 4, 2026
2 checks passed
@tieubao tieubao deleted the feat/sync-ssh-privacy-gate branch May 4, 2026 20:07
tieubao added a commit that referenced this pull request May 5, 2026
#72)

The /dotfiles-sync command was the upstream cause of PR #69's leak: SSH
fragments were classified as core/local/skip with no privacy review, so
mac-mini-danang got committed plaintext to a public repo.

- Detection now tags each new SSH fragment [clean] or [private] using a
  heuristic (Tailscale .ts.net FQDN, IP in HostName, multi-segment internal
  hostnames, non-standard SSH port, purpose-revealing identity-file names).
- Classification expanded to four-way: core / local / private / skip.
  The 'private' route renames to *.local (gitignored) and creates a 1P
  Secure Note titled 'SSH config: <name>'. Flagged-private fragments must
  never go to core.
- New notify-only check: scan ~/.ssh/config.d/*.local for fragments without
  a matching 1P Secure Note. Drops OP_SERVICE_ACCOUNT_TOKEN per S-49 so the
  lookup sees the user's full vault list.
- Action table gains "Back up SSH fragment privately" with the literal
  op item create command. Existing "Track SSH configs" row warns to verify
  no infra fingerprint first.
- Mirror parity preserved between .claude/commands/ and home/dot_claude/commands/.

Smoke-tested on three synthetic fragments (clean / private hostname / private
port): all classified correctly.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
tieubao added a commit that referenced this pull request May 5, 2026
Document the post-#72 history rewrite: filter-repo, force-push under a
~13s ruleset toggle, backup tag cleanup. The leaked blob is now orphaned
on GitHub; direct SHA access remains until GitHub's internal GC.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant