{"skill":{"slug":"nerua1-vibe-safe","displayName":"VibeSafe — Security Pre-Flight for AI Coding Agents","summary":"Security pre-flight for AI coding agents — plan libs, audit CVEs, certify, then code. Non-blocking in autonomous mode (ex-post report).","description":"---\nname: vibe-safe\ndescription: Security pre-flight for AI coding agents — plan libs, audit CVEs, certify, then code. Non-blocking in autonomous mode (ex-post report).\ntrigger: Before writing any code that installs or uses external packages/libraries\nversion: 1.1.0\ncompatible: claude-code, kimi, hermes, openclaw, copilot, cursor\n---\n\n# VibeSafe — Security Pre-Flight Protocol\n\n> **Vibe coding fast is fine. Vibe coding blind is debt.**\n> Run this BEFORE committing to any library. Redesign is free before you write line 1. It's not free on line 1000.\n\n---\n\n## WHEN TO INVOKE\n\n**Always invoke when:**\n- Starting a new project or feature that adds dependencies\n- User says \"use X library\" or \"install Y\"\n- You are about to write a `package.json`, `requirements.txt`, `pyproject.toml`, `go.mod`, `Cargo.toml`\n\n**Safe to skip:** Pure logic code, refactoring existing code, documentation, config changes with no new deps.\n\n**Autonomous mode:** Run phases 1-3 AFTER coding (ex-post), append `risk-report.md` to session output. Never block the user mid-flow.\n\n**Interactive mode:** Run phases 1-3 BEFORE coding. User can type `/skip-audit` to proceed anyway (decision logged in stay_safe.md as \"user-waived\").\n\n---\n\n## PHASE 1: PLAN\n\nBefore touching any code, produce this exact table in your response:\n\n```markdown\n## VibeSafe Pre-Flight — Planning\n\n### Proposed Libraries\n| Library | Version (target) | Ecosystem | Purpose | Alternatives considered | Why this one |\n|---------|-----------------|-----------|---------|------------------------|--------------|\n| express | ^4.18           | npm       | HTTP server | fastify, hono, koa | ecosystem size |\n| ...     | ...             | ...       | ...     | ...                    | ...          |\n\n### Threat Model\n| Risk | Likelihood | Impact | Mitigation |\n|------|-----------|--------|------------|\n| Supply chain attack via malicious package | Low | Critical | Pin exact versions, use lockfile |\n| CVE in outdated dep | Medium | High | Audit before code |\n| Secrets leaked to git | Medium | Critical | .env + .gitignore policy |\n| Unmaintained lib breaks in 6 months | Medium | Medium | Check last commit < 12 months |\n```\n\n**Secrets policy declaration (MANDATORY):**\nConfirm in your plan:\n- API keys go into `.env` file only, never in source code\n- `.env` is always in `.gitignore`\n- Credentials are accessed via environment variables or a secret manager\n- `.env.example` with dummy values is committed to the repo\n\nIf any library requires embedding secrets in source code: REDESIGN, find alternative.\n\n---\n\n## PHASE 2: AUDIT\n\nRun these checks. Use real tools when available. Always run at least the OSV API check (no tools required).\n\n### Node.js / npm\n```bash\n# If package.json exists or you are about to create one:\nnpm audit --json 2>/dev/null | python3 -c \"\nimport json, sys\nd = json.load(sys.stdin)\nvulns = d.get('vulnerabilities', {})\ncritical = sum(1 for v in vulns.values() if v.get('severity') == 'critical')\nhigh = sum(1 for v in vulns.values() if v.get('severity') == 'high')\nmedium = sum(1 for v in vulns.values() if v.get('severity') == 'moderate')\nprint(f'Critical: {critical}, High: {high}, Medium: {medium}, Total: {len(vulns)}')\n\" 2>/dev/null || echo \"npm audit not available — use OSV API check instead\"\n```\n\n### Python / pip\n```bash\n# Install pip-audit if missing, then run:\npip show pip-audit > /dev/null 2>&1 || pip install pip-audit --quiet\npip-audit --format=json 2>/dev/null | python3 -c \"\nimport json, sys\nd = json.load(sys.stdin)\ndeps = d.get('dependencies', [])\ncritical = [v for dep in deps for v in dep.get('vulns', []) if v.get('severity', '').lower() == 'critical']\nhigh = [v for dep in deps for v in dep.get('vulns', []) if v.get('severity', '').lower() == 'high']\nprint(f'Critical: {len(critical)}, High: {len(high)}, Packages checked: {len(deps)}')\n\" 2>/dev/null || echo \"pip-audit not available — install: pip install pip-audit\"\n```\n\n### OSV.dev API (any ecosystem, no local tools required)\nFor each planned library, query the open vulnerability database:\n```bash\n# Replace LIBRARY_NAME and ECOSYSTEM (npm, PyPI, Go, crates.io, RubyGems, Maven, NuGet)\ncurl -s -X POST https://api.osv.dev/v1/query \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"package\":{\"name\":\"LIBRARY_NAME\",\"ecosystem\":\"npm\"}}' \\\n  | python3 -c \"\nimport json, sys\nd = json.load(sys.stdin)\nvulns = d.get('vulns', [])\nfor v in vulns:\n    sev = v.get('database_specific', {}).get('severity', 'unknown')\n    print(f\\\"{v['id']}: {sev} — {v.get('summary','')[:80]}\\\")\nif not vulns:\n    print('No known vulnerabilities')\n\"\n```\n\n### Maintenance check (GitHub API)\n```bash\n# For open-source libs, check recency of last commit:\n# Replace OWNER/REPO with the package source repository\ncurl -s \"https://api.github.com/repos/OWNER/REPO/commits?per_page=1\" \\\n  -H \"Accept: application/vnd.github.v3+json\" \\\n  | python3 -c \"\nimport json, sys\nfrom datetime import datetime, timezone\nd = json.load(sys.stdin)\nif d and isinstance(d, list):\n    date_str = d[0]['commit']['author']['date']\n    last = datetime.fromisoformat(date_str.replace('Z', '+00:00'))\n    age = (datetime.now(timezone.utc) - last).days\n    print(f'Last commit: {date_str} ({age} days ago)')\n    if age > 365:\n        print('WARNING: Unmaintained (>12 months without commits)')\n    if age > 730:\n        print('CRITICAL: Abandoned (>24 months without commits)')\nelse:\n    print('Could not fetch commit data')\n\"\n```\n\n### deps.dev API (Google — maintenance, licensing, advisories)\n```bash\n# For npm packages (URL-encode as needed)\nPKGNAME=\"express\"\ncurl -s \"https://api.deps.dev/v3alpha/packages/npm/${PKGNAME}\" \\\n  | python3 -c \"\nimport json, sys\nd = json.load(sys.stdin)\nprint('Advisories:', d.get('advisoryKeys', []))\nversions = d.get('versions', [])\nif versions:\n    latest = sorted(versions, key=lambda v: v.get('publishedAt',''), reverse=True)[0]\n    print('Latest version:', latest.get('versionKey', {}).get('version'))\n    print('Published:', latest.get('publishedAt'))\n\"\n```\n\n### Decision thresholds\n\n**Auto-BLOCK (agent cannot proceed without redesign):**\n- Critical CVE with no fix available\n- Package requires embedding credentials in source code\n- Package has no license in a licensed project\n- Package has 0 downloads and no commits in 24+ months (likely abandoned/typosquat)\n- Package name matches a known typosquat pattern (e.g., `reacts`, `lodahs`)\n\n**CONDITIONAL (user decision required, proceed with acknowledgment):**\n- High CVE with an available fix (fix it first, then downgrade to CERTIFIED)\n- Last commit 12-24 months ago\n- Package has <100 weekly downloads (bus factor risk)\n- Dependency chain is unusually deep (>15 levels for npm)\n\n**CERTIFIED (proceed):**\n- No critical or high CVEs\n- Last commit within 12 months\n- Active maintainer community\n- License is compatible with project\n\n---\n\n## PHASE 3: CERTIFY\n\nAfter running audits, generate `stay_safe.md` in the project root by calling:\n\n```bash\n./tools/stay-safe-gen.sh .vibesafe/summary.json\n# OR\npython3 ./tools/audit.py --generate-cert\n```\n\n**Certification rules:**\n\n| Audit Result | Certificate Status | Can proceed? |\n|---|---|---|\n| No critical/high CVEs, all maintained | CERTIFIED | Yes, immediately |\n| High CVE with available patch | CONDITIONAL | Yes, after user acknowledges |\n| Medium CVEs or unmaintained packages | CONDITIONAL | Yes, after user acknowledges |\n| Critical CVE with no fix | BLOCKED | No — redesign required |\n| Abandoned package (24+ months) | BLOCKED | No — replace package |\n\nWhen BLOCKED: go back to PHASE 1, replace the flagged library, re-run audit.\nMaximum 3 redesign iterations. After 3 failures: \"I cannot find a safe dependency for this purpose. Please advise.\"\n\n---\n\n## PHASE 4: CODE\n\nOnly after `stay_safe.md` shows CERTIFIED or CONDITIONAL (with explicit user approval in interactive mode):\n\n1. Implement the solution using ONLY audited libraries\n2. Apply secrets policy: all credentials via `process.env.X` or `os.environ[\"X\"]`\n3. Create `.env.example` with dummy/placeholder values for all required env vars\n4. Verify `.gitignore` covers `.env`, `.env.*`, `*.key`, `*.pem`, `secrets.*`, `credentials.*`, `.vibesafe/`\n5. If a new dependency is discovered mid-coding that was NOT in the Phase 1 plan:\n   - Stop\n   - Add the package to plan\n   - Run OSV API check for that package (minimum)\n   - Continue only if clean\n\n---\n\n## PHASE 5: POST-CODING REPORT (Autonomous mode)\n\nAfter coding is complete, run a final scan on actually-installed packages and produce `risk-report.md`:\n\n```bash\n./tools/audit.sh --mode=installed > .vibesafe/post-summary.json\n./tools/stay-safe-gen.sh .vibesafe/post-summary.json --template=risk-report\n```\n\nIf post-scan finds new critical/high CVEs (introduced by transitive dependencies during install),\nprepend this block to the final response:\n\n```\nWARNING — VibeSafe Post-Coding Scan Found New Issues\n=====================================================\nCritical CVEs found in installed packages: N\nHigh CVEs found in installed packages: N\nThese were not present in the pre-flight plan (likely transitive dependencies).\nSee risk-report.md for full details.\nAction required before deploying to production.\n```\n\n---\n\n## REDESIGN LOOP\n\n```\nBLOCKED package detected\n        |\n        v\nRemove from plan\n        |\n        v\nCheck \"Alternatives considered\" column from Phase 1\n        |\n        v\nEvaluate alternative with Phase 2 audit\n        |\n   _____|_____\n  |           |\nCLEAN      BLOCKED\n  |           |\nProceed    Attempt #2 alternative\n           If no more alternatives:\n           \"Can this feature be implemented without any external library?\"\n           If no: escalate to user\n```\n\n---\n\n## SKIP MECHANISM\n\nUser can type `/skip-audit` or `skip preflight` at any point in interactive mode.\n\nWhen skipped:\n- Log in stay_safe.md: `Status: USER-WAIVED — audit skipped by user at {ISO_TIMESTAMP}`\n- Continue coding normally\n- STILL run post-coding report (Phase 5) — skip does not disable ex-post scan\n- Note in final output: \"Security pre-flight was skipped. Run ./tools/audit.sh before production deploy.\"\n\n---\n\n## SECRETS POLICY — MANDATORY FOR ALL CODE WRITTEN\n\nThe agent MUST enforce these rules in every file it writes during Phase 4:\n\n| Rule | Implementation |\n|---|---|\n| No secrets in source | Never write API keys, passwords, tokens, connection strings in .js/.py/.ts/.go/.rs/.rb |\n| Use env vars | `process.env.MY_SECRET` (Node) / `os.environ[\"MY_SECRET\"]` (Python) / `os.Getenv(\"MY_SECRET\")` (Go) |\n| Document secrets | Always create `.env.example` with placeholder values |\n| Protect .env | Always ensure `.gitignore` includes `.env` and `.env.*` |\n| Recommend hooks | Suggest `detect-secrets` or `git-secrets` as pre-commit hook |\n\n---\n\n## AGENT INVOCATION REFERENCE\n\n| Agent | How to invoke |\n|---|---|\n| Claude Code | `Skill(\"vibe-safe\")` or prefix task: \"Run vibe-safe pre-flight first\" |\n| Kimi CLI / Hermes | Read this file from known path, execute phases via tool calls |\n| OpenClaw (port 18789) | Configure webhook trigger on package install pattern |\n| VS Code Continue/Copilot | Run \"VibeSafe: Audit Project\" task from `.vscode/tasks.json` |\n| CI/CD | `.github/workflows/security-gate.yml` on push/PR |\n\n---\n\n## QUICK REFERENCE\n\n```\n/vibe-safe          — run full pre-flight (interactive)\n/vibe-safe skip     — skip to coding, run post-scan only\n/vibe-safe report   — run phase 5 post-scan on current project\n/vibe-safe cert     — show current stay_safe.md status\n```\n\n## SCOPE — WHAT VIBESAFE DOES NOT DO\n\n- VibeSafe does not run SAST on your own code (use Semgrep, CodeQL, Bandit)\n- VibeSafe does not scan container images (use Trivy, Grype)\n- VibeSafe does not manage secret rotation (use Vault, AWS Secrets Manager)\n- VibeSafe audits external dependencies only — not your business logic\n","tags":{"audit":"1.1.0","auto-fix":"1.1.0","cve":"1.1.0","dashboard":"1.1.0","explain":"1.1.0","latest":"1.1.0","safety":"1.1.0","security":"1.1.0","vibe-coding":"1.1.0"},"stats":{"comments":0,"downloads":353,"installsAllTime":0,"installsCurrent":0,"stars":0,"versions":3},"createdAt":1778026478470,"updatedAt":1778492854429},"latestVersion":{"version":"1.1.0","createdAt":1778052353005,"changelog":"No changes detected for version 1.1.0.\n\n- No file changes were made in this version.\n- Functionality and documentation remain the same as the previous release.","license":"MIT-0"},"metadata":null,"owner":{"handle":"nerua1","userId":"s178f4bnw35dnxc3ymhvgf114983yzer","displayName":"nerua1","image":"https://avatars.githubusercontent.com/u/271220546?v=4"},"moderation":null}