- 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.
369 lines
9.4 KiB
Markdown
369 lines
9.4 KiB
Markdown
# 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)
|