Install
$ agentstack add skill-kennguyen887-agent-foundation-prevent-secret-and-pii-leaks ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
When to use
About to git push to a public or shared repo, open-source something, publish a package, or run an export/sync/vendor step that copies your local content into a public destination. Also: reviewing a diff before it goes out, or cleaning up after a leak.
Reason about THREE classes, not just "secrets"
Be precise — they differ in severity and remediation:
- Credentials / secrets — API keys, tokens, passwords, private keys, connection strings,
.envvalues. Highest. If exposed → rotate immediately (assume compromised), then scrub. - PII — emails, real names, usernames, teammate handles, customer data. Can't be "rotated"; once public, treat as disclosed.
- Internal identifiers — cloud account IDs, internal hostnames/URLs, IAM user names, resource/cluster/ARN/bucket names, private org or project codenames, ticket IDs. Info-disclosure, not credentials — don't call these "secrets," but keep them out of public/OSS too.
All three must stay out of a public/shared destination; only the severity and fix differ.
Before you publish (prevention — this is where the win is)
- Confirm the destination's visibility first. Public vs private — check, never assume (
gh repo view --json visibility). "It's probably private" has caused real leaks. - Scan the EXACT bytes being published, not just the obvious files. Include config, fixtures, lockfiles, CI files, and the tooling itself. → The sanitizer-isn't-sanitized trap: an export/sync script that scrubs identifiers often hard-codes those very identifiers in its own config (the scrub list = a list of your real emails/orgs/usernames/handles). Keep such local-only tooling gitignored, never vendored.
- Publish OUTPUT, not source/tooling. Vendor only sanitized, generic content; replace every real identifier with a placeholder (`
,my-service,example.com,your-org`). Docs/skills: principle-first, no org/customer names, no real infra identifiers. - Make the pipeline fail-closed. A publish/export step should run a secret+PII scan and exit non-zero if anything survives — don't rely on eyeballing the diff. Add a pre-commit/pre-push hook for the same.
- Default-deny for shared (public/partner) destinations. When unsure whether something is safe to publish, leave it out and ask.
If it already leaked (remediation)
Order matters; do not skip rotation for credentials.
- Credentials → ROTATE NOW, before anything else. Scrubbing history does not un-leak a key that bots may have already scraped.
- Stop the bleeding:
gitignore+git rm --cached(untrack). This does NOT remove it from history — past commits still contain it. - Rewrite history: back up first (
git bundle create backup.bundle --all), then remove the file/secret from every commit —git filter-repo --path --invert-paths(preferred), orgit filter-branch --index-filter 'git rm --cached --ignore-unmatch ' --if filter-repo isn't installed. - Force-push the rewritten history (destructive — rewrites SHAs, breaks clones; have the backup):
git push --force-with-lease. - Residuals you can't reach by force-push:
- Forks keep the old history independently (
gh repo view --json forkCount;gh api repos///forks). You can't rewrite someone else's fork. - Platform caches keep old commits reachable by SHA for a while.
- → For both, the lever is GitHub Support ("remove sensitive data"): they purge cached views and remove the data across the fork network.
- Triage by class: credentials = rotated (step 1); PII / internal identifiers = can't rotate → scrubbed + treated as disclosed.
Mindset
You can never fully un-publish — history, forks, caches, and scrapers persist. So the budget belongs in prevention: verify visibility, scan the exact published bytes (including the tooling that handles secrets), placeholder everything, and fail closed.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: kennguyen887
- Source: kennguyen887/agent-foundation
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.