Security Scanning
CodePeel runs multiple layers of security analysis on every pull request, detecting secrets, injection vulnerabilities, memory safety issues, and architectural security flaws. The secret scanning layer posts findings within seconds, while deeper AI-powered analysis runs in parallel and completes within 10-45 seconds. All security findings are posted as inline comments on the exact lines where issues were detected.
Overview
Security scanning is always enabled and cannot be turned off. Every PR review includes all security layers regardless of your configuration. The only configuration option that affects security scanning is securityOnly: true, which suppresses non-security findings (bugs, performance, architecture) while keeping all security layers active.
Note on scanner coverage: Built-in pattern coverage differs between the GitHub PR pipeline (which also includes injection, performance, and memory-safety patterns) and the IDE/webapp scanner (which is secret-only). For consistent coverage, add your important detections to
security.custom_patternsin.codepeel.yml— custom patterns run in both pipelines.
The scanning system is designed to fail open. If any security layer encounters an error (timeout, missing scanner, network issue), the review continues without that layer's results rather than blocking the PR. This ensures security scanning never prevents developers from working, while still catching issues when the system is healthy.
Security findings are deduplicated across all layers. If the secret scanner and the SAST layer both flag the same line, only one comment is posted. Deduplication uses a file:line key, and proximity matching (within 3 lines) consolidates findings from different engines.
All security layers are available on every plan including Free. There is no tier gating on security scanning -- every CodePeel user receives the same level of security analysis regardless of whether they are on Free, Pro, or Max.
The Four Layers
CodePeel runs four independent security analysis passes in parallel on every PR. Each layer specializes in a different class of security issues, and all four run simultaneously regardless of PR size.
Layer 1: Secret Scanning (Instant)
The secret scanning layer runs first and posts results within seconds, before any other analysis completes. It uses a two-pronged approach combining regex-based pattern matching with entropy-based detection.
Regex-based scanning tests every added line in the diff against a library of known secret patterns. Patterns are compiled once and tested against each line individually. The PR-pipeline scanner also checks for injection vulnerabilities, performance anti-patterns, and memory safety issues using dedicated pattern sets. The IDE/webapp scanner is secret-only — it does not include the injection/performance/memory patterns that the PR pipeline runs. For consistent coverage across PR reviews and IDE reviews, add your important detections to security.custom_patterns in .codepeel.yml (custom patterns run in both pipelines).
TruffleHog integration provides an additional layer of entropy-based secret detection. When TruffleHog is available, it runs alongside the regex scanner and catches unknown secret formats. Results are deduplicated against regex findings.
| Timing | Detection method | Scope |
|---|---|---|
| Instant (1-3 seconds) | Regex patterns | Known secret formats, injection patterns |
| Instant (3-5 seconds) | TruffleHog | Entropy-based, catches unknown formats |
Layer 2: AI Security Analysis (10-30 seconds)
The AI analysis layer is the core of CodePeel's review engine. It uses multiple AI providers to analyze the full diff for exploitable vulnerabilities. The AI receives the diff along with your configuration (custom instructions, expert rules, review profile) and produces structured findings.
The AI is guided by strict severity criteria. Critical findings are reserved for remotely exploitable vulnerabilities, credential leaks, and authentication bypasses. The AI will not flag theoretical issues without clear exploit vectors or style preferences disguised as security concerns.
Layer 3: SAST (10-20 seconds)
The SAST (Static Application Security Testing) layer runs an AI-based pattern analysis focused exclusively on CWE-classified security vulnerabilities. It operates independently from the AI analysis layer, providing a second opinion on security issues.
The SAST analysis focuses 100% on security, explicitly referencing OWASP Top 10 and CWE identifiers. Findings from SAST are deduplicated against AI findings using proximity matching (same file, within 3 lines).
The SAST layer analyzes code structure for unsafe deserialization, prototype pollution, ReDoS, XXE, SSRF, and insecure direct object references.
Layer 4: Architecture Security Review (15-25 seconds)
For larger PRs, the architecture review layer evaluates security at a structural level: authentication flow correctness, data flow security, trust boundary violations, and error handling that leaks sensitive information.
This layer is automatically skipped when securityOnly: true is set in your configuration. It is also suppressed on files under 120 lines, where architectural analysis provides limited value.
Built-in Secret Patterns
The regex scanner includes patterns for all major secret formats. These run on every review without any configuration.
API keys and tokens
| Pattern name | What it detects | Example match |
|---|---|---|
| AWS Access Key ID | AWS access keys (AKIA, AGPA, etc.) | AKIAIOSFODNN7EXAMPLE |
| OpenAI/Stripe Live Key | Keys starting with sk-live-, sk-test-, sk-cp-, sk-or- | sk-live-abc123def456... |
| GitHub Token | Personal access tokens | ghp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| GitHub OAuth Token | OAuth tokens | gho_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| GitLab Personal Access Token | GitLab PATs | glpat-xxxxxxxxxxxxxxxxxxxx |
| Firebase API Key | Google Firebase keys | AIzaSyxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| Stripe Secret Key | Stripe live secret keys | sk_live_xxxxxxxxxxxxxxxxxxxxxxxx |
| SendGrid API Key | SendGrid keys | SG.xxxxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| Twilio Account SID | Twilio SIDs | ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| Mailgun API Key | Mailgun keys | key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| Square Access Token | Square tokens | sq0atp-xxxxxxxxxxxxxxxxxxxxxx |
| Shopify Access Token | Shopify PATs | shpat_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| DigitalOcean PAT | DigitalOcean tokens | dop_v1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
| Slack Webhook | Slack incoming webhook URLs | https://hooks.slack.com/services/T.../B.../... |
Credentials and secrets
| Pattern name | What it detects |
|---|---|
| Heroku API Key | Status differs by surface. The PR-pipeline scanner does not include a Heroku pattern. The IDE/webapp scanner does still include the broad UUID regex [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}, which matches every standard UUID and produces heavy false positives. Expect noise from this pattern on IDE/CLI reviews. To detect Heroku keys reliably, add a tighter custom pattern (e.g., [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}.*heroku with a path filter) in security.custom_patterns — custom patterns run in both pipelines. |
| Generic Secret | secret=, token=, password=, api_key= with 8+ char values |
| Generic API Key | Differs by surface. PR pipeline: apiKey, apiSecret, secretKey with 20+ char values in key="value" form. IDE/webapp scanner: a much broader [a-z0-9]{32} pattern (any 32-char lowercase alphanumeric) — expect false positives. |
| RSA Private Key | -----BEGIN RSA PRIVATE KEY----- |
| JWT Token | Base64-encoded JWT tokens (eyJ...) |
| Database Connection String | mongodb://, postgres://, mysql://, redis:// URLs |
| Encryption Key | encryption_key, secret_key, aes_key with 16+ char values |
Injection and vulnerability patterns
| Pattern name | Severity | What it detects |
|---|---|---|
| SQL Injection Risk | Critical | SQL keywords with variable interpolation |
| String Concatenation in Query | Critical | String concatenation into SQL statements |
| PCI DSS Violation | Critical | Full card data, CVV, or card numbers stored in code |
| Timing Attack | High | String comparison (==) of secrets/passwords |
| Race Condition - Non-Atomic Flag | High | Boolean flags without locks (bool _isProcessing = false) |
| N+1 Query Pattern | Medium | Database calls inside loops |
| Refund Idempotency Missing | Medium | Refund operations without idempotency checks |
Memory and performance patterns
| Pattern name | Severity | What it detects |
|---|---|---|
| Unbounded Map Cache | Medium | Map/Object caches without size limits or TTL |
| Cache Without Eviction | Medium | Cache operations without max size or expiry |
| Unbounded List Growth | Medium | Lists/buffers that grow without bounds |
| Repeated Computation Without Memoization | Medium | Expensive operations inside loops |
| Potential N+1 Query Pattern | Medium | Database queries inside iteration loops |
Custom Secret Patterns
You can add organization-specific secret patterns that are checked during the instant scanning pass. Custom patterns run alongside the built-in patterns and produce findings within seconds.
Adding custom patterns
Add patterns to your .codepeel.yml:
security:
custom_patterns:
- "MYAPP_KEY_[A-Za-z0-9]{16,}"
- "Bearer [A-Za-z0-9\\-._~+/]+=*"
- "AKIA[A-Z0-9]{16}"
- "sk_(live|test)_[A-Za-z0-9]{24,}"
- "myco_[a-f0-9]{32}"
Pattern safety
Custom patterns are validated for ReDoS (Regular Expression Denial of Service) safety before execution. A pattern is rejected if:
- It exceeds 200 characters in length
- It contains nested quantifiers like
(a+)+that could cause catastrophic backtracking - It contains alternation groups with quantifiers like
(a|b)+
Rejected patterns are logged with a warning but do not block the review. Other valid patterns continue to run normally.
Writing effective patterns
To write a custom pattern, identify the consistent prefix or format of your secrets:
| Your secret format | Pattern |
|---|---|
MYAPP_KEY_ followed by 16+ alphanumeric chars | MYAPP_KEY_[A-Za-z0-9]{16,} |
myco_ followed by 32 hex chars | myco_[a-f0-9]{32} |
| Bearer tokens in code | Bearer [A-Za-z0-9\\-._~+/]+=* |
Internal tokens with INT_ prefix | INT_[A-Z0-9]{24} |
Test your patterns at regex101.com before adding them. Paste sample code containing your secret format in the test string and verify the pattern highlights correctly.
How It Works
Scanning flow
-
PR opened or updated. CodePeel receives the webhook and fetches the diff.
-
Secret scanning runs immediately. Regex patterns and TruffleHog run in parallel against the diff.
-
Findings are posted instantly. Secret scanning results are posted as inline comments before the AI analysis even starts. This gives developers immediate feedback on credential leaks.
-
AI analysis, SAST, and architecture review run in parallel. All three layers start simultaneously with individual timeouts.
-
Results are aggregated. Findings from all layers are combined, deduplicated, and filtered through quality gates.
-
Deduplication. Same
file:linefindings are collapsed. Proximity deduplication (within 3 lines) consolidates overlapping findings from different engines. For secret scanning specifically, if more than 3 identical findings exist, only the first 2 are posted.
TruffleHog integration
When TruffleHog is available, the scanner feeds added lines to it and maps the detected secrets back to the original file and line. If TruffleHog is not installed or the execution fails, the scanner falls back to regex-only mode silently.
Multi-line detection
The scanner includes multi-line N+1 query detection that spans across line boundaries. It looks for patterns where a database call is followed within a few lines by a loop. This catches N+1 patterns that single-line regex cannot detect.
Severity Levels
Security findings use the same severity scale as all CodePeel findings, but with security-specific criteria for each level.
| Severity | Criteria | Impact on health score | Where it appears |
|---|---|---|---|
| Critical | Remotely exploitable, credential leak, auth bypass, data loss | -20 per finding (max -50) | PR inline comment |
| High/Major | Significant vulnerability with clear exploit vector | -10 per finding (max -30) | PR inline comment |
| Medium/Minor | Requires specific conditions to exploit | -4 per finding (max -15) | PR inline comment |
| Low/Trivial | Minor security recommendation | -1 per finding (max -5) | Dashboard only |
What makes a finding "Critical"
A finding is classified as critical when it meets any of these criteria:
- A secret or credential is exposed in source code
- SQL injection is possible with user-controlled input
- Authentication can be bypassed
- Full card data (PCI DSS violation) is stored
- Remote code execution is possible
- Data loss or corruption can occur
Health score impact
Security findings affect the health score using the same formula as other findings. A single critical security finding deducts 20 points. Multiple critical findings are capped at -50 total. See Features for the complete health score calculation.
Security-Only Mode
Focus reviews exclusively on security vulnerabilities by enabling security-only mode. This suppresses all non-security findings (bugs, performance, best practices, architecture) while keeping all four security layers active.
securityOnly: true
When security-only mode is enabled:
- The architecture review layer is skipped entirely (saves 15-25 seconds)
- Bug, performance, and best practice findings from the AI analysis are filtered out
- Secret scanning runs unchanged
- SAST runs unchanged
- Only findings with
type: "security"are posted
Combine with strictMode: true for maximum security coverage:
securityOnly: true
strictMode: true
This configuration is recommended for security-sensitive repositories (authentication services, payment processing, data stores) where you want the AI to focus all its attention on security without distraction from other finding types.
Pre-merge Checks for Security
Use pre-merge checks to enforce security gates that block merges when security issues are found.
Security blocker check
The security_blocker check type fails if any security issue is detected in the review. This is a zero-tolerance gate with no threshold:
- Go to Pre-merge Checks in the sidebar
- Enable the Security Blocker check
- Set severity to Error (blocks merge)
- Configure branch protection to require
codepeel/premerge
With this configuration, no PR can be merged if it contains any security finding. This is the strongest enforcement available.
Critical findings check
The critical_findings check type fails if any critical-severity finding is detected. Since most security findings from secret scanning are critical severity, this provides similar protection while allowing medium-severity security findings to pass.
What to Do When You See a Critical Finding
-
Do not merge the PR. Critical findings indicate exploitable vulnerabilities or exposed credentials.
-
Read the explanation. The inline comment describes the attack vector, impact, and CWE identifier (when applicable).
-
Apply the suggested fix. Click "Commit suggestion" on the inline comment, or implement the recommendation manually.
-
If a secret was exposed: Revoke the credential immediately, even before fixing the code. Secrets in Git history remain accessible even after removal.
-
Push the fix. CodePeel re-reviews incrementally and confirms the issue is resolved.
-
If you disagree: Reply
@codepeel resolveon the comment to dismiss the finding. See Chat Commands for all available commands.
Best Practices
Act on critical findings immediately
Critical security findings represent real, exploitable vulnerabilities. Do not merge PRs with unresolved critical findings. If a secret was exposed, revoke it immediately -- do not wait for the PR to be fixed.
Add custom patterns for your organization
Every organization has internal secret formats. Add patterns for your custom API keys, internal tokens, and service credentials. This catches leaks that generic patterns miss.
Use expert_rules for security policies
Encode your security policies as expert rules in .codepeel.yml:
expert_rules:
- "All database queries must use parameterized statements"
- "Never log request bodies that may contain PII"
- "Authentication tokens must be stored in httpOnly cookies, not localStorage"
- "All user input must be validated with Zod schemas before processing"
- "File uploads must validate MIME type and size before storage"
Enable security-only mode for sensitive repos
For repositories that handle authentication, payments, or sensitive data, enable securityOnly: true to focus the AI entirely on security analysis without noise from other finding types.
Combine with pre-merge checks
Use the security_blocker pre-merge check to enforce a hard gate. This prevents accidental merges of PRs with security issues, even if a developer overlooks the inline comments.
Troubleshooting
Secret scanning not detecting my custom pattern
If your custom pattern is not producing findings:
- Verify the pattern is valid regex (test at regex101.com)
- Check that the pattern is under 200 characters
- Ensure the pattern does not contain nested quantifiers (ReDoS protection rejects these)
- Remember that patterns only match added lines (lines starting with
+in the diff) - Check your review metadata for the rejection reason
False positive on a test file
If a secret pattern matches a test fixture or mock value:
- Use
@codepeel resolveto dismiss the specific finding - Add an ignore rule:
@codepeel ignore: Test fixtures in __tests__/ may contain mock API keys - Add the test directory to
ignore_pathsin your configuration if you want to skip test files entirely
SAST findings duplicating AI findings
SAST and AI analysis run independently and may flag the same issue. CodePeel deduplicates findings within 3 lines of each other on the same file. If you still see duplicates, they are on lines more than 3 apart and represent distinct occurrences of the same vulnerability pattern.
TruffleHog not running
TruffleHog is an optional enhancement. If it is not installed, the scanner falls back to regex-only mode silently. This does not affect the quality of regex-based detection. TruffleHog adds entropy-based detection for secrets that do not match known patterns.
Security findings not blocking merge
Security findings alone do not block merges. You must configure pre-merge checks with the security_blocker check type AND enable branch protection rules requiring the codepeel/premerge status. Without both, security findings are informational only.
Frequently Asked Questions
Can I disable security scanning?
No. Security scanning is always enabled on every review. You cannot disable the secret scanning, SAST, or AI security analysis layers. You can suppress non-security findings with securityOnly: true, but security findings are always reported.
Does security scanning work on IDE reviews?
Yes. When you run a review from the VS Code extension or MCP server, the same security scanning layers run on your diff. Secret patterns, injection detection, and SAST analysis all apply to IDE reviews.
What CWE categories does SAST cover?
The SAST layer covers OWASP Top 10 categories including: injection (CWE-89, CWE-79), broken authentication (CWE-287), sensitive data exposure (CWE-200), XML external entities (CWE-611), broken access control (CWE-284), security misconfiguration, cross-site scripting (CWE-79), insecure deserialization (CWE-502), and server-side request forgery (CWE-918).
Are secrets in Git history detected?
No. CodePeel only scans the diff of the current PR (added lines). It does not scan the full repository history. If a secret was committed in a previous PR and is not part of the current diff, it will not be flagged. Use dedicated tools like git-secrets or GitHub's secret scanning for historical detection.
How do I handle a leaked secret?
- Revoke the secret immediately through the provider's dashboard (AWS, Stripe, GitHub, etc.)
- Remove the secret from code and replace with an environment variable reference
- Push the fix to the PR
- Rotate the secret -- generate a new credential and update your deployment
- Check for unauthorized access in the provider's audit logs
Even after removing a secret from code, it remains in Git history. Consider using git filter-branch or BFG Repo-Cleaner to purge it from history if the repository is public.
Does the scanner check .env files?
The scanner checks any file that appears in the diff. If a .env file is committed and appears in the PR diff, its contents are scanned. However, .env files should be in your .gitignore and never committed. Add .env to your ignore_paths if you have legitimate .env.example files that contain placeholder values.
What happens when the SAST layer times out?
If the SAST analysis does not complete in time, the layer returns an empty result and the review continues with findings from the other layers. The review is not blocked or delayed.
Can I configure which security patterns are active?
The built-in patterns cannot be individually disabled. All patterns run on every review. If a specific pattern produces false positives for your codebase, use @codepeel ignore: to suppress it, or add a learning that tells the AI to skip that pattern in future reviews.
OWASP Top 10 Coverage
The combined security layers provide coverage across the OWASP Top 10 web application security risks. The table below shows which layers detect each category.
| OWASP Category | Secret Scanner | AI Analysis | SAST |
|---|---|---|---|
| A01: Broken Access Control | -- | Yes | Yes |
| A02: Cryptographic Failures | Yes (exposed keys) | Yes | Yes |
| A03: Injection (SQL, XSS, etc.) | Yes (regex patterns) | Yes | Yes |
| A04: Insecure Design | -- | Yes | -- |
| A05: Security Misconfiguration | -- | Yes | Yes |
| A06: Vulnerable Components | -- | Yes | -- |
| A07: Auth Failures | -- | Yes | Yes |
| A08: Data Integrity Failures | -- | Yes | Yes |
| A09: Logging Failures | -- | Yes | -- |
| A10: SSRF | -- | Yes | Yes |
The secret scanner provides instant detection for A02 (exposed credentials) and A03 (injection patterns). The AI analysis layer covers all categories through contextual understanding. The SAST layer provides deterministic CWE-based detection for categories with well-defined patterns.
Deduplication Strategy
When multiple security layers flag the same issue, CodePeel ensures you only see one comment per issue. The deduplication system operates at multiple levels to prevent comment flooding.
Exact deduplication
Findings with the same file:line key across all layers are collapsed. The first finding posted wins. This prevents the secret scanner and SAST from both posting about the same hardcoded key on the same line.
Proximity deduplication
Findings within 3 lines of each other on the same file are consolidated. The higher-severity finding wins. This handles cases where the secret scanner flags line 42 and SAST flags line 44 for the same underlying issue.
Identical finding consolidation
If the secret scanner produces more than 3 findings with the same comment text (for example, the same pattern type detected in multiple files), only the first 2 are posted. The second finding includes a note listing all other locations where the same issue was found.
This prevents scenarios where a single leaked pattern (like a repeated API key) generates dozens of identical comments across the PR.
Security Scanning and Review Consumption
Security scanning does not consume additional reviews beyond the standard PR review. When a PR is reviewed, all four security layers run as part of that single review. There is no separate charge for security analysis.
The security layers run on every review regardless of plan tier. Free, Pro, and Max users all receive the same security scanning coverage. The only difference is that Pro and Max users can enable auto-fix to automatically generate fix PRs for security findings.
Comparison: Security Scanning vs Custom Rules
CodePeel provides two mechanisms for detecting security issues. Understanding the difference helps you choose the right approach.
| Security Scanning (built-in) | Custom Rules (.codepeel.yml) | |
|---|---|---|
| Configuration | None required | Must define in YAML |
| Patterns | 20+ built-in secret patterns + injection patterns | Your custom regex patterns |
| Detection method | Regex + TruffleHog + AI + SAST | Regex only |
| Scope | All added lines in diff | Files matching paths globs |
| Severity | Auto-assigned (mostly critical) | You choose (critical/high/medium/low) |
| Plan required | All plans | Pro or Max |
| Context-aware | Yes (transaction suppression) | Yes (transaction suppression) |
Use built-in security scanning for standard vulnerability detection. Use custom rules for organization-specific patterns that the built-in scanner does not cover (internal token formats, banned function calls, compliance requirements).
Integration with Other Features
Learnings
When you dismiss a security finding with @codepeel resolve or mark it as incorrect in the VS Code extension, a learning is created that suppresses similar findings in future reviews. Use this for intentional patterns (test fixtures, mock credentials) that should not be flagged.
Auto-fix
When auto-fix is enabled, security findings with suggestedFix values are included in the auto-fix PR. Common auto-fixes for security issues include replacing string concatenation with parameterized queries, adding input validation, and replacing eval() with safer alternatives. See Auto-Fix for details.
Health score
Security findings contribute to the health score with the same deduction formula as other findings. A single critical security finding deducts 20 points from the score. Use the health score as a quick signal for overall PR quality, and pre-merge checks for hard enforcement.
Incremental reviews
When you push a fix for a security finding, CodePeel's incremental review system detects that the previously flagged line has changed. The security layers re-scan the new code and only post findings on lines that were not previously commented. If your fix resolves the issue, no new comment is posted and the finding is effectively cleared.
Chat commands
You can interact with security findings using chat commands. Reply @codepeel resolve to dismiss a finding, or @codepeel explain to get more context about the vulnerability and its exploit vector.
Related Documentation
- Configuration --
.codepeel.ymlreference includingsecurity.custom_patterns - Pre-merge Checks -- Enforce security gates that block merges
- Features -- Complete reference for all analysis layers and the health score