Prove a security finding
Prove reachability for scanner findings against a repository snapshot, triage by classification, and re-prove that a fix closes the finding after you patch it.
Static scanners produce long lists of findings, most of which are never reachable in the running application. Algenta's security analysis takes a batch of scanner findings plus a repository snapshot and returns a proof for each one: whether the sink is reachable from an entrypoint, the dataflow path that reaches it, and how sound that verdict is. After you ship a fix, a closure call re-proves the same finding against the patched snapshot so you can show it is genuinely closed — not just filtered.
This is a triage-and-verify workflow: create the analysis on a snapshot, read the proofs to decide what to fix, patch it, then re-prove closure. All routes live under /v1/repositories and require Authorization: Bearer $ALGENTA_API_KEY.
Before you start
You need:
$REPOSITORY_ID— the connector id (see Connect data).$SNAPSHOT_ID— an immutable snapshot of the ref you scanned. Create one as shown in Triage a repository; the analysis is cached against it.A scanner run: its
sarif_digest, the scannername, and thefindingsyou want proven — each with a stablecanonical_id, itsrule_id, afinding_kind, and aprimary_location.
Analyze a batch of findings
Post the snapshot, the scanner descriptor, and the findings. The engine proves each finding's reachability and caches the result against the snapshot, so re-submitting the same batch is cheap.
POST /v1/repositories/{repository_id}/security-analyses
curl -sS -X POST "https://api.algenta.ai/v1/repositories/$REPOSITORY_ID/security-analyses" \
-H "Authorization: Bearer $ALGENTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"snapshot_id": "'"$SNAPSHOT_ID"'",
"sarif_digest": "sha256:9c1f...",
"scanner": { "name": "example-scanner", "version": "2.17.0" },
"findings": [
{
"canonical_id": "finding-sql-injection-001",
"rule_id": "py/sql-injection",
"finding_kind": "sql-injection",
"severity": "high",
"primary_location": { "uri": "src/api/orders.py", "start_line": 142 }
}
]
}'import os
import httpx
repo_id = os.environ["REPOSITORY_ID"]
resp = httpx.post(
f"https://api.algenta.ai/v1/repositories/{repo_id}/security-analyses",
headers={"Authorization": f"Bearer {os.environ['ALGENTA_API_KEY']}"},
json={
"snapshot_id": os.environ["SNAPSHOT_ID"],
"sarif_digest": "sha256:9c1f...",
"scanner": {"name": "example-scanner", "version": "2.17.0"},
"findings": [
{
"canonical_id": "finding-sql-injection-001",
"rule_id": "py/sql-injection",
"finding_kind": "sql-injection",
"severity": "high",
"primary_location": {"uri": "src/api/orders.py", "start_line": 142},
}
],
},
timeout=300.0,
)
analysis = resp.json()
for proof in analysis["proofs"]:
print(proof["canonical_finding_id"], proof["classification"], proof["proof_type"])Read the proofs
Each proof classifies one finding and shows the evidence behind the verdict:
Use these fields to triage:
classification
The headline verdict: exploitable, production-reachable, unreachable, or unknown.
proof_type
How the verdict was reached: dataflow, entrypoint_reachability, absence_proof, off_matrix, or no_evidence.
analysis_envelope.is_complete_sound
Whether the analysis was sound and complete for this finding's language and framework.
entrypoints / sinks / propagation_paths
The concrete path that makes the sink reachable — the evidence to hand a reviewer.
sanitizers
Sanitizers found on the path that may neutralize the flow.
scanner_flow_validation
Whether your scanner's own flow corroborates the engine's path.
Fix exploitable and production-reachable findings first, and deprioritize unreachable ones. Treat unknown (and any proof whose analysis_envelope.is_complete_sound is false) as needing a human look rather than an automatic dismissal.
Re-prove closure after a fix
Once you have patched and merged the fix (for example through Fix a repository), create a new snapshot of the patched ref and re-prove the finding against it. Closure asks one question: is the original finding still reachable?
POST /v1/repositories/{repository_id}/security-analyses/closure
The 200 SecurityAnalysisClosureResponse returns:
closure_status—closed(the fix removed reachability),open(still reachable), orunknown(the engine could not prove either way).alternate_path_found—trueif the finding is now reachable by a different path than the one you fixed.new_blocking_findings— canonical ids of any new findings the patch introduced that block closure.
Next steps
Last updated
Was this helpful?