Skip to content

Fixing Findings

When a scan produces findings, you need to triage each one: fix it, mark it as a false-positive, accept the risk, or defer remediation. This tutorial covers all four paths.

For each finding, ask:

  1. Is it real? Does the code actually have this issue?
  2. Is it a risk? Could it be exploited in your product’s context?
  3. Can you fix it now? Is remediation feasible in this release?
AnswerActionAPI Triage Action
Not realMark as false-positivefalse_positive
Real but acceptableDocument as accepted riskaccepted_risk
Real, fix laterDefer with review datedefer
Real, fix nowRemediate and re-scanreject + create remediation
Already compliantAcceptaccept

The most straightforward path — fix the issue and re-scan:

  1. Read the finding details:

    CRYPTO-01-R1 — Weak cryptographic algorithm MD5 detected
    src/utils/hash.py:12
  2. Fix the code:

    # Before (fail):
    import hashlib
    hash = hashlib.md5(data).hexdigest()
    # After (pass):
    import hashlib
    hash = hashlib.sha256(data).hexdigest()
  3. Re-scan:

    Terminal window
    fleet scan --path . --output pretty
  4. Verify the finding is now pass.

When the scanner flags something that isn’t actually a problem:

Terminal window
curl -X POST /api/v1/assessment/products/{id}/overrides \
-H "Authorization: Bearer $KEY" \
-d '{
"requirement_id": "CRYPTO-01-R1",
"override_type": "false_positive",
"justification": "MD5 is used for non-security cache key generation only. Not used for cryptographic purposes.",
"created_by": "james@crabnebula.dev"
}'

The finding will be suppressed in future scans. The override is tracked with who created it, when, and why.

When the finding is real but the risk is acceptable:

Terminal window
curl -X POST /api/v1/assessment/products/{id}/overrides \
-d '{
"requirement_id": "NET-SVC-02-R1",
"override_type": "accepted_risk",
"justification": "Rate limiting not implemented for internal API. Only accessible from VPN. Risk accepted per risk assessment RA-2026-015.",
"created_by": "security-team"
}'

Accepted risks are treated as compliant in the gap analysis — the justification serves as the evidence.

When you plan to fix it but not in this release:

Terminal window
curl -X POST /api/v1/assessment/products/{id}/overrides \
-d '{
"requirement_id": "NET-SVC-02-R1",
"override_type": "deferred",
"justification": "Rate limiting planned for v1.2 release (ENG-456)",
"created_by": "james@crabnebula.dev",
"review_date": "2026-06-01T00:00:00Z"
}'

Deferred findings remain visible in gap analysis as in_progress.

For confirmed findings that need a fix, create a remediation record:

Terminal window
curl -X POST /api/v1/assessment/products/{id}/remediations \
-d '{
"requirement_id": "CRYPTO-01-R1",
"description": "Replace MD5 with SHA-256 for all hash operations",
"created_by": "james@crabnebula.dev",
"assigned_to": "dev-team",
"ticket_url": "https://linear.app/team/ENG-123",
"pull_request_url": "https://github.com/org/repo/pull/42"
}'

Track the fix through its lifecycle:

Terminal window
# Move to in_progress
curl -X PUT /api/v1/assessment/remediations/{id}/status \
-d '{"status": "implemented"}'
# Verify with a scan
curl -X POST /api/v1/assessment/remediations/{id}/verify \
-d '{"verified_by": "qa-team", "scan_id": "uuid-of-verification-scan"}'

Process multiple findings at once:

Terminal window
curl -X POST /api/v1/assessment/products/{id}/triage \
-d '{
"triaged_by": "james@crabnebula.dev",
"actions": [
{ "requirement_id": "CRYPTO-01-R1", "action": "reject", "justification": "Confirmed, needs fix" },
{ "requirement_id": "NET-SVC-04-R2", "action": "false_positive", "justification": "Debug endpoint is test-only" },
{ "requirement_id": "LOG-PROT-01-R2", "action": "accept", "justification": "Verified tokens are redacted" }
]
}'

For requirements that need documentation:

Terminal window
curl -X POST /api/v1/assessment/products/{id}/evidence/upload \
-d '{
"requirement_id": "VH-DISC-01-R1",
"evidence_type": "doc",
"content": "Coordinated disclosure policy published at https://example.com/security-policy. 90-day timeline, PGP channel available.",
"created_by": "security-team"
}'

After making code changes, re-scan to verify:

Terminal window
fleet scan --path . --output pretty

Previously failed findings should now show as pass. The new scan creates fresh evidence records — old records are preserved for the audit trail.