Files
git.stella-ops.org/docs/implplan/IMPLEMENTATION_STATUS_VERDICT_ATTESTATIONS.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

14 KiB

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 IVerdictRepositoryPostgresVerdictRepository
    • 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

    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