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.
This commit is contained in:
368
docs/airgap/reachability-drift-airgap-workflows.md
Normal file
368
docs/airgap/reachability-drift-airgap-workflows.md
Normal file
@@ -0,0 +1,368 @@
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```csharp
|
||||
// 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:
|
||||
|
||||
```bash
|
||||
# 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
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
# 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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
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:
|
||||
|
||||
```bash
|
||||
# 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>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Smart-Diff Air-Gap Workflows](smart-diff-airgap-workflows.md)
|
||||
- [Offline Bundle Format](offline-bundle-format.md)
|
||||
- [Air-Gap Operations](operations.md)
|
||||
- [Staleness and Time](staleness-and-time.md)
|
||||
- [Sealing and Egress](sealing-and-egress.md)
|
||||
Reference in New Issue
Block a user