Skip to content
SlashClone
Made by@shipcheck

Env secrets check

@shipcheck/env-secrets-check

Check your repo for leaked secrets before you push or launch: .env files git tracks or will pick up, .env files hiding in git history, server keys behind NEXT_PUBLIC_ or VITE_ prefixes that ship to the browser, provider key shapes (Stripe, AWS, GitHub, OpenAI, Anthropic, Supabase service_role), and passwords hardcoded in code. Reports names and redacted hints, never the values.

SkillDevOpsv1.0.0 (latest)Tested
Activity
New: be the first to try it
  1. 1{
  2. 2 "name": "env-secrets-check",
  3. 3 "owner": "shipcheck",
  4. 4 "version": "1.0.0",
  5. 5 "type": "skill",
  6. 6 "description": "Check your repo for leaked secrets before you push or launch: .env files git tracks or will pick up, .env files hiding in git history, server keys behind NEXT_PUBLIC_ or VITE_ prefixes that ship to the browser, provider key shapes (Stripe, AWS, GitHub, OpenAI, Anthropic, Supabase service_role), and passwords hardcoded in code. Reports names and redacted hints, never the values.",
  7. 7 "category": "devops",
  8. 8 "license": "MIT",
  9. 9 "compat": ["claude-code"],
  10. 10 "permissions": {
  11. 11 "shell": ["node scripts/secrets-scan.mjs", "git ls-files", "git log"],
  12. 12 "files": {
  13. 13 "read": ["./**"],
  14. 14 "write": ["./out/**", "./.gitignore"]
  15. 15 }
  16. 16 },
  17. 17 "tests": {
  18. 18 "cases": [
  19. 19 {
  20. 20 "name": "flags an unignored env file, a public service role key, and hardcoded secrets without printing values",
  21. 21 "inputs": {
  22. 22 "project/.env.local": "NEXT_PUBLIC_SUPABASE_URL=http://localhost:54321\nNEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY=replace-me\nSTRIPE_SECRET_KEY=fake-local-value-1234\n",
  23. 23 "project/app/api/pay.ts": "const stripeKey = \"sk_test_0000FAKE0000FAKE0000FAKE00\";\nexport const adminPassword = \"letmein-2026\";\nexport const url = process.env.NEXT_PUBLIC_SUPABASE_URL;\n"
  24. 24 },
  25. 25 "checks": [
  26. 26 {
  27. 27 "type": "command_exits_zero",
  28. 28 "command": "node scripts/secrets-scan.mjs project --json out/secrets-report.json --md out/secrets-report.md"
  29. 29 },
  30. 30 {
  31. 31 "type": "output_matches_schema",
  32. 32 "path": "out/secrets-report.json",
  33. 33 "schema": {
  34. 34 "type": "object",
  35. 35 "required": ["summary", "findings"],
  36. 36 "properties": {
  37. 37 "summary": {
  38. 38 "type": "object",
  39. 39 "properties": {
  40. 40 "high": { "const": 2 },
  41. 41 "medium": { "const": 3 },
  42. 42 "low": { "const": 1 }
  43. 43 }
  44. 44 }
  45. 45 }
  46. 46 }
  47. 47 },
  48. 48 { "type": "file_contains", "path": "out/secrets-report.md", "text": "env-file-not-ignored" },
  49. 49 { "type": "file_contains", "path": "out/secrets-report.md", "text": "NEXT_PUBLIC_SUPABASE_SERVICE_ROLE_KEY is bundled into the browser" },
  50. 50 { "type": "file_contains", "path": "out/secrets-report.md", "text": "stripe-test-key" },
  51. 51 { "type": "file_not_contains", "path": "out/secrets-report.md", "text": "letmein-2026" },
  52. 52 { "type": "file_not_contains", "path": "out/secrets-report.json", "text": "fake-local-value-1234" }
  53. 53 ]
  54. 54 },
  55. 55 {
  56. 56 "name": "a project with ignored env files and an empty template is clean",
  57. 57 "inputs": {
  58. 58 "project/.gitignore": "node_modules\n.env*\n!.env.example\n",
  59. 59 "project/.env.local": "SUPABASE_SERVICE_ROLE_KEY=local-only-value-123\nNEXT_PUBLIC_SUPABASE_ANON_KEY=anon-placeholder\n",
  60. 60 "project/.env.example": "SUPABASE_SERVICE_ROLE_KEY=\nNEXT_PUBLIC_SUPABASE_ANON_KEY=\n",
  61. 61 "project/lib/db.ts": "export const serviceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;\n"
  62. 62 },
  63. 63 "checks": [
  64. 64 {
  65. 65 "type": "command_exits_zero",
  66. 66 "command": "node scripts/secrets-scan.mjs project --json out/secrets-report.json --md out/secrets-report.md"
  67. 67 },
  68. 68 {
  69. 69 "type": "output_matches_schema",
  70. 70 "path": "out/secrets-report.json",
  71. 71 "schema": {
  72. 72 "type": "object",
  73. 73 "properties": {
  74. 74 "summary": {
  75. 75 "type": "object",
  76. 76 "properties": {
  77. 77 "high": { "const": 0 },
  78. 78 "medium": { "const": 0 },
  79. 79 "low": { "const": 0 }
  80. 80 }
  81. 81 }
  82. 82 }
  83. 83 }
  84. 84 },
  85. 85 { "type": "file_not_contains", "path": "out/secrets-report.md", "text": "local-only-value-123" }
  86. 86 ]
  87. 87 }
  88. 88 ]
  89. 89 }