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 store
230    - "**/.yarn/**"               # Yarn cache/offline mirror
231    - "**/bower_components/**"    # Bower packages
232
233    # Version control
234    - "**/.git/**"                # Git repository
235    - "**/.svn/**"                # SVN repository
236    - "**/.hg/**"                 # Mercurial repository
237
238    # IDEs and editors
239    - "**/.idea/**"               # JetBrains IDEs
240    - "**/.vscode/**"             # Visual Studio Code
241    - "**/.eclipse/**"            # Eclipse
242    - "**/.settings/**"           # Eclipse settings
243
244    # Deployment platforms
245    - "**/.vercel/**"             # Vercel
246    - "**/.netlify/**"            # Netlify
247    - "**/.amplify/**"            # AWS Amplify
248    - "**/.serverless/**"         # Serverless Framework
249
250    # Cache and bundlers
251    - "**/.cache/**"              # General cache
252    - "**/.parcel-cache/**"       # Parcel bundler
253    - "**/.vite/**"               # Vite cache
254    - "**/.turbo/**"              # Turborepo cache
255    - "**/.esbuild/**"            # esbuild cache
256    - "**/.rpt2_cache/**"         # rollup-plugin-typescript2
257    - "**/tmp/**"                 # Temporary files
258    - "**/temp/**"                # Temporary files
259
260    # Python
261    - "**/__pycache__/**"         # Python bytecode cache
262    - "**/.pytest_cache/**"       # pytest cache
263    - "**/.mypy_cache/**"         # mypy type checker cache
264    - "**/.ruff_cache/**"         # Ruff linter cache
265    - "**/.venv/**"               # Virtual environment
266    - "**/venv/**"                # Virtual environment
267    - "**/.tox/**"                # Tox testing tool
268    - "**/.nox/**"                # Nox testing tool
269    - "**/__pypackages__/**"      # PEP 582
270    - "**/site-packages/**"       # Installed packages
271    - "**/.eggs/**"               # setuptools eggs
272
273    # Ruby
274    - "**/.bundle/**"             # Bundler
275
276    # Java/Gradle/Maven
277    - "**/.gradle/**"             # Gradle cache
278    - "**/.mvn/**"                # Maven wrapper
279
280    # Go
281    - "**/vendor/**"              # Go vendor directory
282
283    # Coverage reports
284    - "**/coverage/**"            # Coverage reports
285    - "**/.nyc_output/**"         # NYC/Istanbul coverage
286    - "**/htmlcov/**"             # Python coverage HTML
287    - "**/.coverage/**"           # Python coverage data
288
289    # Logs and reports
290    - "**/logs/**"                # Log directories
291    - "**/*.log"                  # Log files
292    - "**/report/**"              # Report directories
293    - "**/reports/**"             # Report directories
294    - "**/.report/**"             # Hidden report directories
295
296    # Temporary and backup files
297    - "**/*.tmp"                  # Temporary files
298    - "**/*.temp"                 # Temporary files
299    - "**/*.bak"                  # Backup files
300    - "**/*.swp"                  # Vim swap files
301    - "**/*.swo"                  # Vim swap files
302    - "**/*~"                     # Backup files (emacs, etc.)
303
304    # OS-specific
305    - "**/.DS_Store"              # macOS
306    - "**/Thumbs.db"              # Windows
307    - "**/desktop.ini"            # Windows
308
309    # Docker
310    - "**/.docker/**"             # Docker cache/data
311
312    # Test directories (optional - uncomment if needed)
313    # - "**/test/**"              # Test directories
314    # - "**/tests/**"             # Test directories
315    # - "**/__tests__/**"         # Jest tests
316    # - "**/*.test.{js,ts,jsx,tsx}"  # Test files
317    # - "**/*.spec.{js,ts,jsx,tsx}"  # Spec files
318
319# =============================================================================
320# RULE CONFIGURATION
321# =============================================================================
322
323# Rule IDs to disable
324# disabled_rules:
325#   - "PE-001"
326#   - "EX-002"
327
328# Text file detection configuration
329# text_files:
330#   # Additional file extensions to treat as text
331#   extensions:
332#     - custom
333#     - special
334#
335#   # Additional special file names
336#   special_names:
337#     - CUSTOMFILE
338
339# Custom rules (YAML format)
340# rules:
341#   - id: "CUSTOM-001"
342#     name: "Custom Rule Name"
343#     severity: "high"  # critical, high, medium, low, info
344#     category: "exfiltration"  # exfiltration, privilege_escalation, persistence, etc.
345#     patterns:
346#       - 'pattern_to_match'
347#     message: "Description of the issue"
348#     confidence: "firm"  # tentative, firm, certain
349#     fix_hint: "How to fix this issue"
350
351# Custom malware signatures
352# malware_signatures:
353#   - id: "MW-CUSTOM-001"
354#     name: "Custom Malware Signature"
355#     description: "Description of what this detects"
356#     pattern: "malware_pattern"
357#     severity: "critical"
358#     category: "exfiltration"
359#     confidence: "firm"
360"#
361        .to_string()
362    }
363}
364
365#[cfg(test)]
366mod tests {
367    use super::*;
368
369    #[test]
370    fn test_template_is_valid_yaml() {
371        let template = Config::generate_template();
372
373        // Should parse as valid YAML
374        let result: Result<serde_yaml::Value, _> = serde_yaml::from_str(&template);
375        assert!(
376            result.is_ok(),
377            "Template should be valid YAML: {:?}",
378            result.err()
379        );
380    }
381
382    #[test]
383    fn test_template_contains_ignore_section() {
384        let template = Config::generate_template();
385
386        assert!(template.contains("# IGNORE CONFIGURATION"));
387        assert!(template.contains("ignore:"));
388        assert!(template.contains("patterns:"));
389    }
390
391    #[test]
392    fn test_template_contains_glob_syntax_documentation() {
393        let template = Config::generate_template();
394
395        // Should document glob pattern syntax
396        assert!(template.contains("Glob pattern syntax:"));
397        assert!(template.contains("*       - matches any sequence"));
398        assert!(template.contains("**      - matches any sequence"));
399        assert!(template.contains("?       - matches any single character"));
400        assert!(template.contains("{a,b}   - matches either"));
401        assert!(template.contains("[abc]   - matches any character in the set"));
402    }
403
404    #[test]
405    fn test_template_uses_glob_patterns_not_regex() {
406        let template = Config::generate_template();
407
408        // Should use glob patterns (starting with **/)
409        assert!(template.contains("**/node_modules/**"));
410        assert!(template.contains("**/target/**"));
411        assert!(template.contains("**/.git/**"));
412
413        // Should NOT use old regex patterns
414        assert!(!template.contains("/(target|dist|build|out)/"));
415        assert!(!template.contains("/(node_modules|\\.pnpm|\\.yarn)/"));
416        assert!(!template.contains("/(\\.git|\\.svn|\\.hg)/"));
417    }
418
419    #[test]
420    fn test_template_includes_report_and_log_patterns() {
421        let template = Config::generate_template();
422
423        // Should include report directories
424        assert!(template.contains("**/report/**"));
425        assert!(template.contains("**/reports/**"));
426        assert!(template.contains("**/.report/**"));
427
428        // Should include log patterns
429        assert!(template.contains("**/logs/**"));
430        assert!(template.contains("**/*.log"));
431    }
432
433    #[test]
434    fn test_template_includes_common_build_artifacts() {
435        let template = Config::generate_template();
436
437        // Build outputs
438        assert!(template.contains("**/target/**"));
439        assert!(template.contains("**/dist/**"));
440        assert!(template.contains("**/build/**"));
441        assert!(template.contains("**/out/**"));
442
443        // Package managers
444        assert!(template.contains("**/node_modules/**"));
445        assert!(template.contains("**/.pnpm/**"));
446        assert!(template.contains("**/.yarn/**"));
447
448        // Version control
449        assert!(template.contains("**/.git/**"));
450        assert!(template.contains("**/.svn/**"));
451    }
452
453    #[test]
454    fn test_template_includes_framework_specific_patterns() {
455        let template = Config::generate_template();
456
457        // JavaScript/TypeScript frameworks
458        assert!(template.contains("**/.next/**"));
459        assert!(template.contains("**/.nuxt/**"));
460        assert!(template.contains("**/.svelte-kit/**"));
461        assert!(template.contains("**/.astro/**"));
462    }
463
464    #[test]
465    fn test_template_includes_cache_and_temp_patterns() {
466        let template = Config::generate_template();
467
468        // Cache directories
469        assert!(template.contains("**/.cache/**"));
470        assert!(template.contains("**/.vite/**"));
471
472        // Temporary files
473        assert!(template.contains("**/tmp/**"));
474        assert!(template.contains("**/temp/**"));
475        assert!(template.contains("**/*.tmp"));
476        assert!(template.contains("**/*.bak"));
477    }
478
479    #[test]
480    fn test_template_includes_python_patterns() {
481        let template = Config::generate_template();
482
483        assert!(template.contains("**/__pycache__/**"));
484        assert!(template.contains("**/.pytest_cache/**"));
485        assert!(template.contains("**/.venv/**"));
486        assert!(template.contains("**/venv/**"));
487    }
488
489    #[test]
490    fn test_template_includes_coverage_patterns() {
491        let template = Config::generate_template();
492
493        assert!(template.contains("**/coverage/**"));
494        assert!(template.contains("**/.nyc_output/**"));
495        assert!(template.contains("**/htmlcov/**"));
496    }
497
498    #[test]
499    fn test_template_includes_os_specific_patterns() {
500        let template = Config::generate_template();
501
502        // macOS
503        assert!(template.contains("**/.DS_Store"));
504
505        // Windows
506        assert!(template.contains("**/Thumbs.db"));
507        assert!(template.contains("**/desktop.ini"));
508    }
509
510    #[test]
511    fn test_template_includes_severity_configuration() {
512        let template = Config::generate_template();
513
514        assert!(template.contains("# RULE SEVERITY CONFIGURATION"));
515        assert!(template.contains("severity:"));
516        assert!(template.contains("default: error"));
517    }
518
519    #[test]
520    fn test_template_includes_scan_configuration() {
521        let template = Config::generate_template();
522
523        assert!(template.contains("# SCAN CONFIGURATION"));
524        assert!(template.contains("scan:"));
525    }
526
527    #[test]
528    fn test_template_includes_baseline_configuration() {
529        let template = Config::generate_template();
530
531        assert!(template.contains("# BASELINE CONFIGURATION"));
532        assert!(template.contains("baseline:"));
533    }
534
535    #[test]
536    fn test_template_includes_watch_configuration() {
537        let template = Config::generate_template();
538
539        assert!(template.contains("# WATCH MODE CONFIGURATION"));
540        assert!(template.contains("watch:"));
541        assert!(template.contains("debounce_ms:"));
542    }
543}