Skip to main content

Scenario 14: Security-incident investigation

Trace security-incident impact while keeping investigation separate from containment, remediation, postmortem, and closure.

User Guides

Scenario 14 traces callers, entry points, vulnerable usages, and available data-flow evidence for a named incident question. It supports investigation; the incident owner performs the operational response and records closure.

Start with a bounded question

Use a CVE identifier, vulnerable function, exposed endpoint, or observed exploit path. Bind the question to an incident record, source revision, affected environment, and observation time. Never paste secrets, credentials, customer payloads, or unrestricted logs into the query.

If the issue is a proactive hypothesis rather than an active incident, use the security hypothesis workflow separately. It is not the Scenario 14 entry point.

Run the dedicated CLI

Prepare the environment using the CLI guide. Run in PowerShell from the CodeGraph repository root with an existing CPG and an accessible GoCPG gRPC service. Replace the quoted placeholders. For the CLI, use the actual vulnerable function name: the command passes the query directly to call-graph analysis and does not resolve a CVE description into a symbol.

python -m src.cli security incident "<function-name>" --db "<cpg-path>" --format json

Optional --max-depth limits call-graph traversal. Preserve the command, CPG revision, query, and output together. Missing --db fails closed with security incident requires explicit --db for CPG access.

The CLI JSON contains query, direct_callers, transitive_callers, impact_score and entry_points. It does not produce taint-flow findings or prove exploitability. Status 0 means the command completed, not that the incident is resolved. Status 1 can indicate missing graph scope or an analysis error.

How the CLI builds the report

The command passes the function name to the call-graph analyzer. It finds direct callers, then follows caller chains upstream to the --max-depth limit. This connects the defect location to handlers that use the code in the application.

How the CLI builds the report
Field How to use it
query Match the function name to the source revision under investigation.
direct_callers Start with methods that call the function directly.
transitive_callers Inspect callers farther upstream within the configured depth.
impact_score Use the coupling estimate to compare change scopes; assess exploitability from inputs and call conditions.
entry_points Open each candidate’s file and line, then check how the application supplies its inputs.

The impact_score expresses the affected-method count relative to 10% of the graph methods. The analyzer counts unique methods in caller and callee chains, divides that count by total_methods * 0.1, and caps the result at 1. For example, a graph with 1000 methods and 25 affected methods produces a score of 0.25.

When the function has more than 100 direct callers, impact analysis counts affected methods through direct links. In this branch, the report has an empty transitive_callers list: direct callers are already included in direct_callers. The entry_points search runs a separate traversal up to --max-depth.

For entry_points, the analyzer selects callers with no incoming calls (fan_in = 0), methods with common handler names, and entry points configured by the language or domain plugin. For example, in the chain route_handler → parse_request → decode_payload, investigating decode_payload helps locate the handler and intermediate parser. Compare the chain with application routing, input formats, and tests for untrusted input.

Run the typed AppSec scenario

Use the role-bound route when the governed AppSec task and runtime context are available:

from src.digital_employees.runtime.scenarios import (
    RoleBoundScenarioInvocationRequest,
    invoke_role_bound_scenario_request,
)

request = RoleBoundScenarioInvocationRequest(
    query="Trace callers and entry points reaching the vulnerable parser.",
    employee_id="codegraph_appsec",
    scenario_id="scenario_14",
    event_type="appsec_start",
    context={
        "project_key": "codegraph",
        "namespace": "default",
        "task_id": "<task-id>",
        "source_refs": ["<incident-ref>", "<revision-ref>"],
        "file_paths": ["<bounded-source-path>"],
    },
)
result = invoke_role_bound_scenario_request(request)
if result.get("error"):
    raise RuntimeError(result["error"])
if not result.get("scenario_id") or not result.get("answer"):
    raise RuntimeError("Scenario returned no scenario identity or answer")
print(result["answer"])

The CLI and typed route are different evidence carriers. Record which one produced each finding.

Read the result

Use the result to prioritize manual verification of direct and transitive callers, entry points, vulnerable usages, attack paths, and taint-flow observations. Validate critical paths in the bound source and affected environment.

Compare recommendations with the code, input data, and incident logs. If a path is empty, check the exact symbol name, traversal depth, and whether the required methods are present in the CPG. Supplement runtime-only relationships with observations from the affected environment.

From analysis to response

Give the incident owner the report, source revision, and verified paths. For each response stage, record the action, accountable owner, and verification result:

From analysis to response
Stage Action and result
containment The incident owner isolates the affected environment through the response procedure and verifies the restriction.
remediation The developer fixes the confirmed path, adds a regression test, and repeats analysis on the corrected revision.
postmortem The team records the cause, detection sequence, and measures to prevent recurrence.
governed closure The incident owner collects correction, test, and recovery results, then records the closure decision.

The operational plan names who rotates secrets, restricts traffic, deploys the correction, and notifies stakeholders. CodeGraph call chains help identify the handlers and checks that belong in that plan.

Failure and recovery

  • Explicit database rejected or unavailable: stop and restore the intended revision-bound CPG.
  • No matching function: check the exact symbol, language coverage, entry point, and traversal depth.
  • Partial or fallback result: label it as preliminary and obtain source/runtime evidence before action.
  • Active exploitation or unsafe environment: follow the customer’s incident command process; do not wait for CodeGraph analysis.