Files
git.stella-ops.org/docs/airgap/reachability-drift-airgap-workflows.md
master 8779e9226f feat: add stella-callgraph-node for JavaScript/TypeScript call graph extraction
- Implemented a new tool `stella-callgraph-node` that extracts call graphs from JavaScript/TypeScript projects using Babel AST.
- Added command-line interface with options for JSON output and help.
- Included functionality to analyze project structure, detect functions, and build call graphs.
- Created a package.json file for dependency management.

feat: introduce stella-callgraph-python for Python call graph extraction

- Developed `stella-callgraph-python` to extract call graphs from Python projects using AST analysis.
- Implemented command-line interface with options for JSON output and verbose logging.
- Added framework detection to identify popular web frameworks and their entry points.
- Created an AST analyzer to traverse Python code and extract function definitions and calls.
- Included requirements.txt for project dependencies.

chore: add framework detection for Python projects

- Implemented framework detection logic to identify frameworks like Flask, FastAPI, Django, and others based on project files and import patterns.
- Enhanced the AST analyzer to recognize entry points based on decorators and function definitions.
2025-12-19 18:11:59 +02:00

9.4 KiB

Reachability Drift Air-Gap Workflows

Sprint: SPRINT_3600_0001_0001
Task: RDRIFT-MASTER-0006 - Document air-gap workflows for reachability drift

Overview

Reachability Drift Detection can operate in fully air-gapped environments using offline bundles. This document describes the workflows for running reachability drift analysis without network connectivity, building on the Smart-Diff air-gap patterns.

Prerequisites

  1. Offline Kit - Downloaded and verified (stellaops offline kit download)
  2. Feed Snapshots - Pre-staged vulnerability feeds and surfaces
  3. Call Graph Cache - Pre-extracted call graphs for target artifacts
  4. Vulnerability Surface Bundles - Pre-computed trigger method mappings

Key Differences from Online Mode

Aspect Online Mode Air-Gap Mode
Surface Queries Real-time API Local bundle lookup
Call Graph Extraction On-demand Pre-computed + cached
Graph Diff Direct comparison Bundle-to-bundle
Attestation Online transparency log Offline DSSE bundle
Metrics Telemetry enabled Local-only metrics

Workflow 1: Offline Reachability Drift Analysis

Step 1: Prepare Offline Bundle with Call Graphs

On a connected machine:

# Download offline kit with reachability bundles
stellaops offline kit download \
  --output /path/to/offline-bundle \
  --include-feeds nvd,osv,epss \
  --include-surfaces \
  --feed-date 2025-01-15

# Pre-extract call graphs for known artifacts
stellaops callgraph extract \
  --artifact registry.example.com/app:v1 \
  --artifact registry.example.com/app:v2 \
  --output /path/to/offline-bundle/callgraphs \
  --languages dotnet,nodejs,java,go,python

# Include vulnerability surface bundles
stellaops surfaces export \
  --cve-list /path/to/known-cves.txt \
  --output /path/to/offline-bundle/surfaces \
  --format ndjson

# Package for transfer
stellaops offline kit package \
  --input /path/to/offline-bundle \
  --output stellaops-reach-offline-2025-01-15.tar.gz \
  --sign

Step 2: Transfer to Air-Gapped Environment

Transfer the bundle using approved media:

  • USB drive (scanned and approved)
  • Optical media (DVD/Blu-ray)
  • Data diode

Step 3: Import Bundle

On the air-gapped machine:

# Verify bundle signature
stellaops offline kit verify \
  --input stellaops-reach-offline-2025-01-15.tar.gz \
  --public-key /path/to/signing-key.pub

# Extract and configure
stellaops offline kit import \
  --input stellaops-reach-offline-2025-01-15.tar.gz \
  --data-dir /opt/stellaops/data

Step 4: Run Reachability Drift Analysis

# Set offline mode
export STELLAOPS_OFFLINE=true
export STELLAOPS_DATA_DIR=/opt/stellaops/data
export STELLAOPS_SURFACES_DIR=/opt/stellaops/data/surfaces
export STELLAOPS_CALLGRAPH_CACHE=/opt/stellaops/data/callgraphs

# Run reachability drift
stellaops reach-drift \
  --base-scan scan-v1.json \
  --current-scan scan-v2.json \
  --base-callgraph callgraph-v1.json \
  --current-callgraph callgraph-v2.json \
  --output drift-report.json \
  --format json

Workflow 2: Pre-Computed Drift Export

For environments that cannot run the full analysis, pre-compute drift results on a connected machine and export them for review.

Step 1: Pre-Compute Drift Results

# On connected machine: compute drift
stellaops reach-drift \
  --base-scan scan-v1.json \
  --current-scan scan-v2.json \
  --output drift-results.json \
  --include-witnesses \
  --include-paths

# Generate offline viewer bundle
stellaops offline viewer export \
  --drift-report drift-results.json \
  --output drift-viewer-bundle.html \
  --self-contained

Step 2: Transfer and Review

The self-contained HTML viewer can be opened in any browser on the air-gapped machine without additional dependencies.


Workflow 3: Incremental Call Graph Updates

For environments that need to update call graphs without full re-extraction.

Step 1: Export Graph Delta

On connected machine after code changes:

# Extract delta since last snapshot
stellaops callgraph delta \
  --base-snapshot callgraph-v1.json \
  --current-source /path/to/code \
  --output graph-delta.json

Step 2: Apply Delta in Air-Gap

# Merge delta into existing graph
stellaops callgraph merge \
  --base /opt/stellaops/data/callgraphs/app-v1.json \
  --delta graph-delta.json \
  --output /opt/stellaops/data/callgraphs/app-v2.json

Bundle Contents

Call Graph Bundle Structure

callgraphs/
├── manifest.json           # Bundle metadata
├── checksums.sha256        # Content hashes
├── app-v1/
│   ├── snapshot.json       # CallGraphSnapshot
│   ├── entrypoints.json    # Entrypoint index
│   └── sinks.json          # Sink index
└── app-v2/
    ├── snapshot.json
    ├── entrypoints.json
    └── sinks.json

Surface Bundle Structure

surfaces/
├── manifest.json           # Bundle metadata
├── checksums.sha256        # Content hashes
├── by-cve/
│   ├── CVE-2024-1234.json  # Surface + triggers
│   └── CVE-2024-5678.json
└── by-package/
    ├── nuget/
    │   └── Newtonsoft.Json/
    │       └── surfaces.ndjson
    └── npm/
        └── lodash/
            └── surfaces.ndjson

Offline Surface Query

When running in air-gap mode, the surface query service automatically uses local bundles:

// Configuration for air-gap mode
services.AddSingleton<ISurfaceQueryService>(sp =>
{
    var options = sp.GetRequiredService<IOptions<AirGapOptions>>().Value;
    
    if (options.Enabled)
    {
        return new OfflineSurfaceQueryService(
            options.SurfacesBundlePath,
            sp.GetRequiredService<ILogger<OfflineSurfaceQueryService>>());
    }
    
    return sp.GetRequiredService<OnlineSurfaceQueryService>();
});

Attestation in Air-Gap Mode

Reachability drift results can be attested even in offline mode using pre-provisioned signing keys:

# Sign drift results with offline key
stellaops attest sign \
  --input drift-results.json \
  --predicate-type https://stellaops.io/attestation/reachability-drift/v1 \
  --key /opt/stellaops/keys/signing-key.pem \
  --output drift-attestation.dsse.json

# Verify attestation (offline)
stellaops attest verify \
  --input drift-attestation.dsse.json \
  --trust-root /opt/stellaops/keys/trust-root.json

Staleness Considerations

Call Graph Freshness

Call graphs should be re-extracted when:

  • Source code changes significantly
  • Dependencies are updated
  • Framework versions change

Maximum recommended staleness: 7 days for active development, 30 days for stable releases.

Surface Bundle Freshness

Surface bundles should be updated when:

  • New CVEs are published
  • Vulnerability details are refined
  • Trigger methods are updated

Maximum recommended staleness: 24 hours for high-security environments, 7 days for standard environments.

Staleness Indicators

# Check bundle freshness
stellaops offline status \
  --data-dir /opt/stellaops/data

# Output:
# Bundle Type      | Last Updated        | Age    | Status
# -----------------|---------------------|--------|--------
# NVD Feed         | 2025-01-15T00:00:00 | 3 days | OK
# OSV Feed         | 2025-01-15T00:00:00 | 3 days | OK
# Surfaces         | 2025-01-14T12:00:00 | 4 days | WARNING
# Call Graphs (v1) | 2025-01-10T08:00:00 | 8 days | STALE

Determinism Requirements

All offline workflows must produce deterministic results:

  1. Call Graph Extraction - Same source produces identical graph hash
  2. Drift Detection - Same inputs produce identical drift report
  3. Path Witnesses - Same reachability query produces identical paths
  4. Attestation - Signature over canonical JSON (sorted keys, no whitespace)

Verification:

# Verify determinism
stellaops reach-drift \
  --base-scan scan-v1.json \
  --current-scan scan-v2.json \
  --output drift-1.json

stellaops reach-drift \
  --base-scan scan-v1.json \
  --current-scan scan-v2.json \
  --output drift-2.json

# Must be identical
diff drift-1.json drift-2.json
# (no output = identical)

Troubleshooting

Missing Surface Data

Error: No surface found for CVE-2024-1234 in package pkg:nuget/Newtonsoft.Json@12.0.1

Resolution: Update surface bundle or fall back to package-API-level reachability:

stellaops reach-drift \
  --fallback-mode package-api \
  ...

Call Graph Extraction Failure

Error: Failed to extract call graph - missing language support for 'rust'

Resolution: Pre-extract call graphs on a machine with required tooling, or skip unsupported languages:

stellaops callgraph extract \
  --skip-unsupported \
  ...

Bundle Signature Verification Failure

Error: Bundle signature invalid - public key mismatch

Resolution: Ensure correct public key is used, or re-download bundle:

# List available trust roots
stellaops offline trust-roots list

# Import new trust root (requires approval)
stellaops offline trust-roots import \
  --key new-signing-key.pub \
  --fingerprint <expected-fingerprint>