6.6 KiB
Runtime Linkage Verification Guide
Ownership: Scanner Guild / Signals Guild Services:
StellaOps.Scanner.Reachability.FunctionMapAPI:POST /api/v1/function-maps,POST /api/v1/function-maps/{id}/verifyCLI:stella function-map generate|verify,stella observations query
What is Runtime Linkage Verification?
Runtime linkage verification bridges the gap between static analysis (what code could run) and runtime observation (what code actually runs). It works by:
- Generating a function map from static analysis (SBOM + call graph) that declares expected call paths
- Deploying probes (eBPF uprobes/kprobes) to observe actual function invocations at runtime
- Verifying that observed call patterns match the expected static model
This produces a confidence metric (observation rate) quantifying how much of the declared attack surface has been confirmed by runtime evidence.
When to Use Function Maps
| Scenario | Benefit |
|---|---|
| High-risk vulnerabilities | Confirm whether vulnerable code paths are actually exercised |
| Reachability disputes | Resolve static "maybe reachable" findings with runtime evidence |
| Compliance audits | Provide cryptographic proof of runtime behavior |
| Air-gapped environments | Bundle function maps and observations for offline verification |
| Continuous monitoring | Track coverage drift over deployment lifecycle |
Step-by-Step Guide
1. Generate a Function Map
Create a function map predicate from your SBOM and optional static analysis:
stella function-map generate \
--sbom ./app.cdx.json \
--service my-backend \
--hot-functions "crypto/*" --hot-functions "auth/*" \
--min-rate 0.95 \
--window 1800 \
--output function-map.json
Key options:
--hot-functions: Glob patterns for functions of interest (crypto, auth, network are common)--min-rate: Minimum observation rate to consider "verified" (default 0.95 = 95%)--window: Observation window in seconds (default 1800 = 30 minutes)--static-analysis: Path to static analysis results for richer call paths
The output is a JSON predicate conforming to https://stella.ops/predicates/function-map/v1.
2. Deploy Probes
Configure the Stella runtime agent to attach probes for the functions declared in your map. The agent uses eBPF to observe function calls without modifying application code.
Supported probe types:
uprobe/uretprobe— User-space function entry/exitkprobe/kretprobe— Kernel function entry/exittracepoint— Kernel tracepointsusdt— User-space statically defined tracing
The runtime agent writes observations in NDJSON format with fields:
node_hash— SHA-256(PURL + normalized symbol)function_name— Observed function symbolprobe_type— How it was observedobserved_at— Timestampcontainer_id,pod_name,namespace— Context
3. Verify Observations Against the Map
After accumulating observations, verify coverage:
stella function-map verify \
--function-map function-map.json \
--from "2026-01-23T00:00:00Z" \
--to "2026-01-23T01:00:00Z" \
--format table
For offline verification with a bundled observations file:
stella function-map verify \
--function-map function-map.json \
--offline \
--observations observations.ndjson \
--format json
Output includes:
verified: Whether observation rate meets the thresholdobservation_rate: Fraction of expected paths confirmed (0.0-1.0)target_rate: Required rate from the function mapper_path_breakdown: Status of each declared call pathunexpected_symbols: Functions observed but not in the mapmissing_symbols: Expected functions not yet observed
4. Upload to Platform (Optional)
Store function maps in the Platform for centralized management:
# Create via API
curl -X POST /api/v1/function-maps \
-H "Content-Type: application/json" \
-d @function-map.json
# Verify via API
curl -X POST /api/v1/function-maps/{id}/verify \
-H "Content-Type: application/json" \
-d '{"observations": [...]}'
# Check coverage dashboard
curl GET /api/v1/function-maps/{id}/coverage
Predicate Schema
Function maps use the in-toto attestation framework with predicate type:
https://stella.ops/predicates/function-map/v1
See Function Map V1 Contract for the full schema specification.
Integration with Air-Gap Bundles
Function maps, observations, and verification reports can be included in offline bundles:
bundle.stella.bundle.tgz
├── function-maps/
│ ├── {service}-function-map.json
│ └── {service}-function-map.dsse.json
├── observations/
│ └── {date-label}-observations.ndjson
└── verification/
├── verification-report.json
└── verification-report.dsse.json
See Offline Bundle Format for artifact type details.
Troubleshooting
Low Observation Rate
Symptom: Verification reports observation_rate < target_rate.
Causes:
- Observation window too short — increase
--windowor widen--from/--to - Probes not attached — check runtime agent logs for attachment failures
- Application hasn't exercised the code paths — generate representative load
- Binary stripped or ASLR — provide
--binary-pathhints in the function map
Resolution:
- Use
stella observations query --summaryto see what's been collected - Check per-path breakdown for which specific paths are unobserved
- Extend the observation window or trigger relevant application behavior
Unexpected Symbols
Symptom: Verification reports unexpected function calls not in the map.
Causes:
- Dynamic dispatch or reflection invoking functions not in static analysis
- Shared libraries loaded at runtime that weren't in the SBOM
- Hot functions pattern too narrow
Resolution:
- Regenerate the function map with broader
--hot-functionspatterns - Add the unexpected symbols as optional paths if they're benign
- Set
--fail-on-unexpected falseif unexpected calls should be informational only
Node Hash Mismatch
Symptom: Observations exist but don't match expected node hashes.
Causes:
- PURL mismatch between SBOM and runtime (version drift)
- Symbol name normalization differences (C++ mangling, etc.)
Resolution:
- Verify the PURL in observations matches the function map subject
- Check that symbol names are normalized consistently (same demangling rules)
- Regenerate the function map with the current deployed SBOM version