From atv-starter-kit
Scans agentic configs (.github/, .vscode/) using AgentShield's 33-rule taxonomy and application source code for OWASP Top 10 + STRIDE threats.
npx claudepluginhub all-the-vibes/atv-starterkit --plugin atv-starter-kitThis skill uses the workspace's default tool permissions.
Scan your project for security issues across two surfaces:
Performs comprehensive code security audits across 8 dimensions: OWASP Top 10/CWE vulns, secrets, deps/supply chain, IaC, threats/MITRE ATT&CK, auth, AI code, compliance via 8 parallel agents.
Audits code for security vulnerabilities including OWASP Top 10, auth flaws, injection, data exposure, and dependency risks using STRIDE threat modeling and phased reviews.
Scans codebases for OWASP Top 10 vulnerabilities via static analysis: secret exposure, injection flaws, auth/authz gaps, supply-chain risks, misconfigurations, logging failures. Use before deployments, PR merges, auth/payment changes.
Share bugs, ideas, or general feedback.
Scan your project for security issues across two surfaces:
.github/, .vscode/ configs (33 rules adapted from AgentShield).Heritage: This skill absorbs the former
/csoskill. Old/csotriggers still route here. The on-disk security report file keeps the legacy<!-- cso -->marker block so existing reports stay structurally compatible.
5 config categories: Secrets Β· Permissions Β· Hooks Β· MCP Servers Β· Agents & Skills
#$ARGUMENTS
Argument grammar: Two independent axes, parsed in order.
$ARGUMENTS matches fix (case-insensitive), mode = fix. Otherwise mode = report (default).fix):
config β scope = config (config audit only; skip OWASP/STRIDE)owasp β scope = owasp (OWASP scan only; skip config + STRIDE)stride β scope = stride (STRIDE only; skip config + OWASP)/ or \ or matches an existing path) β scope = <path> (run OWASP/STRIDE narrowed to that path; skip config)full β scope = full (default; run everything available)Examples:
/atv-security β mode=report scope=full/atv-security fix β mode=fix scope=full/atv-security config fix or /atv-security fix config β mode=fix scope=config/atv-security owasp β mode=report scope=owasp/atv-security src/api/ β mode=report scope=src/api/Phase 1: Discovery β Detect config surfaces + app source stack
Phase 2: Tier 1 Config β Deterministic regex scan of .github/, .vscode/ (skip if scope β {full, config})
Phase 3: Tier 2 Config β LLM-assessed config rules (skip if scope β {full, config})
Phase 4: OWASP Top 10 β Application source code scan (skip if no source OR scope β {full, owasp, <path>})
Phase 5: STRIDE β Threat model the application (skip if no source OR scope β {full, stride, <path>})
Phase 6: Score & Grade β Per-surface grades with N/A semantics
Phase 7: Output β Combined report (config + OWASP + STRIDE)
Phase 8: Persist β Upsert into docs/security/YYYY-MM-DD-security-report.md (both marker blocks)
Phase 9: Fix β Opt-in safe fixes for auto-fixable config rules (only when mode=fix)
Use file_search and list_dir to detect both surfaces in parallel.
| Surface | File Pattern | Category |
|---|---|---|
| Instructions | .github/copilot-instructions.md | Agents & Skills |
| MCP Config | .github/copilot-mcp-config.json | MCP Servers |
| Skills | .github/skills/**/*.md | Agents & Skills |
| Agents | .github/agents/**/*.agent.md | Agents & Skills |
| Hooks | .github/hooks/copilot-hooks.json + .github/hooks/scripts/** | Hooks |
| Setup Steps | .github/copilot-setup-steps.yml | Hooks |
| VS Code | .vscode/settings.json, .vscode/extensions.json | Permissions |
Set hasConfig = true if any of the above are found.
| Signal | Stack | Key files to scan |
|---|---|---|
package.json, *.ts, *.js | Node.js / TypeScript | src/**, routes/**, api/**, pages/** |
requirements.txt, *.py | Python | app/**, src/**, views/**, api/** |
Gemfile, *.rb | Ruby / Rails | app/**, config/**, db/** |
go.mod, *.go | Go | **/*.go |
*.cs, *.csproj | .NET | **/*.cs, Controllers/** |
pom.xml, *.java | Java | src/**/*.java |
Set hasSource = true if any application source files are found. If scope is a path, narrow source detection to that path.
Record: list of discovered config files, detected stack, total source files found, entry points identified.
If !hasConfig && !hasSource: report "No ATV configuration or application source detected. Run npx atv-starterkit init to scaffold an agentic environment, or run /atv-security from a project directory." and stop.
If scope=config and !hasConfig: report "Scope config requested but no .github/ directory found." and stop.
If scope β {owasp, stride, <path>} and !hasSource: report "Scope requires application source, but none found." and stop.
Run only when
hasConfig && scope β {full, config}.
Run grep_search with isRegexp: true for each pattern below. For each match, record a finding with the specified fields.
| Rule | Pattern | Scope | Severity | Fix |
|---|---|---|---|---|
| SEC-01 | sk-ant-[a-zA-Z0-9]{20,} | All .github/**, .vscode/** | π΄ critical | Replace with ${ANTHROPIC_API_KEY} env var reference |
| SEC-02 | sk-proj-[a-zA-Z0-9]{20,} | All .github/**, .vscode/** | π΄ critical | Replace with ${OPENAI_API_KEY} env var reference |
| SEC-03 | AKIA[0-9A-Z]{16} | All .github/**, .vscode/** | π΄ critical | Replace with ${AWS_ACCESS_KEY_ID} env var reference |
For rules whose regex patterns require alternation, use the entries below instead of markdown table rows so the raw | characters remain valid for isRegexp: true:
(?:ghp_[a-zA-Z0-9]{36}|github_pat_[a-zA-Z0-9]{22,}).github/**, .vscode/**${GITHUB_TOKEN} env var reference(?:Bearer [a-zA-Z0-9_\-\.]{20,}|mongodb(\+srv)?://[^\s]+|postgres(ql)?://[^\s]+|mysql://[^\s]+|redis://[^\s]+).github/**, .vscode/**${ENV_VAR} reference appropriate to the service| Rule | Pattern | Scope | Severity | Fix |
|---|---|---|---|---|
| MCP-02 | "tools"\s*:\s*\["?\*"?\] | .github/copilot-mcp-config.json | π‘ high | Scope to specific tools needed: ["tool1", "tool2"] |
| MCP-03 | autoApprove | .github/copilot-mcp-config.json | π’ medium | Remove autoApprove or restrict to safe read-only tools |
(?:sk-ant-|sk-proj-|AKIA|ghp_|Bearer ).github/copilot-mcp-config.json env sections${input:VAR} or ${ENV_VAR} references(?:curl.*\$\{|wget.*\$\{|eval.*\$\{).github/hooks/scripts/**(?:curl\s+-X\s+POST.*\$|wget\s+--post).github/hooks/scripts/**| Rule | Pattern | Scope | Severity | Fix |
|---|---|---|---|---|
| HOOK-03a | 2>/dev/null | .github/hooks/scripts/** | π’ medium | Log errors instead of suppressing them silently |
| HOOK-03b | || true$ | .github/hooks/scripts/** | π’ medium | Log errors instead of suppressing them silently |
| HOOK-03c | || exit 0$ | .github/hooks/scripts/** | π’ medium | Log errors instead of suppressing them silently |
| Rule | Pattern | Scope | Severity | Fix |
|---|---|---|---|---|
| AGENT-01 | [\u200B\u200C\u200D\uFEFF] | .github/skills/**, .github/agents/**, .github/copilot-instructions.md | π΄ critical | Remove zero-width characters β likely hidden instruction injection |
| AGENT-02 | [A-Za-z0-9+/]{80,}={0,2} | .github/skills/**, .github/agents/** | π’ medium | Decode and inspect β may contain hidden instructions. Ignore if preceded by sha256:, data:, or http |
| Rule | Pattern | Scope | Severity | Fix |
|---|---|---|---|---|
| PERM-01 | security\.workspace\.trust\.enabled"?\s*:\s*false|chat\.tools\.autoApprove"?\s*:\s*true | .vscode/settings.json | π’ medium | Enable workspace trust; disable agent-tool auto-approval |
Execution: For each rule, run grep_search with the pattern and includePattern matching the scope. Record every match as a finding with: rule ID, category, severity, title, file path, matched evidence (truncated to 100 chars), and fix suggestion.
Run only when
hasConfig && scope β {full, config}.
For each config surface, use read_file to load the content, then assess against the following rules. Apply judgment β distinguish benign patterns from genuinely suspicious ones.
Read: .github/copilot-instructions.md, all .github/agents/*.agent.md, all .github/skills/**/SKILL.md
| Rule | What to detect | Severity | Category | Benign exceptions |
|---|---|---|---|---|
| INJ-01 | Instructions containing "always run", "without asking", "automatically install", "execute without confirmation" | π‘ high | Agents & Skills | "always run tests" or "always check" are benign quality patterns |
| INJ-02 | Instructions to "fetch and execute", "download and run", "curl | bash", "eval remote" | π΄ critical | Agents & Skills | None β always flag |
| INJ-03 | System prompt overrides: "ignore previous instructions", "you are now", "DAN", "jailbreak", fake system messages | π΄ critical | Agents & Skills | None β always flag |
| INJ-04 | Output manipulation: "always report ok", "suppress warnings", "remove security findings", "hide errors" | π‘ high | Agents & Skills | Legitimate error handling instructions are benign |
| INJ-05 | Time-delayed execution: "after 5 minutes", "when user is away", "at 3am", conditional on absence | π‘ high | Agents & Skills | Scheduled CI/CD references are benign |
Read: All .github/agents/*.agent.md
| Rule | What to detect | Severity | Category |
|---|---|---|---|
| ACC-01 | Agent definitions granting unrestricted Bash/shell access without scoping | π‘ high | Agents & Skills |
| ACC-02 | Agent with no allowedTools restriction when it has tool access | π’ medium | Agents & Skills |
| ACC-03 | Escalation chains: agent can spawn sub-agents with elevated permissions | π‘ high | Agents & Skills |
Read: .github/hooks/copilot-hooks.json, all .github/hooks/scripts/**
| Rule | What to detect | Severity | Category |
|---|---|---|---|
| EXEC-01 | Hook scripts that download and execute remote code (curl | sh, wget + execute) | π΄ critical | Hooks |
| EXEC-02 | Global package installs in hooks (npm install -g, pip install, gem install, cargo install) | π’ medium | Hooks |
| EXEC-03 | Container escape patterns: docker --privileged, --pid=host, --network=host, root volume mounts | π΄ critical | Hooks |
| EXEC-04 | Credential access: keychain reads, /etc/shadow, .aws/credentials, credential file access | π΄ critical | Hooks |
Read: .github/copilot-setup-steps.yml
| Rule | What to detect | Severity | Category |
|---|---|---|---|
| SETUP-01 | Remote script execution in setup (curl | bash, wget | sh, remote script download + run) | π΄ critical | Hooks |
| SETUP-02 | Privileged operations (sudo without justification, chmod 777, chown root) | π‘ high | Hooks |
Read: .github/copilot-mcp-config.json
| Rule | What to detect | Severity | Category |
|---|---|---|---|
| MCP-01 | MCP servers using npx -y without version pinning (@package instead of @package@version) β requires parsing JSON structure: check each server's command is "npx" and args array contains "-y" with an unpinned package name (no @semver suffix) | π‘ high | MCP Servers |
Read: .vscode/extensions.json
| Rule | What to detect | Severity | Category |
|---|---|---|---|
| VSCODE-01 | Extension recommendations from untrusted/unknown publishers without justification | π΅ low | Permissions |
Read: All .github/skills/**/SKILL.md, all .github/agents/*.agent.md
| Rule | What to detect | Severity | Category |
|---|---|---|---|
| AGENT-03 | Files with >8,000 characters of effective prose (exclude YAML frontmatter, fenced code blocks, and markdown tables from count) | π’ medium | Agents & Skills |
AGENT-03 exemptions: Skip the following first-party security skill files. They intentionally bundle config + OWASP + STRIDE rule definitions and exceed 8,000 chars by design:
.github/skills/atv-security/SKILL.mdThis exemption applies to the file currently performing the scan and any other ATV-bundled security skills with the same purpose. Do not exempt user-authored skills β long custom skills are legitimate findings.
Execution: For each rule, read the relevant files, assess content against criteria, and record findings. Include the specific evidence that triggered the finding (quoted text, line context). Distinguish benign patterns from suspicious ones using the exceptions listed.
Run only when
hasSource && scope β {full, owasp, <path>}.
For each category, use grep_search for Tier 1 patterns and read_file + LLM assessment for Tier 2. Scan only application source files, not .github/ configs. If scope is a path, scope all greps and reads to that path.
Tier 1 β grep patterns:
| Pattern | What it catches | Severity |
|---|---|---|
role\s*===?\s*["']admin["'] scoped to route/controller files | Hardcoded role checks instead of RBAC | π’ medium |
req\.user\s*&& without authorization middleware | Ad-hoc auth checks bypassing middleware | π‘ high |
Tier 2 β LLM assessment:
/users/:id without checking req.user.id === id)Tier 1 β grep patterns:
| Pattern | What it catches | Severity |
|---|---|---|
| `(?:md5 | sha1 | DES |
http:// in API endpoint URLs (not localhost) | Unencrypted data in transit | π’ medium |
password.*=.*["'][^$] | Hardcoded passwords | π΄ critical |
Tier 2 β LLM assessment:
Tier 1 β grep patterns:
For A03 alternation patterns, use the entries below instead of markdown table rows so the raw | characters remain valid for isRegexp: true:
query\s*\(\s*["'\x60].*\$\{ or query\s*\(.*\+\s*(?:eval|exec|Function)\s*\( with variable input(?:innerHTML\s*=|dangerouslySetInnerHTML|\| safe|\|raw)child_process\.(?:exec|spawn).*\$\{ or subprocess\.call.*\+\.find\(\{.*\$ or \.aggregate\(\[.*\$ in Mongo contextsTier 2 β LLM assessment:
Tier 2 β LLM assessment only (no grep patterns):
Tier 1 β grep patterns:
(?:DEBUG\s*=\s*True|debug:\s*true)cors\(\) without origin restriction, or origin:\s*["']\*["']ALLOWED_HOSTS\s*=\s*\[["']\*["']\]Tier 2 β LLM assessment:
helmet or equivalent middleware)? This is an absence check that requires reading the app setup, not a grep pattern.Tier 1 β grep patterns:
| Pattern | What it catches | Severity |
|---|---|---|
"dependencies" in package.json | Check for known-vulnerable versions | π’ medium |
Tier 2 β LLM assessment:
package.json, requirements.txt, Gemfile, or go.modnpm audit, pip-audit, bundle audit, govulncheckTier 1 β grep patterns:
jwt\.sign.*expiresIn.*(?:["']30d|["']365d|["']never)session.*maxAge.*86400000 (>24h in ms)(?:bcrypt|salt).*rounds.*[1-5][^0-9]Tier 2 β LLM assessment:
Tier 1 β grep patterns:
| Pattern | What it catches | Severity |
|---|---|---|
| `(?:deserialize | unserialize | pickle.load |
Tier 2 β LLM assessment:
<script src="https://..."> tags that load third-party/CDN scripts without an integrity attribute (Subresource Integrity)? This requires reading/parsing the tag β a simple grep can't validate absence of an attribute reliably.Tier 2 β LLM assessment only:
Tier 1 β grep patterns:
(?:fetch\s*\(\s*\w+|axios\.\w+\(\s*\w+|requests\.\w+\(\s*\w+)(?:http\.Get\(\s*\w+|urllib\.request\.urlopen\(\s*\w+)Tier 2 β LLM assessment:
Run only when
hasSource && scope β {full, stride, <path>}.
Read the application's architecture by examining:
Produce a threat matrix:
| Threat | Category | Description | Affected Component | Risk | Mitigation |
|---|---|---|---|---|---|
| Spoofing | Identity | Can an attacker impersonate a user/service? | [auth system, API] | [H/M/L] | [existing or missing control] |
| Tampering | Data integrity | Can data be modified in transit or at rest? | [database, API payload] | [H/M/L] | [existing or missing control] |
| Repudiation | Accountability | Can actions be performed without audit trail? | [logging system] | [H/M/L] | [existing or missing control] |
| Information Disclosure | Confidentiality | Can sensitive data leak? | [error pages, logs, API responses] | [H/M/L] | [existing or missing control] |
| Denial of Service | Availability | Can the service be overwhelmed? | [endpoints without rate limiting] | [H/M/L] | [existing or missing control] |
| Elevation of Privilege | Authorization | Can a user gain unauthorized access? | [role system, admin endpoints] | [H/M/L] | [existing or missing control] |
For each threat:
Compute up to three independent grades. Surfaces that were not scanned (because they were absent or out of scope) render as N/A and are excluded from the aggregate.
Step 1 β Per-category deductions:
For each category, start at 100 and deduct per finding within that category:
Floor each category at 0 (never go negative).
Category mapping for rules:
Step 2 β Weighted aggregate:
ConfigScore = SecretsΓ0.20 + PermissionsΓ0.15 + HooksΓ0.25 + MCPΓ0.25 + AgentsΓ0.15
Round to nearest integer. Map to letter grade.
Simplified alternative: If exact arithmetic is difficult, use per-category pass/fail:
Start at 100, deduct per OWASP finding:
Floor at 0. Map to letter grade.
Count of unmitigated threats:
| Score | Grade |
|---|---|
| 90β100 | A |
| 80β89 | B |
| 65β79 | C |
| 50β64 | D |
| 0β49 | F |
OverallScore = unweighted mean of the present grades among {ConfigScore, OWASPScore}. STRIDE contributes to OverallScore only as a β5 penalty per unmitigated threat (capped at β20). Surfaces marked N/A are skipped β never scored as 0 or 100.
If only one surface ran, OverallScore = <that surface's score> and the other appears as N/A in the report.
Run regardless of mode. In
mode=fix, this report is rendered before any fix prompts.
Print the following report in chat. Do not modify any files (file modifications happen in Phase 8 persistence and Phase 9 fix).
Severity indicators: π΄ critical, π‘ high, π’ medium, π΅ low, βͺ info
## π‘οΈ ATV Security Report
**Date:** YYYY-MM-DD
**Scope:** [config | owasp | stride | <path> | full]
**Surfaces scanned:** [config: yes/no/N/A] Β· [source: yes/no/N/A β stack: <detected>]
| Metric | Value |
|--------|-------|
| **Overall Grade** | [AβF or N/A] |
| **Config Grade** | [AβF]/[0β100] or N/A β no `.github/` configs |
| **OWASP Grade** | [AβF]/[0β100] or N/A β no application source |
| **STRIDE Posture** | [π’/π‘/π΄] or N/A |
### Config Category Breakdown _(omit if config N/A)_
| Category | Score | Status |
|----------|-------|--------|
| Secrets | [0β100] | [π’/π‘/π΄] |
| Permissions | [0β100] | [π’/π‘/π΄] |
| Hooks | [0β100] | [π’/π‘/π΄] |
| MCP Servers | [0β100] | [π’/π‘/π΄] |
| Agents & Skills | [0β100] | [π’/π‘/π΄] |
### Config Findings _(omit if config N/A)_
#### π΄ Critical
- **[RULE-ID] Title** in `file/path`
Evidence: `<matched text, truncated to 100 chars>`
Fix: <actionable fix suggestion>
#### π‘ High
- ...
#### π’ Medium
- ...
#### π΅ Low
- ...
### OWASP Findings _(omit if OWASP N/A)_
#### π΄ Critical
- **[A03] SQL Injection** in `src/db/queries.ts:42`
Evidence: `db.query("SELECT * FROM users WHERE id = " + userId)`
Fix: Use parameterized query: `db.query("SELECT * FROM users WHERE id = $1", [userId])`
#### π‘ High / π’ Medium / π΅ Low
- ...
### STRIDE Threat Matrix _(omit if STRIDE N/A)_
| Threat | Risk | Status |
|--------|------|--------|
| Spoofing | [H/M/L] | [β
Mitigated / β οΈ Partial / β Unmitigated] |
| Tampering | [H/M/L] | [β
/β οΈ/β] |
| Repudiation | [H/M/L] | [β
/β οΈ/β] |
| Info Disclosure | [H/M/L] | [β
/β οΈ/β] |
| Denial of Service | [H/M/L] | [β
/β οΈ/β] |
| Elevation of Privilege | [H/M/L] | [β
/β οΈ/β] |
### Summary
| Files scanned | Config findings | OWASP findings | STRIDE unmitigated | Auto-fixable |
|---------------|----------------|----------------|--------------------|--------------|
| [N] | [N] | [N] | [N] | [N] |
If zero findings across all run phases: report Grade A, all surfaces π’, and congratulate: "Your project looks secure! No findings detected."
After printing the report in chat, persist it to disk so it survives the conversation. Persistence happens immediately after Phase 7 β before the user is prompted for Fix Mode (Phase 9). This ensures the on-disk record reflects the un-fixed state of the scan; re-running with fixes applied will produce a new dated section on the next run.
Target file: docs/security/YYYY-MM-DD-security-report.md (today's date, UTC). One shared file per day. The file retains two marker blocks for backwards compatibility with reports written by the legacy /cso skill.
Marker semantics (post-merge):
<!-- atv-security:start --> ... <!-- atv-security:end --> block holds the config audit section.<!-- cso:start --> ... <!-- cso:end --> block holds the OWASP + STRIDE section. The block heading remains ## /cso Scan for backward compatibility, with a one-line subnote indicating it is now generated by /atv-security.Steps:
docs/security/ exists. If not, create it (write the file β the directory is created implicitly).YYYY-MM-DD and the run timestamp as ISO-8601 (e.g., 2026-04-26T14:32:10Z).read_file the target path.
create_file with this skeleton, then continue at step 4:
# Security Report β YYYY-MM-DD
<!-- atv-security:start -->
## /atv-security Scan
_No scan recorded yet._
<!-- atv-security:end -->
<!-- cso:start -->
## /cso Scan
_Generated by /atv-security after the /cso skill was folded in._
_No scan recorded yet._
<!-- cso:end -->
## /atv-security Scan β <ISO timestamp>
- **Mode:** report | fix
- **Scope:** full | config
- **Config Grade:** <AβF> Β· **Score:** <0β100>/100
- **Files scanned:** <N>
<full config-section markdown from Phase 7>
## /cso Scan β <ISO timestamp>
_Generated by /atv-security (formerly /cso)._
- **Scope:** full | owasp | stride | <path>
- **Stack:** <detected stack>
- **OWASP Grade:** <AβF or N/A> Β· **Score:** <0β100 or N/A>/100
- **STRIDE Posture:** π’/π‘/π΄ or N/A
<OWASP findings + STRIDE matrix from Phase 7>
replace_string_in_file to swap the matching marker block(s). Only update the block(s) corresponding to phases that actually ran β never wipe the other block.π Report saved to docs/security/YYYY-MM-DD-security-report.md.Constraints:
docs/security/YYYY-MM-DD-security-report.md.bak.<unix-timestamp> and warn the user that prior content was preserved in the backup.After persisting the report (Phase 8), apply safe fixes for auto-fixable findings. Fix mode applies only to config findings β OWASP/STRIDE findings are reported but never auto-fixed (changing application source code requires human review).
Auto-fixable rules: SEC-01 through SEC-05 (secretβenv var), MCP-02 (wildcardβscoped tools), MCP-04 (secretβenv var in MCP env).
Safety protocol:
Snapshot: Before touching any file, use read_file to load its entire content. Hold in context as rollback backup.
Present fix: Show the user a before/after diff for each proposed fix:
Fix [RULE-ID]: Replace hardcoded secret with env var reference
File: .github/copilot-mcp-config.json
Before: "ANTHROPIC_API_KEY": "sk-ant-abc123..."
After: "ANTHROPIC_API_KEY": "${ANTHROPIC_API_KEY}"
Apply? (y/n)
Confirm: Wait for explicit user confirmation before each fix.
Apply: Use replace_string_in_file to apply the change.
Validate: Re-read the file with read_file. Confirm JSON/YAML parses correctly:
Revert on failure: If validation fails, use replace_string_in_file with the saved original content to restore the file. Report the error to the user.
Summary: After all fixes, report: "Applied N fixes, skipped M. Re-run /atv-security to verify."
Constraints:
Every finding must include these fields:
| Field | Description |
|---|---|
| Rule ID | e.g., SEC-01, MCP-02, INJ-03, A03 (OWASP), STRIDE-S/T/R/I/D/E |
| Surface | Config / OWASP / STRIDE |
| Category | Secrets / Permissions / Hooks / MCP Servers / Agents & Skills (config) β or OWASP A01βA10 β or STRIDE letter |
| Severity | π΄ critical / π‘ high / π’ medium / π΅ low / βͺ info |
| Title | Short descriptive title |
| File | Repo-relative path to the affected file |
| Evidence | Matched text or assessment reason (truncated to 100 chars) |
| Fix | Actionable remediation suggestion |
| Auto-fixable | Yes/No β applies to config Tier 1 secret rules SEC-01βSEC-05 plus MCP-02 and MCP-04. OWASP/STRIDE findings are always No. |