## 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>
317 lines
10 KiB
YAML
317 lines
10 KiB
YAML
# .gitea/workflows/test-lanes.yml
|
|
# Lane-based test execution using standardized trait filtering
|
|
# Implements Task 10 from SPRINT 5100.0007.0001
|
|
|
|
name: Test Lanes
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [ main, develop ]
|
|
paths:
|
|
- 'src/**'
|
|
- 'tests/**'
|
|
- 'scripts/test-lane.sh'
|
|
- '.gitea/workflows/test-lanes.yml'
|
|
push:
|
|
branches: [ main ]
|
|
workflow_dispatch:
|
|
inputs:
|
|
run_performance:
|
|
description: 'Run Performance lane tests'
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
run_live:
|
|
description: 'Run Live lane tests (external dependencies)'
|
|
required: false
|
|
default: false
|
|
type: boolean
|
|
|
|
env:
|
|
DOTNET_VERSION: '10.0.100'
|
|
BUILD_CONFIGURATION: Release
|
|
TEST_RESULTS_DIR: ${{ github.workspace }}/test-results
|
|
|
|
jobs:
|
|
# ===========================================================================
|
|
# Unit Lane: Fast, isolated, deterministic tests (PR-gating)
|
|
# ===========================================================================
|
|
unit-tests:
|
|
name: Unit Tests
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 15
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup .NET ${{ env.DOTNET_VERSION }}
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
include-prerelease: true
|
|
|
|
- name: Restore solution
|
|
run: dotnet restore src/StellaOps.sln
|
|
|
|
- name: Build solution
|
|
run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore
|
|
|
|
- name: Run Unit lane tests
|
|
run: |
|
|
mkdir -p "$TEST_RESULTS_DIR"
|
|
chmod +x scripts/test-lane.sh
|
|
./scripts/test-lane.sh Unit \
|
|
--logger "trx;LogFileName=unit-tests.trx" \
|
|
--results-directory "$TEST_RESULTS_DIR" \
|
|
--verbosity normal
|
|
|
|
- name: Upload Unit test results
|
|
uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: unit-test-results
|
|
path: ${{ env.TEST_RESULTS_DIR }}
|
|
if-no-files-found: ignore
|
|
retention-days: 7
|
|
|
|
# ===========================================================================
|
|
# Contract Lane: API contract stability tests (PR-gating)
|
|
# ===========================================================================
|
|
contract-tests:
|
|
name: Contract Tests
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 10
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup .NET ${{ env.DOTNET_VERSION }}
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
include-prerelease: true
|
|
|
|
- name: Restore solution
|
|
run: dotnet restore src/StellaOps.sln
|
|
|
|
- name: Build solution
|
|
run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore
|
|
|
|
- name: Run Contract lane tests
|
|
run: |
|
|
mkdir -p "$TEST_RESULTS_DIR"
|
|
chmod +x scripts/test-lane.sh
|
|
./scripts/test-lane.sh Contract \
|
|
--logger "trx;LogFileName=contract-tests.trx" \
|
|
--results-directory "$TEST_RESULTS_DIR" \
|
|
--verbosity normal
|
|
|
|
- name: Upload Contract test results
|
|
uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: contract-test-results
|
|
path: ${{ env.TEST_RESULTS_DIR }}
|
|
if-no-files-found: ignore
|
|
retention-days: 7
|
|
|
|
# ===========================================================================
|
|
# Integration Lane: Service + storage tests with Testcontainers (PR-gating)
|
|
# ===========================================================================
|
|
integration-tests:
|
|
name: Integration Tests
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 30
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup .NET ${{ env.DOTNET_VERSION }}
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
include-prerelease: true
|
|
|
|
- name: Restore solution
|
|
run: dotnet restore src/StellaOps.sln
|
|
|
|
- name: Build solution
|
|
run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore
|
|
|
|
- name: Run Integration lane tests
|
|
env:
|
|
POSTGRES_TEST_IMAGE: postgres:16-alpine
|
|
run: |
|
|
mkdir -p "$TEST_RESULTS_DIR"
|
|
chmod +x scripts/test-lane.sh
|
|
./scripts/test-lane.sh Integration \
|
|
--logger "trx;LogFileName=integration-tests.trx" \
|
|
--results-directory "$TEST_RESULTS_DIR" \
|
|
--verbosity normal
|
|
|
|
- name: Upload Integration test results
|
|
uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: integration-test-results
|
|
path: ${{ env.TEST_RESULTS_DIR }}
|
|
if-no-files-found: ignore
|
|
retention-days: 7
|
|
|
|
# ===========================================================================
|
|
# Security Lane: AuthZ, input validation, negative tests (PR-gating)
|
|
# ===========================================================================
|
|
security-tests:
|
|
name: Security Tests
|
|
runs-on: ubuntu-22.04
|
|
timeout-minutes: 20
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup .NET ${{ env.DOTNET_VERSION }}
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
include-prerelease: true
|
|
|
|
- name: Restore solution
|
|
run: dotnet restore src/StellaOps.sln
|
|
|
|
- name: Build solution
|
|
run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore
|
|
|
|
- name: Run Security lane tests
|
|
run: |
|
|
mkdir -p "$TEST_RESULTS_DIR"
|
|
chmod +x scripts/test-lane.sh
|
|
./scripts/test-lane.sh Security \
|
|
--logger "trx;LogFileName=security-tests.trx" \
|
|
--results-directory "$TEST_RESULTS_DIR" \
|
|
--verbosity normal
|
|
|
|
- name: Upload Security test results
|
|
uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: security-test-results
|
|
path: ${{ env.TEST_RESULTS_DIR }}
|
|
if-no-files-found: ignore
|
|
retention-days: 7
|
|
|
|
# ===========================================================================
|
|
# Performance Lane: Benchmarks and regression thresholds (optional/scheduled)
|
|
# ===========================================================================
|
|
performance-tests:
|
|
name: Performance Tests
|
|
runs-on: ubuntu-22.04
|
|
if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.run_performance == 'true')
|
|
timeout-minutes: 30
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup .NET ${{ env.DOTNET_VERSION }}
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
include-prerelease: true
|
|
|
|
- name: Restore solution
|
|
run: dotnet restore src/StellaOps.sln
|
|
|
|
- name: Build solution
|
|
run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore
|
|
|
|
- name: Run Performance lane tests
|
|
run: |
|
|
mkdir -p "$TEST_RESULTS_DIR"
|
|
chmod +x scripts/test-lane.sh
|
|
./scripts/test-lane.sh Performance \
|
|
--logger "trx;LogFileName=performance-tests.trx" \
|
|
--results-directory "$TEST_RESULTS_DIR" \
|
|
--verbosity normal
|
|
|
|
- name: Upload Performance test results
|
|
uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: performance-test-results
|
|
path: ${{ env.TEST_RESULTS_DIR }}
|
|
if-no-files-found: ignore
|
|
retention-days: 14
|
|
|
|
# ===========================================================================
|
|
# Live Lane: External API smoke tests (opt-in only, never PR-gating)
|
|
# ===========================================================================
|
|
live-tests:
|
|
name: Live Tests (External Dependencies)
|
|
runs-on: ubuntu-22.04
|
|
if: github.event_name == 'workflow_dispatch' && github.event.inputs.run_live == 'true'
|
|
timeout-minutes: 20
|
|
steps:
|
|
- name: Checkout repository
|
|
uses: actions/checkout@v4
|
|
|
|
- name: Setup .NET ${{ env.DOTNET_VERSION }}
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: ${{ env.DOTNET_VERSION }}
|
|
include-prerelease: true
|
|
|
|
- name: Restore solution
|
|
run: dotnet restore src/StellaOps.sln
|
|
|
|
- name: Build solution
|
|
run: dotnet build src/StellaOps.sln --configuration $BUILD_CONFIGURATION --no-restore
|
|
|
|
- name: Run Live lane tests
|
|
run: |
|
|
mkdir -p "$TEST_RESULTS_DIR"
|
|
chmod +x scripts/test-lane.sh
|
|
./scripts/test-lane.sh Live \
|
|
--logger "trx;LogFileName=live-tests.trx" \
|
|
--results-directory "$TEST_RESULTS_DIR" \
|
|
--verbosity normal
|
|
continue-on-error: true
|
|
|
|
- name: Upload Live test results
|
|
uses: actions/upload-artifact@v4
|
|
if: always()
|
|
with:
|
|
name: live-test-results
|
|
path: ${{ env.TEST_RESULTS_DIR }}
|
|
if-no-files-found: ignore
|
|
retention-days: 7
|
|
|
|
# ===========================================================================
|
|
# Test Results Summary
|
|
# ===========================================================================
|
|
test-summary:
|
|
name: Test Results Summary
|
|
runs-on: ubuntu-22.04
|
|
needs: [unit-tests, contract-tests, integration-tests, security-tests]
|
|
if: always()
|
|
steps:
|
|
- name: Download all test results
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
path: all-test-results
|
|
|
|
- name: Generate summary
|
|
run: |
|
|
echo "## Test Lane Results" >> $GITHUB_STEP_SUMMARY
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
|
|
for lane in unit contract integration security; do
|
|
result_dir="all-test-results/${lane}-test-results"
|
|
if [ -d "$result_dir" ]; then
|
|
echo "### ${lane^} Lane: ✅ Passed" >> $GITHUB_STEP_SUMMARY
|
|
else
|
|
echo "### ${lane^} Lane: ❌ Failed or Skipped" >> $GITHUB_STEP_SUMMARY
|
|
fi
|
|
done
|
|
|
|
echo "" >> $GITHUB_STEP_SUMMARY
|
|
echo "See individual job logs for detailed test output." >> $GITHUB_STEP_SUMMARY
|