shipwright-cli 1.10.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +114 -36
  2. package/completions/_shipwright +212 -32
  3. package/completions/shipwright.bash +97 -25
  4. package/docs/strategy/01-market-research.md +619 -0
  5. package/docs/strategy/02-mission-and-brand.md +587 -0
  6. package/docs/strategy/03-gtm-and-roadmap.md +759 -0
  7. package/docs/strategy/QUICK-START.txt +289 -0
  8. package/docs/strategy/README.md +172 -0
  9. package/package.json +4 -2
  10. package/scripts/sw +208 -1
  11. package/scripts/sw-activity.sh +500 -0
  12. package/scripts/sw-adaptive.sh +925 -0
  13. package/scripts/sw-adversarial.sh +1 -1
  14. package/scripts/sw-architecture-enforcer.sh +1 -1
  15. package/scripts/sw-auth.sh +613 -0
  16. package/scripts/sw-autonomous.sh +664 -0
  17. package/scripts/sw-changelog.sh +704 -0
  18. package/scripts/sw-checkpoint.sh +1 -1
  19. package/scripts/sw-ci.sh +602 -0
  20. package/scripts/sw-cleanup.sh +1 -1
  21. package/scripts/sw-code-review.sh +637 -0
  22. package/scripts/sw-connect.sh +1 -1
  23. package/scripts/sw-context.sh +605 -0
  24. package/scripts/sw-cost.sh +1 -1
  25. package/scripts/sw-daemon.sh +432 -130
  26. package/scripts/sw-dashboard.sh +1 -1
  27. package/scripts/sw-db.sh +540 -0
  28. package/scripts/sw-decompose.sh +539 -0
  29. package/scripts/sw-deps.sh +551 -0
  30. package/scripts/sw-developer-simulation.sh +1 -1
  31. package/scripts/sw-discovery.sh +412 -0
  32. package/scripts/sw-docs-agent.sh +539 -0
  33. package/scripts/sw-docs.sh +1 -1
  34. package/scripts/sw-doctor.sh +59 -1
  35. package/scripts/sw-dora.sh +615 -0
  36. package/scripts/sw-durable.sh +710 -0
  37. package/scripts/sw-e2e-orchestrator.sh +535 -0
  38. package/scripts/sw-eventbus.sh +393 -0
  39. package/scripts/sw-feedback.sh +471 -0
  40. package/scripts/sw-fix.sh +1 -1
  41. package/scripts/sw-fleet-discover.sh +567 -0
  42. package/scripts/sw-fleet-viz.sh +404 -0
  43. package/scripts/sw-fleet.sh +8 -1
  44. package/scripts/sw-github-app.sh +596 -0
  45. package/scripts/sw-github-checks.sh +1 -1
  46. package/scripts/sw-github-deploy.sh +1 -1
  47. package/scripts/sw-github-graphql.sh +1 -1
  48. package/scripts/sw-guild.sh +569 -0
  49. package/scripts/sw-heartbeat.sh +1 -1
  50. package/scripts/sw-hygiene.sh +559 -0
  51. package/scripts/sw-incident.sh +617 -0
  52. package/scripts/sw-init.sh +88 -1
  53. package/scripts/sw-instrument.sh +699 -0
  54. package/scripts/sw-intelligence.sh +1 -1
  55. package/scripts/sw-jira.sh +1 -1
  56. package/scripts/sw-launchd.sh +363 -28
  57. package/scripts/sw-linear.sh +1 -1
  58. package/scripts/sw-logs.sh +1 -1
  59. package/scripts/sw-loop.sh +64 -3
  60. package/scripts/sw-memory.sh +1 -1
  61. package/scripts/sw-mission-control.sh +487 -0
  62. package/scripts/sw-model-router.sh +545 -0
  63. package/scripts/sw-otel.sh +596 -0
  64. package/scripts/sw-oversight.sh +689 -0
  65. package/scripts/sw-pipeline-composer.sh +1 -1
  66. package/scripts/sw-pipeline-vitals.sh +1 -1
  67. package/scripts/sw-pipeline.sh +687 -24
  68. package/scripts/sw-pm.sh +693 -0
  69. package/scripts/sw-pr-lifecycle.sh +522 -0
  70. package/scripts/sw-predictive.sh +1 -1
  71. package/scripts/sw-prep.sh +1 -1
  72. package/scripts/sw-ps.sh +1 -1
  73. package/scripts/sw-public-dashboard.sh +798 -0
  74. package/scripts/sw-quality.sh +595 -0
  75. package/scripts/sw-reaper.sh +1 -1
  76. package/scripts/sw-recruit.sh +573 -0
  77. package/scripts/sw-regression.sh +642 -0
  78. package/scripts/sw-release-manager.sh +736 -0
  79. package/scripts/sw-release.sh +706 -0
  80. package/scripts/sw-remote.sh +1 -1
  81. package/scripts/sw-replay.sh +520 -0
  82. package/scripts/sw-retro.sh +691 -0
  83. package/scripts/sw-scale.sh +444 -0
  84. package/scripts/sw-security-audit.sh +505 -0
  85. package/scripts/sw-self-optimize.sh +1 -1
  86. package/scripts/sw-session.sh +1 -1
  87. package/scripts/sw-setup.sh +1 -1
  88. package/scripts/sw-standup.sh +712 -0
  89. package/scripts/sw-status.sh +1 -1
  90. package/scripts/sw-strategic.sh +658 -0
  91. package/scripts/sw-stream.sh +450 -0
  92. package/scripts/sw-swarm.sh +583 -0
  93. package/scripts/sw-team-stages.sh +511 -0
  94. package/scripts/sw-templates.sh +1 -1
  95. package/scripts/sw-testgen.sh +515 -0
  96. package/scripts/sw-tmux-pipeline.sh +554 -0
  97. package/scripts/sw-tmux.sh +1 -1
  98. package/scripts/sw-trace.sh +485 -0
  99. package/scripts/sw-tracker-github.sh +188 -0
  100. package/scripts/sw-tracker-jira.sh +172 -0
  101. package/scripts/sw-tracker-linear.sh +251 -0
  102. package/scripts/sw-tracker.sh +117 -2
  103. package/scripts/sw-triage.sh +603 -0
  104. package/scripts/sw-upgrade.sh +1 -1
  105. package/scripts/sw-ux.sh +677 -0
  106. package/scripts/sw-webhook.sh +627 -0
  107. package/scripts/sw-widgets.sh +530 -0
  108. package/scripts/sw-worktree.sh +1 -1
@@ -0,0 +1,505 @@
1
+ #!/usr/bin/env bash
2
+ # ╔═══════════════════════════════════════════════════════════════════════════╗
3
+ # ║ shipwright security-audit — Comprehensive Security Auditing ║
4
+ # ║ Secret detection · License checking · Vulnerability scanning · SBOM ║
5
+ # ╚═══════════════════════════════════════════════════════════════════════════╝
6
+ set -euo pipefail
7
+ trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
+
9
+ VERSION="2.0.0"
10
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
+ REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
+
13
+ # ─── Colors (matches Seth's tmux theme) ─────────────────────────────────────
14
+ CYAN='\033[38;2;0;212;255m' # #00d4ff — primary accent
15
+ PURPLE='\033[38;2;124;58;237m' # #7c3aed — secondary
16
+ BLUE='\033[38;2;0;102;255m' # #0066ff — tertiary
17
+ GREEN='\033[38;2;74;222;128m' # success
18
+ YELLOW='\033[38;2;250;204;21m' # warning
19
+ RED='\033[38;2;248;113;113m' # error
20
+ DIM='\033[2m'
21
+ BOLD='\033[1m'
22
+ RESET='\033[0m'
23
+
24
+ # ─── Cross-platform compatibility ──────────────────────────────────────────
25
+ # shellcheck source=lib/compat.sh
26
+ [[ -f "$SCRIPT_DIR/lib/compat.sh" ]] && source "$SCRIPT_DIR/lib/compat.sh"
27
+
28
+ # ─── Output Helpers ─────────────────────────────────────────────────────────
29
+ info() { echo -e "${CYAN}${BOLD}▸${RESET} $*"; }
30
+ success() { echo -e "${GREEN}${BOLD}✓${RESET} $*"; }
31
+ warn() { echo -e "${YELLOW}${BOLD}⚠${RESET} $*"; }
32
+ error() { echo -e "${RED}${BOLD}✗${RESET} $*" >&2; }
33
+
34
+ now_iso() { date -u +"%Y-%m-%dT%H:%M:%SZ"; }
35
+
36
+ # ─── Audit State ───────────────────────────────────────────────────────────
37
+ FINDINGS=()
38
+ CRITICAL_COUNT=0
39
+ HIGH_COUNT=0
40
+ MEDIUM_COUNT=0
41
+ LOW_COUNT=0
42
+
43
+ # Append finding with priority
44
+ add_finding() {
45
+ local priority="$1" # CRITICAL, HIGH, MEDIUM, LOW
46
+ local category="$2" # secrets, licenses, vulnerabilities, permissions, network, compliance
47
+ local title="$3"
48
+ local description="$4"
49
+ local remediation="$5"
50
+
51
+ local color=""
52
+ case "$priority" in
53
+ CRITICAL) color="$RED"; ((CRITICAL_COUNT++)) ;;
54
+ HIGH) color="$RED"; ((HIGH_COUNT++)) ;;
55
+ MEDIUM) color="$YELLOW"; ((MEDIUM_COUNT++)) ;;
56
+ LOW) color="$BLUE"; ((LOW_COUNT++)) ;;
57
+ esac
58
+
59
+ FINDINGS+=("${priority}|${category}|${title}|${description}|${remediation}")
60
+ }
61
+
62
+ # ─── Secret Detection ───────────────────────────────────────────────────────
63
+
64
+ scan_secrets() {
65
+ info "Scanning for hardcoded secrets..."
66
+
67
+ local patterns=(
68
+ "AKIA[0-9A-Z]{16}" # AWS Access Key ID
69
+ "aws_secret_access_key\s*=\s*['\"]?[^\s'\"]*['\"]?" # AWS Secret
70
+ "password\s*[=:]\s*['\"]?[^\s'\"]*['\"]?" # Generic password
71
+ "api[_-]?key\s*[=:]\s*['\"]?[^\s'\"]*['\"]?" # API key
72
+ "token\s*[=:]\s*['\"]?[^\s'\"]*['\"]?" # Generic token
73
+ "gh_[a-zA-Z0-9_]{36}" # GitHub token
74
+ "-----BEGIN RSA PRIVATE KEY-----" # RSA private key
75
+ "-----BEGIN PRIVATE KEY-----" # Generic private key
76
+ "PRIVATE KEY" # Private key marker
77
+ "AUTH_TOKEN" # Auth token
78
+ "oauth_token\s*[=:]" # OAuth token
79
+ "x-api-key\s*[=:]" # API key header
80
+ )
81
+
82
+ local secret_files=()
83
+ while IFS= read -r file; do
84
+ [[ -z "$file" ]] && continue
85
+ for pattern in "${patterns[@]}"; do
86
+ if grep -qEi "$pattern" "$file" 2>/dev/null; then
87
+ secret_files+=("$file")
88
+ break
89
+ fi
90
+ done
91
+ done < <(find "$REPO_DIR" -type f \( -name "*.sh" -o -name "*.py" -o -name "*.js" -o -name "*.json" -o -name ".env*" -o -name "*.yaml" -o -name "*.yml" \) 2>/dev/null | grep -v ".git\|node_modules\|.worktree" || true)
92
+
93
+ if [[ ${#secret_files[@]} -gt 0 ]]; then
94
+ for file in "${secret_files[@]}"; do
95
+ add_finding "CRITICAL" "secrets" "Potential hardcoded secret in $file" \
96
+ "Found patterns matching secret formats (AWS keys, API keys, tokens, private keys)" \
97
+ "Rotate credentials immediately. Remove secrets from version control. Use environment variables or secret management system instead. Use git-secrets or pre-commit hooks to prevent future leaks."
98
+ done
99
+ fi
100
+
101
+ # Check for .env files in git
102
+ if find "$REPO_DIR" -name ".env" -type f ! -path "*/.git/*" ! -path "*/.worktree/*" 2>/dev/null | grep -q .; then
103
+ add_finding "HIGH" "secrets" ".env file in repository" \
104
+ ".env files containing secrets should never be committed to version control" \
105
+ "Add .env to .gitignore. Use .env.example template instead. Document required variables in README."
106
+ fi
107
+
108
+ local secret_count=${#secret_files[@]}
109
+ [[ $secret_count -eq 0 ]] && success "No obvious hardcoded secrets detected" || warn "Found $secret_count files with potential secrets"
110
+ }
111
+
112
+ # ─── License Compliance ─────────────────────────────────────────────────────
113
+
114
+ scan_licenses() {
115
+ info "Scanning for license compliance..."
116
+
117
+ # Detect package manager
118
+ local has_npm=false has_pip=false has_go=false has_cargo=false
119
+
120
+ [[ -f "$REPO_DIR/package.json" ]] && has_npm=true
121
+ [[ -f "$REPO_DIR/requirements.txt" || -f "$REPO_DIR/setup.py" ]] && has_pip=true
122
+ [[ -f "$REPO_DIR/go.mod" ]] && has_go=true
123
+ [[ -f "$REPO_DIR/Cargo.toml" ]] && has_cargo=true
124
+
125
+ # Check npm licenses
126
+ if $has_npm && command -v npm &>/dev/null; then
127
+ while IFS= read -r line; do
128
+ [[ "$line" =~ GPL|AGPL ]] && [[ ! "$line" =~ MIT|Apache|BSD ]] && \
129
+ add_finding "MEDIUM" "licenses" "GPL/AGPL dependency in npm project" \
130
+ "Found GPL/AGPL licensed package: $line" \
131
+ "Review license compatibility. Consider alternatives with permissive licenses. Document GPL/AGPL usage."
132
+ done < <(npm list --depth=0 2>/dev/null | grep -i "gpl\|agpl" || true)
133
+ fi
134
+
135
+ # Check for LICENSES directory
136
+ if [[ ! -d "$REPO_DIR/LICENSES" ]]; then
137
+ add_finding "LOW" "licenses" "Missing LICENSES directory" \
138
+ "No LICENSES directory found for SPDX/license documentation" \
139
+ "Create LICENSES/ directory. Document all third-party licenses used. Generate with license scanner tools."
140
+ fi
141
+
142
+ # Detect MIT project using GPL
143
+ if [[ -f "$REPO_DIR/LICENSE" ]]; then
144
+ if grep -qi "MIT\|Apache" "$REPO_DIR/LICENSE" 2>/dev/null; then
145
+ # MIT/Apache project — flag GPL dependencies
146
+ while IFS= read -r line; do
147
+ [[ "$line" =~ GPL|AGPL ]] && \
148
+ add_finding "HIGH" "licenses" "GPL/AGPL in permissive project" \
149
+ "MIT/Apache project using GPL/AGPL dependency: $line" \
150
+ "Replace GPL dependencies with permissive alternatives. Update LICENSE file if needed."
151
+ done < <(npm list 2>/dev/null | grep -i "gpl\|agpl" || true)
152
+ fi
153
+ fi
154
+
155
+ success "License compliance check complete"
156
+ }
157
+
158
+ # ─── Vulnerability Scanning ────────────────────────────────────────────────
159
+
160
+ scan_vulnerabilities() {
161
+ info "Scanning for known vulnerabilities..."
162
+
163
+ local vuln_count=0
164
+
165
+ # Check npm vulnerabilities
166
+ if [[ -f "$REPO_DIR/package.json" ]] && command -v npm &>/dev/null; then
167
+ while IFS= read -r line; do
168
+ [[ -z "$line" ]] && continue
169
+ ((vuln_count++))
170
+ add_finding "HIGH" "vulnerabilities" "npm security vulnerability" \
171
+ "Found npm audit issue: $line" \
172
+ "Run 'npm audit fix' to remediate. Update vulnerable dependencies. Re-test after updates."
173
+ done < <(npm audit 2>/dev/null | grep -i "vulnerability\|found" || true)
174
+ fi
175
+
176
+ # Check pip vulnerabilities
177
+ if [[ -f "$REPO_DIR/requirements.txt" ]] && command -v pip &>/dev/null; then
178
+ if command -v safety &>/dev/null; then
179
+ while IFS= read -r line; do
180
+ [[ -z "$line" ]] && continue
181
+ ((vuln_count++))
182
+ add_finding "HIGH" "vulnerabilities" "Python package vulnerability" \
183
+ "Found via safety: $line" \
184
+ "Update vulnerable package. Test compatibility. Run safety check after updates."
185
+ done < <(safety check 2>/dev/null || true)
186
+ fi
187
+ fi
188
+
189
+ [[ $vuln_count -eq 0 ]] && success "No known vulnerabilities detected" || warn "Found $vuln_count vulnerabilities"
190
+ }
191
+
192
+ # ─── SBOM Generation ───────────────────────────────────────────────────────
193
+
194
+ generate_sbom() {
195
+ info "Generating Software Bill of Materials..."
196
+
197
+ local sbom_file="${REPO_DIR}/.claude/pipeline-artifacts/sbom.json"
198
+ mkdir -p "$(dirname "$sbom_file")"
199
+
200
+ local sbom='{"bomFormat":"CycloneDX","specVersion":"1.4","version":1,"components":[]}'
201
+
202
+ # Add npm packages
203
+ if [[ -f "$REPO_DIR/package.json" ]] && command -v npm &>/dev/null; then
204
+ local npm_list
205
+ npm_list=$(npm list --json 2>/dev/null || echo '{"dependencies":{}}')
206
+ while IFS='=' read -r name version; do
207
+ [[ -z "$name" || -z "$version" ]] && continue
208
+ sbom=$(echo "$sbom" | jq --arg n "$name" --arg v "$version" \
209
+ '.components += [{"type":"library","name":$n,"version":$v,"purl":"pkg:npm/\($n)@\($v)"}]')
210
+ done < <(npm list --depth=0 --json 2>/dev/null | jq -r '.dependencies | to_entries[] | "\(.key)=\(.value.version)"' || true)
211
+ fi
212
+
213
+ # Add git commit info
214
+ local commit=""
215
+ [[ -d "$REPO_DIR/.git" ]] && commit=$(cd "$REPO_DIR" && git rev-parse HEAD 2>/dev/null || echo "unknown")
216
+ sbom=$(echo "$sbom" | jq --arg c "$commit" '.metadata.component.commit = $c')
217
+
218
+ # Write SBOM
219
+ echo "$sbom" | jq . > "$sbom_file" 2>/dev/null || true
220
+
221
+ success "SBOM generated: $sbom_file"
222
+ }
223
+
224
+ # ─── Permissions Audit ──────────────────────────────────────────────────────
225
+
226
+ audit_permissions() {
227
+ info "Auditing file permissions..."
228
+
229
+ # Check for world-writable files
230
+ while IFS= read -r file; do
231
+ [[ -z "$file" ]] && continue
232
+ add_finding "MEDIUM" "permissions" "World-writable file: $file" \
233
+ "File has overly permissive permissions (mode ending in 2 or 7)" \
234
+ "Run: chmod o-w \"$file\" to remove world-writable bit"
235
+ done < <(find "$REPO_DIR" -type f -perm -002 ! -path "*/.git/*" ! -path "*/.worktree/*" 2>/dev/null || true)
236
+
237
+ # Check for setuid/setgid binaries
238
+ while IFS= read -r file; do
239
+ [[ -z "$file" ]] && continue
240
+ add_finding "HIGH" "permissions" "setuid/setgid binary: $file" \
241
+ "Binary has setuid or setgid bit set" \
242
+ "Review necessity. Remove if not essential. Audit access controls."
243
+ done < <(find "$REPO_DIR" -type f \( -perm -4000 -o -perm -2000 \) ! -path "*/.git/*" 2>/dev/null || true)
244
+
245
+ # Check for readable private keys
246
+ while IFS= read -r file; do
247
+ [[ -z "$file" ]] && continue
248
+ add_finding "CRITICAL" "permissions" "Readable private key: $file" \
249
+ "Private key file has permissive read permissions" \
250
+ "Run: chmod 600 \"$file\" immediately. Rotate the key. Audit access logs."
251
+ done < <(find "$REPO_DIR" -type f \( -name "*.pem" -o -name "*.key" -o -name "id_rsa" \) ! -path "*/.git/*" 2>/dev/null | while read -r f; do
252
+ [[ $(stat -f%A "$f" 2>/dev/null || stat -c%a "$f" 2>/dev/null) =~ [^0].. ]] && echo "$f"
253
+ done || true)
254
+
255
+ success "Permissions audit complete"
256
+ }
257
+
258
+ # ─── Network Exposure Analysis ─────────────────────────────────────────────
259
+
260
+ analyze_network() {
261
+ info "Analyzing network exposure..."
262
+
263
+ local urls_found=()
264
+
265
+ # Find external network calls
266
+ while IFS= read -r line; do
267
+ [[ -z "$line" ]] && continue
268
+ if [[ "$line" =~ http://|https://|curl|wget ]]; then
269
+ urls_found+=("$line")
270
+ fi
271
+ done < <(grep -r "http\|curl\|wget\|socket\|fetch\|request" "$REPO_DIR/scripts/" "$REPO_DIR/src/" 2>/dev/null | grep -v ".git\|.worktree\|Binary" || true)
272
+
273
+ if [[ ${#urls_found[@]} -gt 0 ]]; then
274
+ info "Found ${#urls_found[@]} network-related operations"
275
+ for line in "${urls_found[@]}"; do
276
+ warn " $line"
277
+ done
278
+
279
+ add_finding "MEDIUM" "network" "External network calls detected" \
280
+ "Script makes external API/network calls. Found ${#urls_found[@]} references." \
281
+ "Audit all network calls. Ensure TLS/HTTPS. Validate certificates. Log network activity."
282
+ fi
283
+
284
+ success "Network exposure analysis complete"
285
+ }
286
+
287
+ # ─── Compliance Report ──────────────────────────────────────────────────────
288
+
289
+ generate_compliance_report() {
290
+ info "Generating compliance report..."
291
+
292
+ local report_file="${REPO_DIR}/.claude/pipeline-artifacts/security-compliance-report.md"
293
+ mkdir -p "$(dirname "$report_file")"
294
+
295
+ cat > "$report_file" <<'EOF'
296
+ # Security Compliance Report
297
+
298
+ ## SOC2 Checklist
299
+
300
+ ### CC (Common Criteria)
301
+ - [ ] CC1: Risk Assessment completed
302
+ - [ ] CC2: Management objectives and responsibilities defined
303
+ - [ ] CC3: Communication of objectives and responsibilities
304
+ - [ ] CC4: Information security culture established
305
+ - [ ] CC5: Roles and responsibilities assigned
306
+ - [ ] CC6: Segregation of duties enforced
307
+ - [ ] CC7: Human resources policies and procedures
308
+ - [ ] CC8: Competence of personnel
309
+ - [ ] CC9: Accountability assigned
310
+
311
+ ### C (Criteria)
312
+ - [ ] C1.1: Authorization and access controls
313
+ - [ ] C1.2: Change management procedures
314
+ - [ ] C2.1: System monitoring
315
+ - [ ] C2.2: Monitoring of systems and applications
316
+ - [ ] C3.1: Logical access controls
317
+ - [ ] C3.2: Physical access controls
318
+ - [ ] C4.1: Risk assessment documentation
319
+ - [ ] C5.1: Incident identification and reporting
320
+ - [ ] C6.1: Vulnerability identification and remediation
321
+ - [ ] C7.1: Availability and performance monitoring
322
+
323
+ ## ISO 27001 Controls
324
+
325
+ ### A.5 - Organizational Controls
326
+ - [ ] A.5.1: Management commitment to security
327
+ - [ ] A.5.2: Security policy established
328
+ - [ ] A.5.3: Allocation of information security responsibilities
329
+
330
+ ### A.6 - Personnel Controls
331
+ - [ ] A.6.1: Confidentiality or non-disclosure agreements
332
+ - [ ] A.6.2: Information security awareness training
333
+ - [ ] A.6.3: Procedures for third-party access
334
+
335
+ ### A.7 - Physical and Environmental Controls
336
+ - [ ] A.7.1: Perimeter security
337
+ - [ ] A.7.2: Entry controls
338
+ - [ ] A.7.3: Workspace security
339
+
340
+ ### A.8 - Technical Controls
341
+ - [ ] A.8.1: Access control policies
342
+ - [ ] A.8.2: Cryptography usage
343
+ - [ ] A.8.3: Malware protection
344
+
345
+ ## GDPR Compliance
346
+
347
+ - [ ] Data inventory completed
348
+ - [ ] Data processing agreements in place
349
+ - [ ] Data subject rights procedures
350
+ - [ ] Data breach notification plan
351
+ - [ ] Privacy by design implemented
352
+ - [ ] Data retention policy defined
353
+
354
+ ## Findings Summary
355
+
356
+ | Priority | Count |
357
+ |----------|-------|
358
+ | CRITICAL | 0 |
359
+ | HIGH | 0 |
360
+ | MEDIUM | 0 |
361
+ | LOW | 0 |
362
+
363
+ EOF
364
+
365
+ success "Compliance report generated: $report_file"
366
+ }
367
+
368
+ # ─── Unified Full Scan ──────────────────────────────────────────────────────
369
+
370
+ run_full_scan() {
371
+ echo ""
372
+ echo -e "${CYAN}${BOLD}╔═════════════════════════════════════════════════════════════╗${RESET}"
373
+ echo -e "${CYAN}${BOLD}║ SHIPWRIGHT SECURITY AUDIT${RESET}"
374
+ echo -e "${CYAN}${BOLD}║ Repo: $(basename "$REPO_DIR")${RESET}"
375
+ echo -e "${CYAN}${BOLD}╚═════════════════════════════════════════════════════════════╝${RESET}"
376
+ echo ""
377
+
378
+ scan_secrets
379
+ echo ""
380
+ scan_licenses
381
+ echo ""
382
+ scan_vulnerabilities
383
+ echo ""
384
+ generate_sbom
385
+ echo ""
386
+ audit_permissions
387
+ echo ""
388
+ analyze_network
389
+ echo ""
390
+ generate_compliance_report
391
+ echo ""
392
+
393
+ # Print findings summary
394
+ print_findings_summary
395
+ }
396
+
397
+ # ─── Print Findings ────────────────────────────────────────────────────────
398
+
399
+ print_findings_summary() {
400
+ echo -e "${CYAN}${BOLD}╔═════════════════════════════════════════════════════════════╗${RESET}"
401
+ echo -e "${CYAN}${BOLD}║ FINDINGS SUMMARY${RESET}"
402
+ echo -e "${CYAN}${BOLD}╚═════════════════════════════════════════════════════════════╝${RESET}"
403
+ echo ""
404
+
405
+ echo -e " ${RED}${BOLD}CRITICAL:${RESET} $CRITICAL_COUNT"
406
+ echo -e " ${RED}${BOLD}HIGH:${RESET} $HIGH_COUNT"
407
+ echo -e " ${YELLOW}${BOLD}MEDIUM:${RESET} $MEDIUM_COUNT"
408
+ echo -e " ${BLUE}${BOLD}LOW:${RESET} $LOW_COUNT"
409
+ echo ""
410
+
411
+ if [[ ${#FINDINGS[@]} -eq 0 ]]; then
412
+ success "No security findings detected!"
413
+ return 0
414
+ fi
415
+
416
+ # Sort and display findings
417
+ for finding in "${FINDINGS[@]}"; do
418
+ IFS='|' read -r priority category title description remediation <<< "$finding"
419
+
420
+ local color=""
421
+ case "$priority" in
422
+ CRITICAL) color="$RED" ;;
423
+ HIGH) color="$RED" ;;
424
+ MEDIUM) color="$YELLOW" ;;
425
+ LOW) color="$BLUE" ;;
426
+ esac
427
+
428
+ echo -e "${color}${BOLD}[$priority]${RESET} $title"
429
+ echo -e " ${DIM}Category: $category${RESET}"
430
+ echo -e " ${DIM}Issue: $description${RESET}"
431
+ echo -e " ${GREEN}Remediation: $remediation${RESET}"
432
+ echo ""
433
+ done
434
+ }
435
+
436
+ # ─── Help ───────────────────────────────────────────────────────────────────
437
+
438
+ show_help() {
439
+ echo -e "${CYAN}${BOLD}shipwright security-audit${RESET} ${DIM}v${VERSION}${RESET} — Comprehensive Security Auditing"
440
+ echo ""
441
+ echo -e "${BOLD}USAGE${RESET}"
442
+ echo -e " ${CYAN}shipwright security-audit${RESET} [command]"
443
+ echo ""
444
+ echo -e "${BOLD}COMMANDS${RESET}"
445
+ echo -e " ${CYAN}scan${RESET} Full security scan (all checks)"
446
+ echo -e " ${CYAN}secrets${RESET} Secret detection scan"
447
+ echo -e " ${CYAN}licenses${RESET} License compliance check"
448
+ echo -e " ${CYAN}vulnerabilities${RESET} Vulnerability scan"
449
+ echo -e " ${CYAN}sbom${RESET} Generate Software Bill of Materials"
450
+ echo -e " ${CYAN}permissions${RESET} File permissions audit"
451
+ echo -e " ${CYAN}network${RESET} Network exposure analysis"
452
+ echo -e " ${CYAN}report${RESET} Generate compliance report"
453
+ echo -e " ${CYAN}help${RESET} Show this help message"
454
+ echo ""
455
+ echo -e "${BOLD}EXAMPLES${RESET}"
456
+ echo -e " ${DIM}shipwright security-audit scan${RESET}"
457
+ echo -e " ${DIM}shipwright security-audit secrets${RESET}"
458
+ echo -e " ${DIM}shipwright security-audit licenses --json${RESET}"
459
+ }
460
+
461
+ # ─── Source Guard ──────────────────────────────────────────────────────────
462
+
463
+ if [[ "${BASH_SOURCE[0]}" == "$0" ]]; then
464
+ cmd="${1:-help}"
465
+
466
+ case "$cmd" in
467
+ scan)
468
+ run_full_scan
469
+ ;;
470
+ secrets)
471
+ scan_secrets
472
+ print_findings_summary
473
+ ;;
474
+ licenses)
475
+ scan_licenses
476
+ print_findings_summary
477
+ ;;
478
+ vulnerabilities)
479
+ scan_vulnerabilities
480
+ print_findings_summary
481
+ ;;
482
+ sbom)
483
+ generate_sbom
484
+ ;;
485
+ permissions)
486
+ audit_permissions
487
+ print_findings_summary
488
+ ;;
489
+ network)
490
+ analyze_network
491
+ print_findings_summary
492
+ ;;
493
+ report)
494
+ generate_compliance_report
495
+ ;;
496
+ help|--help|-h)
497
+ show_help
498
+ ;;
499
+ *)
500
+ error "Unknown command: $cmd"
501
+ show_help
502
+ exit 1
503
+ ;;
504
+ esac
505
+ fi
@@ -6,7 +6,7 @@
6
6
  set -euo pipefail
7
7
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
8
8
 
9
- VERSION="1.10.0"
9
+ VERSION="2.0.0"
10
10
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
11
11
  REPO_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
12
12
 
@@ -8,7 +8,7 @@
8
8
  # ║ Supports --template to scaffold from a team template and --terminal ║
9
9
  # ║ to select a terminal adapter (tmux, iterm2, wezterm). ║
10
10
  # ╚═══════════════════════════════════════════════════════════════════════════╝
11
- VERSION="1.10.0"
11
+ VERSION="2.0.0"
12
12
  set -euo pipefail
13
13
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
14
14
 
@@ -9,7 +9,7 @@
9
9
  set -euo pipefail
10
10
  trap 'echo "ERROR: $BASH_SOURCE:$LINENO exited with status $?" >&2' ERR
11
11
 
12
- VERSION="1.10.0"
12
+ VERSION="2.0.0"
13
13
 
14
14
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
15