feat(crypto): Complete Phase 2 - Configuration-driven crypto architecture with 100% compliance

## Summary

This commit completes Phase 2 of the configuration-driven crypto architecture, achieving
100% crypto compliance by eliminating all hardcoded cryptographic implementations.

## Key Changes

### Phase 1: Plugin Loader Infrastructure
- **Plugin Discovery System**: Created StellaOps.Cryptography.PluginLoader with manifest-based loading
- **Configuration Model**: Added CryptoPluginConfiguration with regional profiles support
- **Dependency Injection**: Extended DI to support plugin-based crypto provider registration
- **Regional Configs**: Created appsettings.crypto.{international,russia,eu,china}.yaml
- **CI Workflow**: Added .gitea/workflows/crypto-compliance.yml for audit enforcement

### Phase 2: Code Refactoring
- **API Extension**: Added ICryptoProvider.CreateEphemeralVerifier for verification-only scenarios
- **Plugin Implementation**: Created OfflineVerificationCryptoProvider with ephemeral verifier support
  - Supports ES256/384/512, RS256/384/512, PS256/384/512
  - SubjectPublicKeyInfo (SPKI) public key format
- **100% Compliance**: Refactored DsseVerifier to remove all BouncyCastle cryptographic usage
- **Unit Tests**: Created OfflineVerificationProviderTests with 39 passing tests
- **Documentation**: Created comprehensive security guide at docs/security/offline-verification-crypto-provider.md
- **Audit Infrastructure**: Created scripts/audit-crypto-usage.ps1 for static analysis

### Testing Infrastructure (TestKit)
- **Determinism Gate**: Created DeterminismGate for reproducibility validation
- **Test Fixtures**: Added PostgresFixture and ValkeyFixture using Testcontainers
- **Traits System**: Implemented test lane attributes for parallel CI execution
- **JSON Assertions**: Added CanonicalJsonAssert for deterministic JSON comparisons
- **Test Lanes**: Created test-lanes.yml workflow for parallel test execution

### Documentation
- **Architecture**: Created CRYPTO_CONFIGURATION_DRIVEN_ARCHITECTURE.md master plan
- **Sprint Tracking**: Created SPRINT_1000_0007_0002_crypto_refactoring.md (COMPLETE)
- **API Documentation**: Updated docs2/cli/crypto-plugins.md and crypto.md
- **Testing Strategy**: Created testing strategy documents in docs/implplan/SPRINT_5100_0007_*

## Compliance & Testing

-  Zero direct System.Security.Cryptography usage in production code
-  All crypto operations go through ICryptoProvider abstraction
-  39/39 unit tests passing for OfflineVerificationCryptoProvider
-  Build successful (AirGap, Crypto plugin, DI infrastructure)
-  Audit script validates crypto boundaries

## Files Modified

**Core Crypto Infrastructure:**
- src/__Libraries/StellaOps.Cryptography/CryptoProvider.cs (API extension)
- src/__Libraries/StellaOps.Cryptography/CryptoSigningKey.cs (verification-only constructor)
- src/__Libraries/StellaOps.Cryptography/EcdsaSigner.cs (fixed ephemeral verifier)

**Plugin Implementation:**
- src/__Libraries/StellaOps.Cryptography.Plugin.OfflineVerification/ (new)
- src/__Libraries/StellaOps.Cryptography.PluginLoader/ (new)

**Production Code Refactoring:**
- src/AirGap/StellaOps.AirGap.Importer/Validation/DsseVerifier.cs (100% compliant)

**Tests:**
- src/__Libraries/__Tests/StellaOps.Cryptography.Plugin.OfflineVerification.Tests/ (new, 39 tests)
- src/__Libraries/__Tests/StellaOps.Cryptography.PluginLoader.Tests/ (new)

**Configuration:**
- etc/crypto-plugins-manifest.json (plugin registry)
- etc/appsettings.crypto.*.yaml (regional profiles)

**Documentation:**
- docs/security/offline-verification-crypto-provider.md (600+ lines)
- docs/implplan/CRYPTO_CONFIGURATION_DRIVEN_ARCHITECTURE.md (master plan)
- docs/implplan/SPRINT_1000_0007_0002_crypto_refactoring.md (Phase 2 complete)

## Next Steps

Phase 3: Docker & CI/CD Integration
- Create multi-stage Dockerfiles with all plugins
- Build regional Docker Compose files
- Implement runtime configuration selection
- Add deployment validation scripts

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

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
master
2025-12-23 18:20:00 +02:00
parent b444284be5
commit dac8e10e36
241 changed files with 22567 additions and 307 deletions

View File

@@ -0,0 +1,342 @@
# Verdict Attestation Implementation Status
**Sprint**: SPRINT_3000_0100_0001 - Signed Delta-Verdicts
**Status**: Phase 1 Complete (Policy Engine + Evidence Locker), Phase 2 Blocked
**Last Updated**: 2025-12-23
## Completed Work
### 1. Policy Engine - Verdict Predicate & Attestation Service ✅
**Location**: `src/Policy/StellaOps.Policy.Engine/Attestation/`
#### Files Created:
1. **VerdictPredicate.cs** - Core predicate models
- `VerdictPredicate` - Main predicate structure matching JSON schema
- `VerdictInfo` - Verdict details (status/severity/score)
- `VerdictRuleExecution` - Rule chain execution trace
- `VerdictEvidence` - Evidence references (advisories, VEX, SBOM)
- `VerdictVexImpact` - VEX impact assessment
- `VerdictReachability` - Call graph reachability data
- Uses canonical JSON serialization with lexicographic key ordering
2. **VerdictPredicateBuilder.cs** - Predicate assembly service
- `Build(PolicyExplainTrace)` - Converts existing trace to attestation predicate
- `Serialize(VerdictPredicate)` - Canonical JSON with sorted keys
- `ComputeDeterminismHash(VerdictPredicate)` - SHA256 over sorted evidence + verdict
- Maps all existing Policy Engine trace data to new attestation format
3. **IVerdictAttestationService.cs** - Service interface
- `AttestVerdictAsync(trace)` - Orchestrates attestation creation
- `VerdictAttestationRequest` - Request DTO with predicate, subject, metadata
- `VerdictAttestationResult` - Response DTO with verdict ID and URI
4. **VerdictAttestationService.cs** - Service implementation
- Feature-flagged via `VerdictAttestationOptions.Enabled`
- Calls `VerdictPredicateBuilder` to create predicate
- Calls `HttpAttestorClient` to request signing
- Returns verdict ID for downstream tracking
5. **HttpAttestorClient.cs** - HTTP client for Attestor service
- `POST /internal/api/v1/attestations/verdict`
- Sends predicate JSON + subject descriptor
- Receives signed attestation metadata
**Design Decisions**:
- Predicate strictly matches `stellaops-policy-verdict.v1.schema.json`
- Determinism hash uses sorted evidence digests + verdict triple
- Offline-first: no hard dependencies on external services
- Feature flag allows gradual rollout
### 2. Evidence Locker - Verdict Storage & API ✅
**Location**: `src/EvidenceLocker/StellaOps.EvidenceLocker/`
#### Files Created:
1. **Migrations/001_CreateVerdictAttestations.sql**
- Table: `evidence_locker.verdict_attestations`
- Columns: verdict_id (PK), tenant_id, run_id, finding_id, policy metadata, verdict triple, envelope (JSONB), digests, rekor_log_index, timestamps
- Indexes: run_id, finding_id, tenant+evaluated_at
- CHECK constraint on verdict_status enum
- Audit trigger: `audit_verdict_attestations_changes`
2. **Storage/IVerdictRepository.cs** - Repository interface
- `StoreVerdictAsync(record)` - Upsert verdict attestation
- `GetVerdictAsync(verdictId)` - Retrieve full record with envelope
- `ListVerdictsForRunAsync(runId, options)` - Query verdicts by run with filtering
- `ListVerdictsAsync(tenantId, options)` - Query verdicts by tenant
- `CountVerdictsForRunAsync(runId, options)` - Pagination count
- Records: `VerdictAttestationRecord`, `VerdictAttestationSummary`, `VerdictListOptions`
3. **Storage/PostgresVerdictRepository.cs** - PostgreSQL implementation
- Uses Npgsql + Dapper for data access
- JSONB storage for DSSE envelope with GIN index
- ON CONFLICT handling for idempotent upserts
- Filtering by status/severity with pagination
- Tenant isolation via WHERE clauses
4. **Api/VerdictContracts.cs** - API response DTOs
- `GetVerdictResponse` - Full verdict with envelope
- `ListVerdictsResponse` - Paged list of summaries
- `VerdictSummary` - Lightweight verdict metadata
- `VerifyVerdictResponse` - Signature verification results
- `SignatureVerification`, `RekorVerification` - Crypto details
- JSON serialization with snake_case naming
5. **Api/VerdictEndpoints.cs** - Minimal API endpoints
- `GET /api/v1/verdicts/{verdictId}` - Retrieve verdict
- `GET /api/v1/runs/{runId}/verdicts` - List verdicts for run
- `POST /api/v1/verdicts/{verdictId}/verify` - Verify signature (TODO: implementation)
- Structured logging for all operations
- Error handling with problem details
6. **StellaOps.EvidenceLocker.csproj** - Project file
- Dependencies: Npgsql 9.0.3, Dapper 2.1.35, OpenTelemetry, Serilog
- Project references: Scheduler.Models, Policy.Engine, Configuration, DependencyInjection, Auth, Telemetry
#### Integration Points:
1. **DI Registration** - Updated `EvidenceLockerInfrastructureServiceCollectionExtensions.cs`
- Registered `IVerdictRepository``PostgresVerdictRepository`
- Connection string from `EvidenceLockerOptions.Database.ConnectionString`
2. **WebService Wiring** - Updated `StellaOps.EvidenceLocker.WebService/Program.cs`
- Added `using StellaOps.EvidenceLocker.Api`
- Called `app.MapVerdictEndpoints()` before `app.Run()`
3. **Project References** - Updated `.csproj` files
- `WebService.csproj` → references `StellaOps.EvidenceLocker.csproj`
- `Infrastructure.csproj` → references `StellaOps.EvidenceLocker.csproj`
- Fixed package versions: Npgsql 9.0.3, Dapper 2.1.35
**Design Decisions**:
- PostgreSQL JSONB for envelope storage (queryable + compact)
- Separate verdict fields for efficient indexing without JSON extraction
- Determinism hash stored for replay verification
- Optional Rekor log index for transparency
- Repository pattern for testability
- Minimal APIs for lightweight endpoints
## Blocked Work
### 3. Attestor - VerdictAttestationHandler ⚠️ BLOCKED
**Blocking Issue**: Pre-existing build errors in Attestor dependencies:
- `StellaOps.Replay.Core`: Missing YamlDotNet assembly reference
- `StellaOps.Attestor.ProofChain`: Missing Envelope namespace, ILogger references
**Planned Implementation** (when unblocked):
**Location**: `src/Attestor/StellaOps.Attestor/StellaOps.Attestor.WebService/`
#### Planned Files:
1. **Handlers/VerdictAttestationHandler.cs**
```csharp
public class VerdictAttestationHandler
{
private readonly IAttestationSigningService _signingService;
private readonly IVerdictRepository _verdictRepository;
private readonly ITransparencyWitnessClient _transparencyClient;
public async Task<VerdictAttestationResponse> HandleAsync(
VerdictAttestationRequest request,
CancellationToken cancellationToken)
{
// 1. Validate predicate schema
// 2. Create AttestationSignRequest with predicate payload
// 3. Sign with IAttestationSigningService
// 4. Extract DSSE envelope from result
// 5. Store in Evidence Locker via IVerdictRepository
// 6. Optional: Submit to Rekor via ITransparencyWitnessClient
// 7. Return verdict ID + attestation URI
}
}
```
2. **Endpoints** - Add to WebService Program.cs
- `POST /internal/api/v1/attestations/verdict` - Create verdict attestation
- Accepts predicate JSON + subject descriptor
- Returns verdict ID + DSSE envelope URI
3. **DI Registration**
- Register `VerdictAttestationHandler` as scoped service
- Wire up dependencies: signing, storage, transparency
**Dependencies**:
- ✅ `IAttestationSigningService` - Existing
- ✅ `ITransparencyWitnessClient` - Existing
- ✅ `IVerdictRepository` - Implemented (Evidence Locker)
- ❌ Build environment - **BLOCKED**
## Pending Work
### 4. Policy Engine Integration ⏸️
**Task**: Wire Policy Engine to call VerdictAttestationService after verdict evaluation
**Location**: `src/Policy/StellaOps.Policy.Engine/Evaluation/PolicyEvaluator.cs` (or similar)
**Changes Needed**:
1. Inject `IVerdictAttestationService` into evaluator
2. After successful policy evaluation, call `AttestVerdictAsync(trace)`
3. Store returned verdict ID in evaluation metadata
4. Ensure async context properly propagated
**Depends On**: Task 3 (Attestor Handler) completion
### 5. Unit Tests ⏸️
**Location**: `src/Policy/StellaOps.Policy.Engine/__Tests/`
**Files to Create**:
1. **VerdictPredicateBuilderTests.cs**
- Test: Schema validation (predicate matches JSON schema)
- Test: Determinism hash stability (same input → same hash)
- Test: Rule chain mapping accuracy
- Test: Evidence digest computation
- Test: VEX impact extraction
- Test: Reachability data mapping
- Test: Canonical JSON serialization (key ordering)
2. **VerdictAttestationServiceTests.cs**
- Test: Feature flag disabled (returns null)
- Test: Successful attestation flow
- Test: HTTP client failure handling
- Test: Predicate serialization errors
3. **Integration Test**
- Test: End-to-end policy run → verdict attestation → storage → retrieval
- Test: Deterministic replay (same inputs → same determinism hash)
- Test: Signature verification
**Depends On**: Task 3, 4 completion
### 6. CLI Commands ⏸️
**Location**: `src/Cli/StellaOps.Cli/Commands/`
**Commands to Add**:
1. `stella verdict get <verdict-id>` - Retrieve verdict attestation
2. `stella verdict verify <verdict-id>` - Verify signature
3. `stella verdict list --run <run-id>` - List verdicts for run
4. `stella verdict download <verdict-id> --output <path>` - Download DSSE bundle
**Depends On**: Task 3, 4, 5 completion
## Architecture Summary
```
┌─────────────────┐
│ Policy Engine │
│ - Evaluates │
│ - Generates │
│ Trace │
└────────┬────────┘
│ PolicyExplainTrace
┌────────────────────────────┐
│ VerdictPredicateBuilder │
│ - Converts Trace │
│ - Computes Determinism │
│ - Serializes Canonical │
└────────┬───────────────────┘
│ VerdictPredicate
┌─────────────────────────────────┐
│ VerdictAttestationService │
│ - Orchestrates Signing │
│ - Calls Attestor │
└────────┬────────────────────────┘
│ HTTP POST /internal/api/v1/attestations/verdict
┌────────────────────────────────────┐
│ Attestor │ ⚠️ BLOCKED
│ - VerdictAttestationHandler │
│ - IAttestationSigningService │
│ - Creates DSSE Envelope │
└────────┬───────────────────────────┘
│ VerdictAttestationRecord
┌──────────────────────────────────┐
│ Evidence Locker │ ✅ COMPLETE
│ - PostgresVerdictRepository │
│ - Stores Attestations │
│ - Provides Query API │
└──────────────────────────────────┘
```
## Next Steps
### Immediate Actions Required:
1. **Fix Attestor Build Errors** (Infrastructure team)
- Add missing YamlDotNet package reference to Replay.Core
- Fix ProofChain namespace/using issues
- Verify all Attestor dependencies compile
2. **Implement VerdictAttestationHandler** (This sprint)
- Create handler class in Attestor.WebService
- Wire up signing service, storage, transparency
- Add endpoint to Program.cs
- Test end-to-end flow
3. **Integrate Policy Engine** (This sprint)
- Inject attestation service into evaluator
- Call after successful verdicts
- Store verdict IDs
4. **Write Unit Tests** (This sprint)
- VerdictPredicateBuilder schema/determinism tests
- Service integration tests
- End-to-end replay tests
5. **CLI Commands** (Next sprint)
- verdict get/verify/list/download
- Interactive verification UI
### Success Criteria:
- [ ] Policy runs generate cryptographically-signed verdict attestations
- [ ] Verdicts stored in Evidence Locker with DSSE envelopes
- [ ] Determinism hashes enable bit-for-bit replay verification
- [ ] Optional Rekor anchoring for public auditability
- [ ] CLI commands for verdict inspection and verification
- [ ] Unit test coverage >80% for new code
- [ ] Integration tests validate end-to-end flow
## Technical Debt
1. **EvidenceLockerDataSource Integration**
- Current: PostgresVerdictRepository uses connection string directly
- Future: Migrate to use EvidenceLockerDataSource.OpenConnectionAsync()
- Benefit: Unified session management, tenant scoping
2. **Signature Verification Placeholder**
- Current: `VerdictEndpoints.VerifyVerdictAsync` returns placeholder response
- Future: Implement actual DSSE signature verification
- Dependency: Integrate with Attestor verification service
3. **Pre-existing Attestor Errors**
- EvidencePortableBundleService.cs static field access errors
- Blocking unrelated to verdict attestation work
- Needs separate investigation
## Resources
- **JSON Schema**: `docs/schemas/stellaops-policy-verdict.v1.schema.json`
- **Documentation**: `docs/policy/verdict-attestations.md`
- **Sprint Plan**: `docs/implplan/SPRINT_3000_0100_0001_signed_verdicts.md`
- **Evidence Pack Sprint**: `docs/implplan/SPRINT_3000_0100_0002_evidence_packs.md`
---
**Status Legend**:
- ✅ Complete
- ⚠️ Blocked
- ⏸️ Pending (blocked by dependencies)
- 🔄 In Progress