plugins/compliance/skills/call-graph-analysis/SKILL.md
Perform definitive call graph analysis to prove whether vulnerable functions are reachable from program entry points
npx skillsauth add openshift-eng/ai-helpers call-graph-analysisInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Provides highest-confidence vulnerability assessment by proving whether vulnerable functions can actually be reached during program execution.
Use this skill when:
govulncheck is unavailable or didn't find the CVEcallgraph: go install golang.org/x/tools/cmd/callgraph@latestdigraph: go install golang.org/x/tools/cmd/digraph@latestgo.mod filegraphviz (for visualization): brew install graphviz (macOS) or sudo apt-get install graphviz (Linux)sfdp or dot command (part of graphviz)<package-path>.<function-name>)vta) — passed via --algo from parent commandCVE_ID — used to construct the output directoryOUT_DIR (optional, default: .work/compliance/analyze-cve/${CVE_ID}) — where artifacts are written--algo (default: vta).callgraph invocations use timeout 300 (5 minutes) to prevent hanging on large codebases.vta → rta → cha), then narrow scope to specific packages (e.g., ./cmd/..., ./pkg/...).# Check for callgraph
which callgraph || echo "callgraph not found - install with: go install golang.org/x/tools/cmd/callgraph@latest"
# Check for digraph
which digraph || echo "digraph not found - install with: go install golang.org/x/tools/cmd/digraph@latest"
# Optional: Check for graphviz
which sfdp || echo "graphviz not found - visual graphs won't be generated (optional)"
Decision Point:
# ALGO defaults to "vta" unless user specified --algo
ALGO="${USER_ALGO:-vta}"
# Output directory — aligns with parent command report location
OUT_DIR="${OUT_DIR:-.work/compliance/analyze-cve/${CVE_ID}}"
mkdir -p "${OUT_DIR}"
# Build call graph from workspace root
# Timeout after 300s (5 minutes) to avoid hanging on large codebases
timeout 300 callgraph -algo "${ALGO}" -format=digraph . > "${OUT_DIR}/callgraph.txt"
Error Handling:
vta → rta → cha) and retrytimeout 300 callgraph -algo rta -format=digraph ./cmd/... ./pkg/... > "${OUT_DIR}/callgraph.txt"Output: ${OUT_DIR}/callgraph.txt containing the full program call graph
Extract the vulnerable function signature from CVE details.
# Search for exact function in the cached call graph
VULN_FUNC="<package-path>.<vulnerable-function>"
cat "${OUT_DIR}/callgraph.txt" | digraph nodes | grep "${VULN_FUNC}$"
Decision Point:
Search for paths from main entry points to the vulnerable function.
# Find path from main() to vulnerable function using cached call graph
ENTRY_POINT="command-line-arguments.main"
VULN_FUNC="<package-path>.<vulnerable-function>"
cat "${OUT_DIR}/callgraph.txt" | \
digraph somepath "${ENTRY_POINT}" "${VULN_FUNC}"
Alternative Entry Points to Check:
command-line-arguments.main (main program)*_test.go test functions*.initInterpretation:
Output: Text representation of call chain or empty result
If path exists, generate visual representation:
# Generate DOT format from cached call graph
cat "${OUT_DIR}/callgraph.txt" | \
digraph somepath "${ENTRY_POINT}" "${VULN_FUNC}" | \
digraph to dot > "${OUT_DIR}/callgraph.dot"
# Convert to SVG (if graphviz available)
if which sfdp > /dev/null; then
sfdp -Tsvg -o"${OUT_DIR}/callgraph.svg" -Goverlap=scale "${OUT_DIR}/callgraph.dot"
echo "Visual graph saved to: ${OUT_DIR}/callgraph.svg"
else
echo "Graphviz not available - DOT file saved to: ${OUT_DIR}/callgraph.dot"
fi
Output Files:
${OUT_DIR}/callgraph.dot - DOT notation of call path${OUT_DIR}/callgraph.svg - Visual graph (if graphviz available)Extract human-readable call chain from digraph output:
# Get call chain as text from cached call graph
cat "${OUT_DIR}/callgraph.txt" | \
digraph somepath "${ENTRY_POINT}" "${VULN_FUNC}" | \
digraph to dot | \
grep " -> " | \
sed 's/"//g' | \
sed 's/;//g'
Example Output:
command-line-arguments.main -> <package-path>.Handler
<package-path>.Handler -> <package-path>.ProcessFunction
<package-path>.ProcessFunction -> <vulnerable-package>.<vulnerable-function>
Format for Report:
Execution Path Found:
main → Handler → ProcessFunction → <vulnerable-function> (VULNERABLE)
HIGH RISK:
MEDIUM RISK:
LOW RISK:
Return structured result to parent analysis:
{
"method": "call-graph-reachability",
"algorithm": "vta",
"vulnerable_function": "<package-path>.<vulnerable-function>",
"found_in_graph": true,
"reachable_from_main": true,
"call_chain": "main → Handler → ProcessFunction → <vulnerable-function>",
"risk_level": "HIGH",
"evidence": {
"callgraph_file": "${OUT_DIR}/callgraph.txt",
"dot_file": "${OUT_DIR}/callgraph.dot",
"svg_file": "${OUT_DIR}/callgraph.svg"
}
}
vta → rta → cha)timeout 300 callgraph -algo rta -format=digraph ./cmd/... ./pkg/... > "${OUT_DIR}/callgraph.txt"command-line-arguments.main not found → Look for other entry points# Setup: set CVE_ID and output directory
$ CVE_ID="CVE-YYYY-NNNNN"
$ OUT_DIR=".work/compliance/analyze-cve/${CVE_ID}"
$ mkdir -p "${OUT_DIR}"
# Step 1: Build call graph (default: vta; user can override with --algo)
$ timeout 300 callgraph -algo vta -format=digraph . > "${OUT_DIR}/callgraph.txt"
# Step 2: Check if function is called
$ cat "${OUT_DIR}/callgraph.txt" | digraph nodes | grep "<package-path>.<vulnerable-function>$"
<package-path>.<vulnerable-function>
# Step 3: Find path from main
$ cat "${OUT_DIR}/callgraph.txt" | digraph somepath command-line-arguments.main <package-path>.<vulnerable-function>
digraph {
"command-line-arguments.main" -> "<app-package>.Handler";
"<app-package>.Handler" -> "<app-package>.ProcessFunction";
"<app-package>.ProcessFunction" -> "<intermediate-package>.HelperFunction";
"<intermediate-package>.HelperFunction" -> "<vulnerable-package>.<vulnerable-function>";
}
# Step 4: Generate visual graph
$ cat "${OUT_DIR}/callgraph.txt" | digraph somepath command-line-arguments.main <package-path>.<vulnerable-function> | digraph to dot | sfdp -Tsvg -o"${OUT_DIR}/callgraph.svg"
# Result: HIGH RISK — reachable path found
# Call chain: main → Handler → ProcessFunction → HelperFunction → <vulnerable-function>
This skill is called from Method 4 of the codebase-impact-analysis skill.
When to Invoke:
Return to Parent:
tools
Analyze a JIRA issue and create a pull request to solve it. Use when the user wants to implement a fix or feature described in a Jira issue, push a branch, and open a draft PR.
development
Use when a deeper level of code review is requested. Multi-agent panel code review with specialist reviewers and forced runtime reproducers for all BLOCKING bug findings. Optionally posts to GitHub/GitLab as a PENDING review.
development
Review agentic documentation — verify claims locally against source code first, then use chai-bot for cross-repo and cross-functional verification
development
Use this skill when debugging a failed Prow CI job.