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>
This commit is contained in:
16
etc/keys/scanner-signing-2025.key.json.sample
Normal file
16
etc/keys/scanner-signing-2025.key.json.sample
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"keyId": "scanner-signing-2025",
|
||||
"algorithm": "ECDSA-P256",
|
||||
"comment": "Scanner signing key for PoE DSSE envelopes (2025)",
|
||||
"privateKeyPem": "-----BEGIN PRIVATE KEY-----\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgXXXXXXXXXXXXXXXX\nXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXahRANCArYYYYYYYYYYYYYYYYYYYYYYYYYY\nYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY\nYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY\nYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY\n-----END PRIVATE KEY-----",
|
||||
"validFrom": "2025-01-01T00:00:00Z",
|
||||
"validUntil": "2025-12-31T23:59:59Z",
|
||||
"usage": ["sign"],
|
||||
"notes": [
|
||||
"DO NOT USE THIS KEY IN PRODUCTION - EXAMPLE ONLY",
|
||||
"Generate your own key with: openssl ecparam -name prime256v1 -genkey -noout -out key.pem",
|
||||
"Convert to JSON format with base64 encoding",
|
||||
"Store in secure location (KMS, HSM, or encrypted filesystem)",
|
||||
"Rotate keys every 90 days for production use"
|
||||
]
|
||||
}
|
||||
15
etc/keys/scanner-signing-2025.pub.json.sample
Normal file
15
etc/keys/scanner-signing-2025.pub.json.sample
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"keyId": "scanner-signing-2025",
|
||||
"algorithm": "ECDSA-P256",
|
||||
"comment": "Scanner public key for PoE DSSE verification (2025)",
|
||||
"publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEYYYYYYYYYYYYYYYYYYYYYYYYYYYY\nYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY==\n-----END PUBLIC KEY-----",
|
||||
"validFrom": "2025-01-01T00:00:00Z",
|
||||
"validUntil": "2025-12-31T23:59:59Z",
|
||||
"usage": ["verify"],
|
||||
"notes": [
|
||||
"DO NOT USE THIS KEY IN PRODUCTION - EXAMPLE ONLY",
|
||||
"Distribute this public key to auditors for offline PoE verification",
|
||||
"Include in trusted-keys.json for stella poe verify command",
|
||||
"Verify key fingerprint matches: sha256:..."
|
||||
]
|
||||
}
|
||||
225
etc/policy.poe.yaml.sample
Normal file
225
etc/policy.poe.yaml.sample
Normal file
@@ -0,0 +1,225 @@
|
||||
# StellaOps Proof of Exposure (PoE) Policy Configuration
|
||||
#
|
||||
# This file configures policy gates for validating Proof of Exposure artifacts.
|
||||
# PoE artifacts provide compact, offline-verifiable proof of vulnerability reachability
|
||||
# at the function level with signed DSSE attestations.
|
||||
#
|
||||
# Documentation: docs/modules/policy/poe-policy-gates.md
|
||||
# Schema: src/Policy/StellaOps.Policy.Engine/ProofOfExposure/PoEPolicyModels.cs
|
||||
|
||||
# ====================================
|
||||
# Example 1: Minimal (Development)
|
||||
# ====================================
|
||||
# Minimal configuration for development environments.
|
||||
# PoE is optional, warnings only.
|
||||
|
||||
poe_policy_minimal:
|
||||
require_poe_for_reachable: false
|
||||
require_signed_poe: false
|
||||
require_rekor_timestamp: false
|
||||
on_validation_failure: warn
|
||||
max_poe_age_days: 90
|
||||
reject_stale_poe: false
|
||||
|
||||
# ====================================
|
||||
# Example 2: Standard (Production)
|
||||
# ====================================
|
||||
# Standard configuration for production environments.
|
||||
# Requires PoE for reachable vulnerabilities with DSSE signatures.
|
||||
|
||||
poe_policy_standard:
|
||||
require_poe_for_reachable: true
|
||||
require_signed_poe: true
|
||||
require_rekor_timestamp: false
|
||||
min_edge_confidence: 0.7
|
||||
allow_guarded_paths: true
|
||||
trusted_key_ids:
|
||||
- scanner-signing-2025
|
||||
- scanner-signing-2025-backup
|
||||
max_poe_age_days: 90
|
||||
reject_stale_poe: false
|
||||
require_build_id_match: true
|
||||
require_policy_digest_match: false
|
||||
on_validation_failure: warn
|
||||
|
||||
# ====================================
|
||||
# Example 3: Strict (Critical Systems)
|
||||
# ====================================
|
||||
# Strict configuration for critical systems (finance, healthcare, defense).
|
||||
# Requires PoE with Rekor timestamps and rejects failures.
|
||||
|
||||
poe_policy_strict:
|
||||
require_poe_for_reachable: true
|
||||
require_signed_poe: true
|
||||
require_rekor_timestamp: true
|
||||
min_paths: 1
|
||||
max_path_depth: 15
|
||||
min_edge_confidence: 0.85
|
||||
allow_guarded_paths: false
|
||||
trusted_key_ids:
|
||||
- scanner-signing-2025
|
||||
max_poe_age_days: 30
|
||||
reject_stale_poe: true
|
||||
require_build_id_match: true
|
||||
require_policy_digest_match: true
|
||||
on_validation_failure: reject
|
||||
|
||||
# ====================================
|
||||
# Example 4: Custom
|
||||
# ====================================
|
||||
# Custom configuration with specific requirements.
|
||||
|
||||
poe_policy_custom:
|
||||
# Require PoE for all reachable vulnerabilities
|
||||
require_poe_for_reachable: true
|
||||
|
||||
# DSSE signature is mandatory
|
||||
require_signed_poe: true
|
||||
|
||||
# Rekor transparency log timestamp required for audit compliance
|
||||
require_rekor_timestamp: true
|
||||
|
||||
# Subgraph constraints
|
||||
min_paths: 1 # At least one path to vulnerable code
|
||||
max_path_depth: 20 # Maximum call depth in path
|
||||
min_edge_confidence: 0.75 # Minimum confidence for edges (0.0-1.0)
|
||||
|
||||
# Allow paths with feature flag guards (e.g., if (FeatureFlags.Beta))
|
||||
allow_guarded_paths: true
|
||||
|
||||
# Trusted signing key IDs for DSSE verification
|
||||
trusted_key_ids:
|
||||
- scanner-signing-2025
|
||||
- scanner-signing-2025-backup
|
||||
|
||||
# PoE age constraints
|
||||
max_poe_age_days: 60 # PoE must be refreshed every 60 days
|
||||
reject_stale_poe: false # Warn but don't reject stale PoE
|
||||
|
||||
# Build reproducibility
|
||||
require_build_id_match: true # PoE build ID must match scan build ID
|
||||
|
||||
# Policy versioning
|
||||
require_policy_digest_match: false # Allow PoE from previous policy versions
|
||||
|
||||
# Action on validation failure
|
||||
# Options: warn, reject, downgrade, review
|
||||
on_validation_failure: downgrade
|
||||
|
||||
# ====================================
|
||||
# Integration with Policy Engine
|
||||
# ====================================
|
||||
# Use PoE policy configuration in policy evaluation rules.
|
||||
#
|
||||
# Example OPA/Rego policy:
|
||||
#
|
||||
# package stellaops.policy
|
||||
#
|
||||
# import data.poe_policy_standard as poe_config
|
||||
#
|
||||
# violation[msg] {
|
||||
# finding := input.findings[_]
|
||||
# finding.is_reachable == true
|
||||
# not finding.poe_validation.is_valid
|
||||
# poe_config.require_poe_for_reachable == true
|
||||
# msg := sprintf("Reachable vulnerability %s missing valid PoE", [finding.vuln_id])
|
||||
# }
|
||||
#
|
||||
# severity_adjustment[adjusted] {
|
||||
# finding := input.findings[_]
|
||||
# not finding.poe_validation.is_valid
|
||||
# poe_config.on_validation_failure == "downgrade"
|
||||
# adjusted := {
|
||||
# "finding_id": finding.finding_id,
|
||||
# "original_severity": finding.severity,
|
||||
# "adjusted_severity": downgrade_severity(finding.severity)
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# downgrade_severity(severity) = "High" {
|
||||
# severity == "Critical"
|
||||
# }
|
||||
#
|
||||
# downgrade_severity(severity) = "Medium" {
|
||||
# severity == "High"
|
||||
# }
|
||||
#
|
||||
# downgrade_severity(severity) = "Low" {
|
||||
# severity == "Medium"
|
||||
# }
|
||||
#
|
||||
# downgrade_severity(severity) = severity {
|
||||
# severity != "Critical"
|
||||
# severity != "High"
|
||||
# severity != "Medium"
|
||||
# }
|
||||
|
||||
# ====================================
|
||||
# Field Descriptions
|
||||
# ====================================
|
||||
#
|
||||
# require_poe_for_reachable: (boolean)
|
||||
# Whether PoE is mandatory for vulnerabilities marked as reachable.
|
||||
# Default: false
|
||||
#
|
||||
# require_signed_poe: (boolean)
|
||||
# Whether PoE must be cryptographically signed with DSSE.
|
||||
# Default: true
|
||||
#
|
||||
# require_rekor_timestamp: (boolean)
|
||||
# Whether PoE signatures must be timestamped in Rekor transparency log.
|
||||
# Default: false
|
||||
#
|
||||
# min_paths: (integer, optional)
|
||||
# Minimum number of paths required in PoE subgraph.
|
||||
# Null means no minimum.
|
||||
#
|
||||
# max_path_depth: (integer, optional)
|
||||
# Maximum allowed path depth in PoE subgraph.
|
||||
# Null means no maximum.
|
||||
#
|
||||
# min_edge_confidence: (decimal, 0.0-1.0)
|
||||
# Minimum confidence threshold for PoE edges.
|
||||
# Default: 0.7
|
||||
#
|
||||
# allow_guarded_paths: (boolean)
|
||||
# Whether to allow PoE with feature flag guards.
|
||||
# Default: true
|
||||
#
|
||||
# trusted_key_ids: (array of strings)
|
||||
# List of trusted key IDs for DSSE signature verification.
|
||||
# Example: ["scanner-signing-2025"]
|
||||
#
|
||||
# max_poe_age_days: (integer)
|
||||
# Maximum age of PoE artifacts before they're considered stale.
|
||||
# Default: 90
|
||||
#
|
||||
# reject_stale_poe: (boolean)
|
||||
# Whether to reject findings with stale PoE.
|
||||
# Default: false
|
||||
#
|
||||
# require_build_id_match: (boolean)
|
||||
# Whether PoE build ID must match scan build ID.
|
||||
# Default: true
|
||||
#
|
||||
# require_policy_digest_match: (boolean)
|
||||
# Whether PoE policy digest must match current policy.
|
||||
# Default: false
|
||||
#
|
||||
# on_validation_failure: (enum)
|
||||
# Action to take when PoE validation fails.
|
||||
# Options:
|
||||
# - warn: Allow the finding but add a warning
|
||||
# - reject: Reject the finding (treat as policy violation)
|
||||
# - downgrade: Downgrade severity of the finding
|
||||
# - review: Mark the finding for manual review
|
||||
# Default: warn
|
||||
|
||||
# ====================================
|
||||
# Related Configuration
|
||||
# ====================================
|
||||
# - Scanner PoE emission: etc/scanner.poe.yaml.sample
|
||||
# - Signing keys: etc/keys/scanner-signing-2025.key.json.sample
|
||||
# - Public keys: etc/keys/scanner-signing-2025.pub.json.sample
|
||||
# - CLI export: stella poe export --help
|
||||
# - CLI verify: stella poe verify --help
|
||||
101
etc/scanner.poe.yaml.sample
Normal file
101
etc/scanner.poe.yaml.sample
Normal file
@@ -0,0 +1,101 @@
|
||||
# Scanner Configuration with Proof of Exposure (PoE) Settings
|
||||
# Copy to etc/scanner.yaml and customize for your deployment
|
||||
|
||||
scanner:
|
||||
# ... other scanner settings ...
|
||||
|
||||
reachability:
|
||||
# Proof of Exposure configuration
|
||||
poe:
|
||||
# Enable PoE generation (default: false)
|
||||
# Set to true to emit PoE artifacts for reachable vulnerabilities
|
||||
enabled: false
|
||||
|
||||
# Maximum depth for subgraph extraction (hops from entry to sink)
|
||||
# Range: 5-20, default: 10
|
||||
# Higher values find more paths but increase processing time
|
||||
maxDepth: 10
|
||||
|
||||
# Maximum number of paths to include in each PoE
|
||||
# Range: 1-10, default: 5
|
||||
# Multiple paths provide alternative evidence for auditors
|
||||
maxPaths: 5
|
||||
|
||||
# Include guard predicates (feature flags, platform conditionals) in edges
|
||||
# Default: true
|
||||
# Guards help explain conditional reachability
|
||||
includeGuards: true
|
||||
|
||||
# Only emit PoE for vulnerabilities with reachability=true
|
||||
# Default: true
|
||||
# Set to false to emit PoE for all vulnerabilities (including unreachable with empty paths)
|
||||
emitOnlyReachable: true
|
||||
|
||||
# Attach PoE artifacts to OCI images as attestations
|
||||
# Default: false
|
||||
# Requires OCI registry write access
|
||||
attachToOci: false
|
||||
|
||||
# Submit PoE DSSE envelopes to Rekor transparency log
|
||||
# Default: false
|
||||
# Requires network access to Rekor instance
|
||||
submitToRekor: false
|
||||
|
||||
# Path pruning strategy
|
||||
# Options: ShortestWithConfidence | ShortestOnly | ConfidenceFirst | RuntimeFirst
|
||||
# Default: ShortestWithConfidence
|
||||
pruneStrategy: ShortestWithConfidence
|
||||
|
||||
# Require runtime confirmation for high-risk findings
|
||||
# Default: false
|
||||
# When true, only runtime-observed paths are included in PoE
|
||||
requireRuntimeConfirmation: false
|
||||
|
||||
# Signing key ID for DSSE envelopes
|
||||
# Must match a key in keys directory or KMS
|
||||
# Default: "scanner-signing-2025"
|
||||
signingKeyId: scanner-signing-2025
|
||||
|
||||
# Include SBOM reference in PoE evidence block
|
||||
# Default: true
|
||||
includeSbomRef: true
|
||||
|
||||
# Include VEX claim URI in PoE evidence block
|
||||
# Default: false
|
||||
includeVexClaimUri: false
|
||||
|
||||
# Include runtime facts URI in PoE evidence block
|
||||
# Default: false
|
||||
includeRuntimeFactsUri: false
|
||||
|
||||
# Prettify PoE JSON (2-space indentation)
|
||||
# Default: true
|
||||
# Set to false for minimal file size (~20% reduction)
|
||||
prettifyJson: true
|
||||
|
||||
# Example: Minimal PoE configuration (enabled with defaults)
|
||||
# reachability:
|
||||
# poe:
|
||||
# enabled: true
|
||||
|
||||
# Example: Strict PoE configuration (high-assurance environments)
|
||||
# reachability:
|
||||
# poe:
|
||||
# enabled: true
|
||||
# maxDepth: 8
|
||||
# maxPaths: 1
|
||||
# requireRuntimeConfirmation: true
|
||||
# submitToRekor: true
|
||||
# attachToOci: true
|
||||
# pruneStrategy: ShortestOnly
|
||||
|
||||
# Example: Comprehensive PoE configuration (maximum context for auditors)
|
||||
# reachability:
|
||||
# poe:
|
||||
# enabled: true
|
||||
# maxDepth: 15
|
||||
# maxPaths: 10
|
||||
# includeSbomRef: true
|
||||
# includeVexClaimUri: true
|
||||
# includeRuntimeFactsUri: true
|
||||
# pruneStrategy: RuntimeFirst
|
||||
Reference in New Issue
Block a user