/privacy-guard
Prevents private infrastructure details (node hostnames, internal project names, local usernames and personal emails, absolute home paths, private and VPN IP ranges) from leaking into public repositories through commits, PRs, docs or release artifacts. Use when working in a
$ npx -y skills add fvadicamo/dev-agent-skills --skill privacy-guard --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/privacy-guard
Context preview
The summary Claude sees to decide when to auto-load this skill.
Prevents private infrastructure details (node hostnames, internal project names, local usernames and personal emails, absolute home paths, private and VPN IP ranges) from leaking into public repositories through commits, PRs, docs or release artifacts. Use when working in a
SKILL.md
privacy-guard.SKILL.mdname: privacy-guard
description: Prevents private infrastructure details (node hostnames, internal project names, local usernames and personal emails, absolute home paths, private and VPN IP ranges) from leaking into public repositories through commits, PRs, docs or release artifacts. Use when working in a public or soon-to-be-public repo, before commits or releases, when writing deployment docs for an OSS project, or when the user asks to "set up the privacy guard", "install privacy-guard", "check for leaks", "protect this public repo". Bootstraps a pre-commit hook backed by a gitignored local denylist plus gitleaks.
argument-hint: "[setup <repo-path> | check | update-denylist]"
privacy-guard
Guard against accidentally publishing details of your private infrastructure in public repositories (or in repositories that may become public later). Two legs: behavioral rules for the Claude session, always on, and a per-repo technical gate: a pre-commit hook backed by a gitignored local denylist, plus gitleaks.
Threat model
The public repository is the boundary. Anything that describes your private infrastructure must not cross it, in any form: committed files, commit messages, branch names, PR and issue bodies, release notes, published artifacts, screenshots.
**Sensitive, never in a public repo:**
- node hostnames and internal aliases (workstations, VPS, client machines)
- names of internal projects and service instances that were never published
- local usernames, personal and work email addresses
- personal domains and URLs of internal services
- absolute paths of home directories and internal mounts
- private-network IP ranges and VPN address space (for example the Tailscale CGNAT range
`100.64.0.0/10`)
- cookie files, tokens, credentials (also covered by gitleaks)
**Not sensitive, fine in public docs:**
- public products and technologies named generically (Tailscale, Docker, n8n)
- the maintainer's public GitHub username
- deployment patterns described in generic form ("a Docker host reachable over your private
network / behind a VPN")
The concrete list of sensitive tokens is yours and stays private. This skill ships `references/denylist-template.txt`, a placeholder-only starting point: fill it in a private location (a private dotfiles repo, a private notes repo) and treat that filled copy as the seed you propagate from. Never commit the filled version to a public repo.
Behavioral rules (Claude session in a public repo)
1. Never write internal tokens into committed files. Private deployment details are documented in a private repo or in a gitignored `.local/` directory, never in the public repo's docs. 2. The user mentioning internal names in conversation does NOT authorize writing them into the repo: the conversation is private, the repo is not. 3. Before every commit: re-read the diff looking for denylist tokens. The hook is the safety net, not the first check. 4. This applies outside files too: commit messages, branch names, PR and issue titles and bodies, CHANGELOG entries, published artifacts. 5. If a sensitive token has already reached published git history: tell the user immediately (rotation, history rewrite with BFG or filter-repo are their calls), do not just remove it from the tip.
Per-repo setup (`setup <repo-path>`)
From the root of the target repo:
1. Copy `references/check_privacy.sh` to `scripts/check_privacy.sh` and make it executable. It stays a **copy**: fix it here and recopy, never edit it there. See *Keeping copies current* below for why that rule needs a check behind it. 2. Create `.local/privacy-denylist.txt` from your private seed (or from `references/denylist-template.txt` on a first run), adapting the patterns to this repo's context. 3. Make sure `.gitignore` contains `.local/`. 4. Add the blocks from `references/pre-commit-snippet.yaml` to `.pre-commit-config.yaml` (gitleaks + privacy-denylist). 5. Run `pre-commit install`, adding `--hook-type pre-push` if the repo uses push hooks. 6. Verify: create a temporary file containing one token from the denylist and check that `scripts/check_privacy.sh <file>` exits with code 1. An unfilled denylist (only comments) makes the hook a silent no-op, so this step is what tells you the guard is actually armed.
Design property: the denylist is NOT committed, because publishing the list would reveal the very tokens it protects. As a consequence the hook is a no-op for external contributors and in CI. Generic secrets (keys, tokens) stay covered by gitleaks, which runs everywhere.
Variant: repos with versioned git hooks
If the target repo sets `core.hooksPath` (a shared `.githooks/` directory committed to the repo), `pre-commit install` refuses to run, by design: *"Cowardly refusing to install hooks with `core.hooksPath` set"*. Do not unset it to make room for the framework, that would disable the hooks the repo already relies on. Instead, replace steps 4 and 5 with a call to `check_privacy.sh` from the existing hook, over the staged file list:
files=()
while IFS= read -r -d '' f; do files+=("$f"); done \
< <(git diff --cached --name-only -z --diff-filter=d)
if [ ${#files[@]} -gt 0 ]; then
bash scripts/check_privacy.sh "${files[@]}" || exit 1
fiThe `-z`/`read -d ''` pair keeps filenames with spaces intact, and `|| exit 1` is what makes the hook actually block: swallowing the script's exit code leaves a guard that reports and lets the commit through anyway.
Two consequences worth stating to the user. Without the framework nothing invokes gitleaks per commit, so run it in CI instead. And the framework's stash step no longer changes what this check sees: it reads `git diff --cached`, so it looks at the staged blobs either way. The flip side is a real loss and should be said out loud: a token living only in an unstaged edit is no longer reported, where the old whole-file form did notice it. It is not being committed, so a pre-comm
Read more
name: privacy-guard description: Prevents private infrastructure details (node hostnames, internal project names, local usernames and personal emails, absolute home paths, private and VPN IP ranges) from leaking into public repositories through commits, PRs, docs or release artifacts. Use when working in a public or soon-to-be-public repo, before commits or releases, when writing deployment docs for an OSS project, or when the user asks to "set up the privacy guard", "install privacy-guard", "check for leaks", "protect this public repo". Bootstraps a pre-commit hook backed by a gitignored local denylist plus gitleaks. argument-hint: "[setup <repo-path> | check | update-denylist]"
privacy-guard
Guard against accidentally publishing details of your private infrastructure in public repositories (or in repositories that may become public later). Two legs: behavioral rules for the Claude session, always on, and a per-repo technical gate: a pre-commit hook backed by a gitignored local denylist, plus gitleaks.
Threat model
The public repository is the boundary. Anything that describes your private infrastructure must not cross it, in any form: committed files, commit messages, branch names, PR and issue bodies, release notes, published artifacts, screenshots.
**Sensitive, never in a public repo:**
- node hostnames and internal aliases (workstations, VPS, client machines)
- names of internal projects and service instances that were never published
- local usernames, personal and work email addresses
- personal domains and URLs of internal services
- absolute paths of home directories and internal mounts
- private-network IP ranges and VPN address space (for example the Tailscale CGNAT range
`100.64.0.0/10`)
- cookie files, tokens, credentials (also covered by gitleaks)
**Not sensitive, fine in public docs:**
- public products and technologies named generically (Tailscale, Docker, n8n)
- the maintainer's public GitHub username
- deployment patterns described in generic form ("a Docker host reachable over your private
network / behind a VPN")
The concrete list of sensitive tokens is yours and stays private. This skill ships `references/denylist-template.txt`, a placeholder-only starting point: fill it in a private location (a private dotfiles repo, a private notes repo) and treat that filled copy as the seed you propagate from. Never commit the filled version to a public repo.
Behavioral rules (Claude session in a public repo)
1. Never write internal tokens into committed files. Private deployment details are documented in a private repo or in a gitignored `.local/` directory, never in the public repo's docs. 2. The user mentioning internal names in conversation does NOT authorize writing them into the repo: the conversation is private, the repo is not. 3. Before every commit: re-read the diff looking for denylist tokens. The hook is the safety net, not the first check. 4. This applies outside files too: commit messages, branch names, PR and issue titles and bodies, CHANGELOG entries, published artifacts. 5. If a sensitive token has already reached published git history: tell the user immediately (rotation, history rewrite with BFG or filter-repo are their calls), do not just remove it from the tip.
Per-repo setup (`setup <repo-path>`)
From the root of the target repo:
1. Copy `references/check_privacy.sh` to `scripts/check_privacy.sh` and make it executable. It stays a **copy**: fix it here and recopy, never edit it there. See *Keeping copies current* below for why that rule needs a check behind it. 2. Create `.local/privacy-denylist.txt` from your private seed (or from `references/denylist-template.txt` on a first run), adapting the patterns to this repo's context. 3. Make sure `.gitignore` contains `.local/`. 4. Add the blocks from `references/pre-commit-snippet.yaml` to `.pre-commit-config.yaml` (gitleaks + privacy-denylist). 5. Run `pre-commit install`, adding `--hook-type pre-push` if the repo uses push hooks. 6. Verify: create a temporary file containing one token from the denylist and check that `scripts/check_privacy.sh <file>` exits with code 1. An unfilled denylist (only comments) makes the hook a silent no-op, so this step is what tells you the guard is actually armed.
Design property: the denylist is NOT committed, because publishing the list would reveal the very tokens it protects. As a consequence the hook is a no-op for external contributors and in CI. Generic secrets (keys, tokens) stay covered by gitleaks, which runs everywhere.
Variant: repos with versioned git hooks
If the target repo sets `core.hooksPath` (a shared `.githooks/` directory committed to the repo), `pre-commit install` refuses to run, by design: *"Cowardly refusing to install hooks with `core.hooksPath` set"*. Do not unset it to make room for the framework, that would disable the hooks the repo already relies on. Instead, replace steps 4 and 5 with a call to `check_privacy.sh` from the existing hook, over the staged file list:
files=()
while IFS= read -r -d '' f; do files+=("$f"); done \
< <(git diff --cached --name-only -z --diff-filter=d)
if [ ${#files[@]} -gt 0 ]; then
bash scripts/check_privacy.sh "${files[@]}" || exit 1
fiThe `-z`/`read -d ''` pair keeps filenames with spaces intact, and `|| exit 1` is what makes the hook actually block: swallowing the script's exit code leaves a guard that reports and lets the commit through anyway.
Two consequences worth stating to the user. Without the framework nothing invokes gitleaks per commit, so run it in CI instead. And the framework's stash step no longer changes what this check sees: it reads `git diff --cached`, so it looks at the staged blobs either way. The flip side is a real loss and should be said out loud: a token living only in an unstaged edit is no longer reported, where the old whole-file form did notice it. It is not being committed, so a pre-comm
Showing the first part of this file.
Agent skills and hooks for development workflows - Git, GitHub, skill authoring, safety guardrails, and public-repo privacy. These skills are designed for Claude Code, the CLI tool by Anthropic.
Other skills on dev-agent-skills.
- /git-commit
Creates git commits following Conventional Commits format with type/scope/subject. Use when user wants to commit changes, create commit, save work, or stage and commit. Enforces project-specific conventions from CLAUDE.md.
Open skill - /github-pr-creation
Creates GitHub Pull Requests with automated validation and task tracking. Use when user wants to create PR, open pull request, submit for review, or check if ready for PR. Analyzes commits, validates task completion, generates Conventional Commits title and description, suggests
Open skill - /github-pr-merge
Merges GitHub Pull Requests after validating pre-merge checklist. Use when user wants to merge PR, close PR, finalize PR, complete merge, approve and merge, or execute merge. Runs pre-merge validation (tests, lint, CI, comments), confirms with user, merges with proper format,
Open skill - /github-pr-review
Handles PR review comments and feedback resolution. Use when user wants to resolve PR comments, handle review feedback, fix review comments, address PR review, check review status, respond to reviewer, verify PR readiness, review PR comments, analyze review feedback, evaluate PR
Open skill - /creating-skills
Guide for creating Claude Code skills following Anthropic's official best practices. Use when user wants to create a new skill, build a skill, write SKILL.md, update an existing skill, or needs skill creation guidelines. Provides structure, frontmatter fields, naming
Open skill

