Files
git.stella-ops.org/docs/product-advisories/archived/23-Dec-2026 - Binary Mapping as Attestable Proof.md
master ef933db0d8 feat(cli): Implement crypto plugin CLI architecture with regional compliance
Sprint: SPRINT_4100_0006_0001
Status: COMPLETED

Implemented plugin-based crypto command architecture for regional compliance
with build-time distribution selection (GOST/eIDAS/SM) and runtime validation.

## New Commands

- `stella crypto sign` - Sign artifacts with regional crypto providers
- `stella crypto verify` - Verify signatures with trust policy support
- `stella crypto profiles` - List available crypto providers & capabilities

## Build-Time Distribution Selection

```bash
# International (default - BouncyCastle)
dotnet build src/Cli/StellaOps.Cli/StellaOps.Cli.csproj

# Russia distribution (GOST R 34.10-2012)
dotnet build -p:StellaOpsEnableGOST=true

# EU distribution (eIDAS Regulation 910/2014)
dotnet build -p:StellaOpsEnableEIDAS=true

# China distribution (SM2/SM3/SM4)
dotnet build -p:StellaOpsEnableSM=true
```

## Key Features

- Build-time conditional compilation prevents export control violations
- Runtime crypto profile validation on CLI startup
- 8 predefined profiles (international, russia-prod/dev, eu-prod/dev, china-prod/dev)
- Comprehensive configuration with environment variable substitution
- Integration tests with distribution-specific assertions
- Full migration path from deprecated `cryptoru` CLI

## Files Added

- src/Cli/StellaOps.Cli/Commands/CryptoCommandGroup.cs
- src/Cli/StellaOps.Cli/Commands/CommandHandlers.Crypto.cs
- src/Cli/StellaOps.Cli/Services/CryptoProfileValidator.cs
- src/Cli/StellaOps.Cli/appsettings.crypto.yaml.example
- src/Cli/__Tests/StellaOps.Cli.Tests/CryptoCommandTests.cs
- docs/cli/crypto-commands.md
- docs/implplan/SPRINT_4100_0006_0001_COMPLETION_SUMMARY.md

## Files Modified

- src/Cli/StellaOps.Cli/StellaOps.Cli.csproj (conditional plugin refs)
- src/Cli/StellaOps.Cli/Program.cs (plugin registration + validation)
- src/Cli/StellaOps.Cli/Commands/CommandFactory.cs (command wiring)
- src/Scanner/__Libraries/StellaOps.Scanner.Core/Configuration/PoEConfiguration.cs (fix)

## Compliance

- GOST (Russia): GOST R 34.10-2012, FSB certified
- eIDAS (EU): Regulation (EU) No 910/2014, QES/AES/AdES
- SM (China): GM/T 0003-2012 (SM2), OSCCA certified

## Migration

`cryptoru` CLI deprecated → sunset date: 2025-07-01
- `cryptoru providers` → `stella crypto profiles`
- `cryptoru sign` → `stella crypto sign`

## Testing

 All crypto code compiles successfully
 Integration tests pass
 Build verification for all distributions (international/GOST/eIDAS/SM)

Next: SPRINT_4100_0006_0002 (eIDAS plugin implementation)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-23 13:13:00 +02:00

5.0 KiB
Raw Blame History

Heres a simple, practical way to make vulnerability “reachability” auditable and offlineverifiable in StellaOps without adding a lot of UI or runtime cost.

diagram of call graph to subgraph proof flow

What this is (plain English)

  • Callstack subgraph: when we say a vuln is “reachable,” we really mean some functions in your code can eventually call the risky function. That tiny slice of the big call graph is the subgraph.
  • Proof of exposure (PoE): a compact bundle (think: a few kilobytes) that cryptographically proves which functions and edges make the vuln reachable in a specific build.
  • Offlineverifiable: auditors can check the proof later, in an airgapped setting, using only hashes and your reproducible build IDs.

The minimal data model

  • BuildID: deterministic identifier (e.g., ELF BuildID or sourceoftruth content hash).
  • Nodes: function identifiers (module, symbol, debugaddr, source:line?).
  • Edges: caller → callee (with optional guard predicates like feature flags).
  • Entry set: the function(s)/handlers reachable from runtime entrypoints (HTTP handlers, cron, CLI).
  • Sink set: vulnerable API(s)/function(s) tied to a CVE.
  • Reachability proof: {BuildID, nodes[N], edges[E], entryRefs, sinkRefs, policyContext, toolVersions} + DSSE signature.

How it fits the StellaOps ledger

  • Store each resolved callstack as a subgraph object keyed by (BuildID, vulnID, package@version).

  • Link it to:

    • SBOM component node (CycloneDX/SPDX ref).
    • VEX claim (affected/notaffected/underinvestigation).
    • Scan recipe (so anyone can replay the result).
  • Emit one PoE artifact per “(vuln, component) with reachability=true”.

Why this helps

  • Binary precision + explainability: even if you only have a container image, the PoE explains why its reachable.
  • Auditorfriendly: tiny artifact, DSSEsigned, replayable with a known scanner build.
  • Noise control: store reachability as firstclass evidence; triage focuses on subgraphs, not global graphs.

Implementation guide (short and concrete)

1) Extraction (per build)

  • Prefer sourcelevel graphs when available; otherwise:

    • ELF/PE/MachO symbol harvest + debug info (DWARF/PDB) if present.
    • Lightweight static calledge inference (import tables, PLT/GOT, relocation targets).
    • Optional dynamic trace sampling (eBPF hooks) to confirm hot edges.

2) Resolution pipeline

  • Normalize function IDs: ModuleHash:Symbol@Addr[:File:Line].
  • Compute entry set (framework adapters know HTTP/GRPC/CLI entrypoints).
  • Compute sink set via rulepack mapping CVEs → {module:function(s)}.
  • Run bounded graph search with policy guards (feature flags, platform, build tags).
  • Persist the subgraph + metadata.

3) PoE artifact (OCIattached attestation)

  • Canonical JSON (stable sort, normalized IDs).
  • Include: BuildID, tool versions, policy digest, SBOM refs, VEX claim link, subgraph nodes/edges, minimal repro steps.
  • Sign via DSSE; attach as OCI ref to the image digest.

4) Offline verification (auditor)

  • Inputs: PoE, image digest, SBOM slice.
  • Steps: verify DSSE → check BuildID ↔ image digest → confirm nodes/edges hashes → reevaluate policy (optional) → show minimal path(s) entry→sink.

UI: keep it small

  • Evidence tab → “Proof of exposure” pill on any reachable vuln row.

  • Click opens a tiny path viewer (entry→…→sink) with:

    • path count, shortest path, guarded edges (badges for feature flags).
    • “Copy PoE JSON” and “Verify offline” instructions.
  • No separate heavy UI needed; reuse the existing vulnerability details drawer.

C# shape (sketch)

record FunctionId(string ModuleHash, string Symbol, ulong Addr, string? File, int? Line);
record Edge(FunctionId Caller, FunctionId Callee, string[] Guards);
record Subgraph(string BuildId, string ComponentRef, string VulnId,
                IReadOnlyList<FunctionId> Nodes, IReadOnlyList<Edge> Edges,
                string[] EntryRefs, string[] SinkRefs,
                string PolicyDigest, string ToolchainDigest);

interface IReachabilityResolver {
    Subgraph Resolve(string buildId, string componentRef, string vulnId, ResolverOptions opts);
}

interface IProofEmitter {
    byte[] EmitPoE(Subgraph g, PoeMeta meta); // canonical JSON bytes
}

Policy hooks youll want from day one

  • fail_if_unknown_edges > N in prod.
  • require_guard_evidence for claims like “feature off”.
  • max_paths/max_depth to keep proofs compact.
  • source-first-but-fallback-binary selection.

Rollout plan (2 sprints)

  • Sprint A (MVP): static graph, percomponent sinks, shortest path only, PoE JSON + DSSE sign, attach to image, verifycli.
  • Sprint B (Hardening): guard predicates, multiple paths with cap, eBPF confirmation toggle, UI path viewer, policy gates wired to release checks.