Skip to main content

public-export-sanitization

Sanitize internal content before it goes public (repo, blog, talk). Use when publishing, to catch leaked project ids, service-account emails, hostnames, names, and repo-escaping links.

Quellinformationen

Repository
laurigates/claude-plugins
Letzte Quellaktivität
1. Oktober 2026 um 19:22
Erkannte Sprache von SKILL.md
Englisch
Sterne
60
Forks
6

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
3 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
public-export-sanitization
description
Sanitize internal content before it goes public (repo, blog, talk). Use when publishing, to catch leaked project ids, service-account emails, hostnames, names, and repo-escaping links.
allowed-tools
Bash(bash *), Read, Grep, Glob, Edit, TodoWrite
created
2026-09-24T00:00:00.000Z
modified
2026-09-29T00:00:00.000Z
reviewed
2026-09-24T00:00:00.000Z
# Sanitizing Internal Content Before It Goes Public When moving content from a private or internal source into a **public** destination (a public repo, a blog post, a conference talk, a shareable draft), the expensive failure is a **silent context leak**: an internal cloud project id, a service-account email, an internal hostname, a personal name, or a Markdown link that points back into a private repo. A human reviewer reliably misses *one* class of these every time, and the miss becomes visible only after it is public. The judgment (what to keep, how to reword) is yours. The detection is a script: run it, don't re-derive it. ## When to Use This Skill | Use this skill when... | Use instead when... | |---|---| | Moving internal docs, code, or notes into a public repo, post, or talk | Scanning for tokens and keys: `git-plugin:git-security-checks` (gitleaks) | | Checking that an exported doc set has no links back into private sources | Checking a doc is readable by a zero-context reader: `agent-patterns-plugin:cold-read-gate` | | Genericizing infrastructure identifiers for a public write-up | Verifying a machine-read value is *correct*: `documentation-plugin:docs-verify-machine-facts` | ## The tripwire: run it on every export ```bash bash "${CLAUDE_SKILL_DIR}/scripts/check-public-export.sh" --patterns <org.patterns> <export-tree> ``` It scans for internal **identifiers** and for **Markdown links that escape the export or are broken**. Exit 1 means findings to review; exit 2 is a usage error. Patterns ignore `<placeholder>` tokens, so a genericized tree comes back clean. **Built-in patterns are org-neutral only**: GCP service-account emails (`*.iam.gserviceaccount.com`), 12-digit GCP project numbers, and absolute home paths. Your organisation's identifier shapes go in a `--patterns` file, one `label::regex` per line (extended regex, `#` comments allowed), kept wherever your private config lives rather than in the public tree: ```text # org.patterns GCP project id (acme-*)::\bacme-[a-z][a-z0-9-]{2,}\b Internal hostname (corp.example)::\b[a-z0-9-]+\.corp\.example\b Staff email::\b[a-z0-9._%+-]+@example\.com\b ``` Without a `--patterns` file the scan checks only the built-in shapes, so a clean result then says nothing about org-specific identifiers. Two modes: - **Pre-export gate (default, strict):** scan the export set on its own; *any* link leaving it is flagged. This is the self-containment gate below. - **Post-placement verify:** once the content sits inside a larger **public** repo, pass `--repo-root <repo>` so links to public siblings (`../LICENSE`, `../other-doc`) are allowed and only repo-escaping or broken links flag. Other options: `--names <file>` (personal names, which can't be regex'd; seed the list from the source's git authors and access grants), `--allow <regex>` (dismiss a known-benign hit, such as a CSS class that shares a project-id prefix; check the regex does not also hide real ids), `--no-links`, `-q`. It takes **one** tree per run. Given several paths it scans only the last, and the summary line then reads like a clean sweep of all of them. Loop over the trees instead, and check that each summary names the tree you meant. No pattern catches **private repository names**, and they are often the leak that matters most: a repo name is not shaped like an identifier, so no regex can recognise it. Grep for them separately, with the list taken from GitHub rather than from memory: ```bash gh repo list <owner> --visibility private --limit 1000 --json name --jq '.[].name' > /tmp/private-repos.txt grep -rnoFf /tmp/private-repos.txt <export-tree> ``` Short repo names match as substrings (a repo named `dot` matches "two-dot diff"), so read each hit rather than counting them. It is **not** a secret scanner. Run `gitleaks` for tokens and keys; this catches *context* leakage, a different axis. ## Curation rubric (per candidate doc or file) Keep a candidate only if it clears all five: | Gate | Pass condition | |---|---| | **Audience** | The source already marks it shareable (an inventory tag, an explicit "OK to share"); internal-only means drop it. | | **Self-containment** | No dependency on private docs or infra; links rewritten to public targets or removed. | | **Relevance** | Teaches the public audience something genuinely useful. | | **Sensitivity** | No secrets; internal identifiers genericized; safe in the open. | | **Durability** | Durable knowledge, not a point-in-time snapshot that rots. | ## Genericization checklist (identifier to placeholder) Replace the real value and keep the architecture. Common classes: - Cloud project id / number: `<gcp-project-id>` / `<project-number>` - Service-account email: `<sa-name>` (or `<sa-name>@<gcp-project-id>.iam.gserviceaccount.com`; the bare form keeps the scan clean and consistent) - Database, KMS, and secret-manager resource names: `<cloud-sql-instance>`, `<…-keyring>`, `<…-secret>` - Internal hostnames: `<…-host>` - **Private repo names**: describe the shape instead ("a 16-file PR", "a node-pack repo"). A public repo in the same org can be named; check its visibility rather than assuming it from the org - Internal issue/PR refs (`#NNNN`): drop, or "(tracked internally)" - **Personal names** and usernames: a role ("a team member", "an applicant") - Internal cost or accounting codes: the project name, not the numeric code **Keep** the non-sensitive facts that carry the value: region, machine types, CIDRs, component/chart/image versions, public DNS hostnames, public upstream URLs. **A claim about how the organisation is configured** ("this org's `main` has no required status checks") needs more than a placeholder: it is internal, and it goes stale when the setting changes. Replace it with the check the reader can run on their own repo. For that example: `mergeStateStatus` is `UNSTABLE` when a failing check is present but not required, and `BLOCKED` when it is required and the merge is refused. ## Link rewriting No link may leave the export set except to **public** upstream. Links into the private source (`../adr/…`, `../../infra/…`, `.claude/rules/…`) become self-contained prose or are repointed within the export. The script's link check is the backstop for the class humans miss most. ## Delivery discipline - Branch off a fresh `origin/main`, stage only the new paths (`git add <paths>`, never `-A`), and check that `git log origin/main..HEAD` shows only your commit before pushing. - If the export PR is squash-merged and you pushed more commits to its branch afterward, those commits are in neither `main` nor the squash. Replay them onto a fresh `origin/main` in a new PR. - Run the tripwire once more against the content **in its destination** (`--repo-root <repo>`) before opening the PR. ## Agentic Optimizations | Context | Command | |---|---| | Summary line only | `bash "${CLAUDE_SKILL_DIR}/scripts/check-public-export.sh" -q --patterns <org.patterns> <tree>` | | Inside a public repo | `bash "${CLAUDE_SKILL_DIR}/scripts/check-public-export.sh" --repo-root <repo> --patterns <org.patterns> <tree>` | | Identifiers only | `bash "${CLAUDE_SKILL_DIR}/scripts/check-public-export.sh" --no-links --patterns <org.patterns> <tree>` |
Auf GitHub ansehen