Skip to main content

cc_audit/config/
template.rs

1//! Configuration template generation.
2
3use super::types::Config;
4
5impl Config {
6    /// Generate a YAML configuration template with comments.
7    pub fn generate_template() -> String {
8        r#"# cc-audit Configuration File
9# Place this file as .cc-audit.yaml in your project root
10
11# =============================================================================
12# RULE SEVERITY CONFIGURATION (v3.0.0)
13# =============================================================================
14# Controls how findings affect CI exit code.
15# - error: Causes CI failure (exit 1) - DEFAULT for all rules
16# - warn: Report only, does not cause CI failure (exit 0)
17# - ignore: Completely skip the rule (no report)
18#
19# Priority: ignore > warn > default
20
21severity:
22  # Default severity for all rules
23  default: error
24
25  # Rules to treat as warnings only (report but don't fail CI)
26  # warn:
27  #   - PI-001    # Prompt injection patterns
28  #   - PI-002
29  #   - OB-001    # Obfuscation patterns
30
31  # Rules to completely ignore (no report)
32  # ignore:
33  #   - OP-001    # Overpermission
34
35# =============================================================================
36# SCAN CONFIGURATION
37# =============================================================================
38scan:
39  # Output format: terminal, json, sarif, html, markdown
40  # format: terminal
41
42  # Strict mode: show medium/low severity findings and treat warnings as errors
43  strict: false
44
45  # Scan type: skill, hook, mcp, command, rules, docker, dependency, subagent, plugin
46  # scan_type: skill
47
48  # Recursive scan (enabled by default)
49  recursive: true
50
51  # CI mode: non-interactive output
52  ci: false
53
54  # Verbose output
55  verbose: false
56
57  # Minimum confidence level: tentative, firm, certain
58  # min_confidence: tentative
59
60  # Skip comment lines when scanning
61  skip_comments: false
62
63  # Show fix hints in terminal output
64  fix_hint: false
65
66  # Disable malware signature scanning
67  no_malware_scan: false
68
69  # Watch mode: continuously monitor files for changes
70  watch: false
71
72  # Path to a custom malware signatures database (JSON)
73  # malware_db: ./custom-malware.json
74
75  # Path to a custom rules file (YAML format)
76  # custom_rules: ./custom-rules.yaml
77
78  # Output file path (for HTML/JSON/SARIF output)
79  # output: ./report.html
80
81  # Enable deep scan with deobfuscation
82  deep_scan: false
83
84  # Auto-fix issues (where possible)
85  fix: false
86
87  # Preview auto-fix changes without applying them
88  fix_dry_run: false
89
90  # Warn-only mode: treat all findings as warnings (always exit 0)
91  warn_only: false
92
93  # Minimum severity level to include: critical, high, medium, low
94  # min_severity: high
95
96  # Minimum rule severity to treat as errors: error, warn
97  # min_rule_severity: error
98
99  # Strict secrets mode: disable dummy key heuristics for test files
100  strict_secrets: false
101
102  # ---------------------------------------------------------------------------
103  # CVE Scan Options (v1.1.0)
104  # ---------------------------------------------------------------------------
105  # Disable CVE vulnerability scanning
106  no_cve_scan: false
107
108  # Path to a custom CVE database (JSON)
109  # cve_db: ./custom-cve.json
110
111  # ---------------------------------------------------------------------------
112  # Remote Scanning Options (v1.1.0)
113  # ---------------------------------------------------------------------------
114  # Remote repository URL to scan
115  # remote: https://github.com/user/repo
116
117  # Git reference to checkout (branch, tag, commit)
118  # git_ref: main
119
120  # GitHub authentication token (also reads from GITHUB_TOKEN env var)
121  # remote_auth: ghp_xxxxxxxxxxxx
122
123  # Number of parallel clones for batch scanning
124  # parallel_clones: 4
125
126  # ---------------------------------------------------------------------------
127  # Badge Options (v1.1.0)
128  # ---------------------------------------------------------------------------
129  # Generate a badge for the scan result
130  badge: false
131
132  # Badge format: markdown, html, json
133  # badge_format: markdown
134
135  # Show summary only (useful for batch scanning)
136  summary: false
137
138  # ---------------------------------------------------------------------------
139  # Client Scan Options (v1.1.0)
140  # ---------------------------------------------------------------------------
141  # Scan all installed AI coding clients (Claude Code, Cursor, etc.)
142  all_clients: false
143
144  # Specific client to scan: claude, cursor, windsurf, vscode
145  # client: claude
146
147  # ---------------------------------------------------------------------------
148  # SBOM Options (v1.2.0)
149  # ---------------------------------------------------------------------------
150  # Generate SBOM (Software Bill of Materials)
151  sbom: false
152
153  # SBOM output format: cyclonedx, spdx
154  # sbom_format: cyclonedx
155
156  # Include npm dependencies in SBOM
157  sbom_npm: false
158
159  # Include Cargo dependencies in SBOM
160  sbom_cargo: false
161
162# =============================================================================
163# BASELINE CONFIGURATION (Drift Detection / Rug Pull Prevention)
164# =============================================================================
165baseline:
166  # Create a baseline snapshot when scanning
167  enabled: false
168
169  # Check for drift against saved baseline
170  check_drift: false
171
172  # Path to save baseline to
173  # save_to: ./.cc-audit-baseline.json
174
175  # Path to baseline file to compare against
176  # compare_with: ./.cc-audit-baseline.json
177
178# =============================================================================
179# WATCH MODE CONFIGURATION
180# =============================================================================
181watch:
182  # Debounce duration in milliseconds
183  debounce_ms: 300
184
185  # Poll interval in milliseconds
186  poll_interval_ms: 500
187
188# =============================================================================
189# IGNORE CONFIGURATION
190# =============================================================================
191# Uses glob patterns to determine which paths to ignore during scanning.
192# Each pattern is matched against the full path of the file.
193#
194# Glob pattern syntax:
195#   *       - matches any sequence of characters except /
196#   **      - matches any sequence of characters including /
197#   ?       - matches any single character
198#   {a,b}   - matches either a or b
199#   [abc]   - matches any character in the set
200#   [!abc]  - matches any character not in the set
201#
202# Examples:
203#   - "**/node_modules/**"       # Ignore node_modules anywhere
204#   - "**/*.test.{js,ts}"        # Match .test.js or .test.ts files
205#   - "**/test{,s}/**"           # Match test or tests directories
206#   - "**/*.{log,tmp,bak}"       # Match files by extension
207ignore:
208  patterns:
209    # Build outputs
210    - "**/target/**"              # Rust build artifacts
211    - "**/dist/**"                # Distribution/build output
212    - "**/build/**"               # Build directories
213    - "**/out/**"                 # Output directories
214    - "**/_build/**"              # Elixir/Phoenix build
215
216    # JavaScript/TypeScript frameworks
217    - "**/.next/**"               # Next.js
218    - "**/.nuxt/**"               # Nuxt.js
219    - "**/.output/**"             # Nitro/Nuxt output
220    - "**/.svelte-kit/**"         # SvelteKit
221    - "**/.astro/**"              # Astro
222    - "**/.remix/**"              # Remix
223    - "**/.gatsby/**"             # Gatsby
224    - "**/.expo/**"               # Expo
225    - "**/storybook-static/**"    # Storybook
226
227    # Package managers
228    - "**/node_modules/**"        # npm/yarn/pnpm packages
229    - "**/.pnpm/**"               # pnpm virtual store
230    - "**/.pnpm-store/**"         # pnpm global store
231    - "**/.yarn/**"               # Yarn cache/offline mirror
232    - "**/.npm/**"                # npm cache
233    - "**/.pnp.*"                 # Yarn PnP loader files
234    - "**/bower_components/**"    # Bower packages
235    - "**/jspm_packages/**"       # jspm packages
236
237    # Version control
238    - "**/.git/**"                # Git repository
239    - "**/.svn/**"                # SVN repository
240    - "**/.hg/**"                 # Mercurial repository
241
242    # IDEs and editors
243    - "**/.idea/**"               # JetBrains IDEs
244    - "**/.vscode/**"             # Visual Studio Code
245    - "**/.eclipse/**"            # Eclipse
246    - "**/.settings/**"           # Eclipse settings
247
248    # Deployment platforms
249    - "**/.vercel/**"             # Vercel
250    - "**/.netlify/**"            # Netlify
251    - "**/.amplify/**"            # AWS Amplify
252    - "**/.serverless/**"         # Serverless Framework
253
254    # Cache and bundlers
255    - "**/.cache/**"              # General cache
256    - "**/.parcel-cache/**"       # Parcel bundler
257    - "**/.vite/**"               # Vite cache
258    - "**/.turbo/**"              # Turborepo cache
259    - "**/.esbuild/**"            # esbuild cache
260    - "**/.webpack/**"            # webpack cache
261    - "**/.rpt2_cache/**"         # rollup-plugin-typescript2
262    - "**/tmp/**"                 # Temporary files
263    - "**/temp/**"                # Temporary files
264
265    # Python
266    - "**/__pycache__/**"         # Python bytecode cache
267    - "**/.pytest_cache/**"       # pytest cache
268    - "**/.mypy_cache/**"         # mypy type checker cache
269    - "**/.ruff_cache/**"         # Ruff linter cache
270    - "**/.venv/**"               # Virtual environment
271    - "**/venv/**"                # Virtual environment
272    - "**/.tox/**"                # Tox testing tool
273    - "**/.nox/**"                # Nox testing tool
274    - "**/__pypackages__/**"      # PEP 582
275    - "**/site-packages/**"       # Installed packages
276    - "**/.eggs/**"               # setuptools eggs
277
278    # Ruby
279    - "**/.bundle/**"             # Bundler
280
281    # Java/Gradle/Maven
282    - "**/.gradle/**"             # Gradle cache
283    - "**/.mvn/**"                # Maven wrapper
284
285    # Go
286    - "**/vendor/**"              # Go vendor directory
287
288    # Coverage reports
289    - "**/coverage/**"            # Coverage reports
290    - "**/.nyc_output/**"         # NYC/Istanbul coverage
291    - "**/htmlcov/**"             # Python coverage HTML
292    - "**/.coverage/**"           # Python coverage data
293
294    # Logs and reports
295    - "**/logs/**"                # Log directories
296    - "**/*.log"                  # Log files
297    - "**/report/**"              # Report directories
298    - "**/reports/**"             # Report directories
299    - "**/.report/**"             # Hidden report directories
300    - "**/*report*/**"            # Any directory containing 'report' (e.g., playwright-report, test-report)
301
302    # Generated and minified files
303    - "*.min.js"                  # Minified JavaScript
304    - "*.min.css"                 # Minified CSS
305    - "*.d.ts"                    # TypeScript declaration files
306    - "*.generated.*"             # Generated files
307    - "*.g.ts"                    # Generated TypeScript
308    - "*.g.dart"                  # Generated Dart
309    - "*.map"                     # Source maps
310    - "**/bundle.*"               # Bundle outputs
311    - "**/chunk-*"                # Webpack/Vite chunks
312
313    # Temporary and backup files
314    - "**/*.tmp"                  # Temporary files
315    - "**/*.temp"                 # Temporary files
316    - "**/*.bak"                  # Backup files
317    - "**/*.swp"                  # Vim swap files
318    - "**/*.swo"                  # Vim swap files
319    - "**/*~"                     # Backup files (emacs, etc.)
320
321    # OS-specific
322    - "**/.DS_Store"              # macOS
323    - "**/Thumbs.db"              # Windows
324    - "**/desktop.ini"            # Windows
325
326    # Docker
327    - "**/.docker/**"             # Docker cache/data
328
329    # Test directories (optional - uncomment if needed)
330    # - "**/test/**"              # Test directories
331    # - "**/tests/**"             # Test directories
332    # - "**/__tests__/**"         # Jest tests
333    # - "**/*.test.{js,ts,jsx,tsx}"  # Test files
334    # - "**/*.spec.{js,ts,jsx,tsx}"  # Spec files
335
336# =============================================================================
337# RULE CONFIGURATION
338# =============================================================================
339
340# Rule IDs to disable
341# disabled_rules:
342#   - "PE-001"
343#   - "EX-002"
344
345# Text file detection configuration
346# text_files:
347#   # Additional file extensions to treat as text
348#   extensions:
349#     - custom
350#     - special
351#
352#   # Additional special file names
353#   special_names:
354#     - CUSTOMFILE
355
356# Custom rules (YAML format)
357# rules:
358#   - id: "CUSTOM-001"
359#     name: "Custom Rule Name"
360#     severity: "high"  # critical, high, medium, low, info
361#     category: "exfiltration"  # exfiltration, privilege_escalation, persistence, etc.
362#     patterns:
363#       - 'pattern_to_match'
364#     message: "Description of the issue"
365#     confidence: "firm"  # tentative, firm, certain
366#     fix_hint: "How to fix this issue"
367
368# Custom malware signatures
369# malware_signatures:
370#   - id: "MW-CUSTOM-001"
371#     name: "Custom Malware Signature"
372#     description: "Description of what this detects"
373#     pattern: "malware_pattern"
374#     severity: "critical"
375#     category: "exfiltration"
376#     confidence: "firm"
377"#
378        .to_string()
379    }
380}
381
382#[cfg(test)]
383mod tests {
384    use super::*;
385
386    #[test]
387    fn test_template_is_valid_yaml() {
388        let template = Config::generate_template();
389
390        // Should parse as valid YAML
391        let result: Result<serde_yaml::Value, _> = serde_yaml::from_str(&template);
392        assert!(
393            result.is_ok(),
394            "Template should be valid YAML: {:?}",
395            result.err()
396        );
397    }
398
399    #[test]
400    fn test_template_contains_ignore_section() {
401        let template = Config::generate_template();
402
403        assert!(template.contains("# IGNORE CONFIGURATION"));
404        assert!(template.contains("ignore:"));
405        assert!(template.contains("patterns:"));
406    }
407
408    #[test]
409    fn test_template_contains_glob_syntax_documentation() {
410        let template = Config::generate_template();
411
412        // Should document glob pattern syntax
413        assert!(template.contains("Glob pattern syntax:"));
414        assert!(template.contains("*       - matches any sequence"));
415        assert!(template.contains("**      - matches any sequence"));
416        assert!(template.contains("?       - matches any single character"));
417        assert!(template.contains("{a,b}   - matches either"));
418        assert!(template.contains("[abc]   - matches any character in the set"));
419    }
420
421    #[test]
422    fn test_template_uses_glob_patterns_not_regex() {
423        let template = Config::generate_template();
424
425        // Should use glob patterns (starting with **/)
426        assert!(template.contains("**/node_modules/**"));
427        assert!(template.contains("**/target/**"));
428        assert!(template.contains("**/.git/**"));
429
430        // Should NOT use old regex patterns
431        assert!(!template.contains("/(target|dist|build|out)/"));
432        assert!(!template.contains("/(node_modules|\\.pnpm|\\.yarn)/"));
433        assert!(!template.contains("/(\\.git|\\.svn|\\.hg)/"));
434    }
435
436    #[test]
437    fn test_template_includes_report_and_log_patterns() {
438        let template = Config::generate_template();
439
440        // Should include report directories
441        assert!(template.contains("**/report/**"));
442        assert!(template.contains("**/reports/**"));
443        assert!(template.contains("**/.report/**"));
444
445        // Should include wildcard report pattern (e.g., playwright-report, test-report)
446        assert!(template.contains("**/*report*/**"));
447
448        // Should include log patterns
449        assert!(template.contains("**/logs/**"));
450        assert!(template.contains("**/*.log"));
451    }
452
453    #[test]
454    fn test_template_includes_common_build_artifacts() {
455        let template = Config::generate_template();
456
457        // Build outputs
458        assert!(template.contains("**/target/**"));
459        assert!(template.contains("**/dist/**"));
460        assert!(template.contains("**/build/**"));
461        assert!(template.contains("**/out/**"));
462
463        // Package managers
464        assert!(template.contains("**/node_modules/**"));
465        assert!(template.contains("**/.pnpm/**"));
466        assert!(template.contains("**/.pnpm-store/**"));
467        assert!(template.contains("**/.yarn/**"));
468        assert!(template.contains("**/.npm/**"));
469        assert!(template.contains("**/.pnp.*"));
470        assert!(template.contains("**/jspm_packages/**"));
471
472        // Version control
473        assert!(template.contains("**/.git/**"));
474        assert!(template.contains("**/.svn/**"));
475    }
476
477    #[test]
478    fn test_template_includes_framework_specific_patterns() {
479        let template = Config::generate_template();
480
481        // JavaScript/TypeScript frameworks
482        assert!(template.contains("**/.next/**"));
483        assert!(template.contains("**/.nuxt/**"));
484        assert!(template.contains("**/.svelte-kit/**"));
485        assert!(template.contains("**/.astro/**"));
486    }
487
488    #[test]
489    fn test_template_includes_cache_and_temp_patterns() {
490        let template = Config::generate_template();
491
492        // Cache directories
493        assert!(template.contains("**/.cache/**"));
494        assert!(template.contains("**/.vite/**"));
495        assert!(template.contains("**/.webpack/**"));
496
497        // Temporary files
498        assert!(template.contains("**/tmp/**"));
499        assert!(template.contains("**/temp/**"));
500        assert!(template.contains("**/*.tmp"));
501        assert!(template.contains("**/*.bak"));
502    }
503
504    #[test]
505    fn test_template_includes_python_patterns() {
506        let template = Config::generate_template();
507
508        assert!(template.contains("**/__pycache__/**"));
509        assert!(template.contains("**/.pytest_cache/**"));
510        assert!(template.contains("**/.venv/**"));
511        assert!(template.contains("**/venv/**"));
512    }
513
514    #[test]
515    fn test_template_includes_coverage_patterns() {
516        let template = Config::generate_template();
517
518        assert!(template.contains("**/coverage/**"));
519        assert!(template.contains("**/.nyc_output/**"));
520        assert!(template.contains("**/htmlcov/**"));
521    }
522
523    #[test]
524    fn test_template_includes_os_specific_patterns() {
525        let template = Config::generate_template();
526
527        // macOS
528        assert!(template.contains("**/.DS_Store"));
529
530        // Windows
531        assert!(template.contains("**/Thumbs.db"));
532        assert!(template.contains("**/desktop.ini"));
533    }
534
535    #[test]
536    fn test_template_includes_severity_configuration() {
537        let template = Config::generate_template();
538
539        assert!(template.contains("# RULE SEVERITY CONFIGURATION"));
540        assert!(template.contains("severity:"));
541        assert!(template.contains("default: error"));
542    }
543
544    #[test]
545    fn test_template_includes_scan_configuration() {
546        let template = Config::generate_template();
547
548        assert!(template.contains("# SCAN CONFIGURATION"));
549        assert!(template.contains("scan:"));
550    }
551
552    #[test]
553    fn test_template_includes_baseline_configuration() {
554        let template = Config::generate_template();
555
556        assert!(template.contains("# BASELINE CONFIGURATION"));
557        assert!(template.contains("baseline:"));
558    }
559
560    #[test]
561    fn test_template_includes_watch_configuration() {
562        let template = Config::generate_template();
563
564        assert!(template.contains("# WATCH MODE CONFIGURATION"));
565        assert!(template.contains("watch:"));
566        assert!(template.contains("debounce_ms:"));
567    }
568
569    #[test]
570    fn test_template_includes_generated_and_minified_files() {
571        let template = Config::generate_template();
572
573        // Minified files (v3.2.0)
574        assert!(template.contains("\"*.min.js\""));
575        assert!(template.contains("\"*.min.css\""));
576
577        // Generated files (v3.2.0)
578        assert!(template.contains("\"*.d.ts\""));
579        assert!(template.contains("\"*.generated.*\""));
580        assert!(template.contains("\"*.g.ts\""));
581        assert!(template.contains("\"*.g.dart\""));
582
583        // Source maps (v3.2.0)
584        assert!(template.contains("\"*.map\""));
585
586        // Bundle outputs (v3.2.0)
587        assert!(template.contains("\"**/bundle.*\""));
588        assert!(template.contains("\"**/chunk-*\""));
589    }
590}