# Key Rotation Service with Temporal Validity ## Module Signer ## Status VERIFIED ## Description Automated key rotation service with temporal key validity windows, key history tracking (key_history and key_audit_log tables), trust anchor management with PURL pattern matching, and CLI commands for key lifecycle operations. Ensures proof verification uses the correct key for the attestation timestamp. ## Implementation Details - **KeyRotationService**: `src/Signer/__Libraries/StellaOps.Signer.KeyManagement/KeyRotationService.cs` -- implements advisory section 8.2: AddKeyAsync (validates algorithm against AllowedAlgorithms, creates KeyHistoryEntity + KeyAuditLogEntity, updates anchor AllowedKeyIds), RevokeKeyAsync (sets RevokedAt + RevokeReason, moves key from AllowedKeyIds to RevokedKeyIds), CheckKeyValidityAsync (temporal validation: NotYetValid if signedAt < AddedAt, Revoked if signedAt >= RevokedAt, Expired if signedAt >= ExpiresAt), GetRotationWarningsAsync (ExpiryApproaching within ExpiryWarningDays, LongLived exceeding MaxKeyAgeDays, AlgorithmDeprecating for deprecated algorithms), GetKeyHistoryAsync; EF Core transactions with InMemory provider detection - **TrustAnchorManager**: `src/Signer/__Libraries/StellaOps.Signer.KeyManagement/TrustAnchorManager.cs` -- implements advisory section 8.3: GetAnchorAsync, FindAnchorForPurlAsync (glob-style PURL pattern matching with specificity scoring, most-specific-match-wins), CreateAnchorAsync (validates PURL pattern), UpdateAnchorAsync (AllowedPredicateTypes/PolicyRef/PolicyVersion), DeactivateAnchorAsync, VerifySignatureAuthorizationAsync (combines temporal key validity + predicate type authorization), GetActiveAnchorsAsync - **PurlPatternMatcher**: `src/Signer/__Libraries/StellaOps.Signer.KeyManagement/TrustAnchorManager.cs` -- glob-to-regex pattern matching for PURLs (e.g., pkg:npm/*, pkg:maven/org.apache/*); specificity scoring (segments * 10 - wildcards * 5) - **KeyRotationOptions**: configurable AllowedAlgorithms (ES256, ES384, ES512, RS256, EdDSA, SM2, GOST12-256, DILITHIUM3, FALCON512, etc.), ExpiryWarningDays (60), MaxKeyAgeDays (365), DeprecatedAlgorithms (RSA-2048, SHA1-RSA) - **KeyManagementDbContext**: `src/Signer/__Libraries/StellaOps.Signer.KeyManagement/KeyManagementDbContext.cs` -- EF Core context with TrustAnchors, KeyHistory, KeyAuditLog DbSets - **KeyEntities**: `src/Signer/__Libraries/StellaOps.Signer.KeyManagement/Entities/KeyEntities.cs` -- KeyHistoryEntity (HistoryId, AnchorId, KeyId, PublicKey, Algorithm, AddedAt, ExpiresAt, RevokedAt, RevokeReason), KeyAuditLogEntity (LogId, Operation enum: Add/Revoke/Rotate, Actor, Reason) - **TrustAnchorEntity**: `src/Signer/__Libraries/StellaOps.Signer.KeyManagement/Entities/TrustAnchorEntity.cs` -- AnchorId, PurlPattern, AllowedKeyIds, RevokedKeyIds, AllowedPredicateTypes, PolicyRef, PolicyVersion, IsActive - **KeyRotationEndpoints**: `src/Signer/StellaOps.Signer/StellaOps.Signer.WebService/Endpoints/KeyRotationEndpoints.cs` -- REST API at `/api/v1/anchors`: POST /{anchorId}/keys (add key), POST /{anchorId}/keys/{keyId}/revoke, GET /{anchorId}/keys/{keyId}/validity?signedAt=, GET /{anchorId}/keys/history, GET /{anchorId}/keys/warnings; all require KeyManagement authorization - **IKeyRotationService**: `src/Signer/__Libraries/StellaOps.Signer.KeyManagement/IKeyRotationService.cs` -- interface contract - **ITrustAnchorManager**: `src/Signer/__Libraries/StellaOps.Signer.KeyManagement/ITrustAnchorManager.cs` -- interface contract - **Tests**: `src/Signer/StellaOps.Signer/StellaOps.Signer.Tests/KeyManagement/KeyRotationServiceTests.cs`, `TemporalKeyVerificationTests.cs`, `TrustAnchorManagerTests.cs`, `Integration/KeyRotationWorkflowIntegrationTests.cs` - **Source**: SPRINT_0501_0008_0001_proof_chain_key_rotation.md ## E2E Test Plan - [x] POST /api/v1/anchors/{anchorId}/keys adds a key and returns updated AllowedKeyIds with audit log ID - [x] POST /{anchorId}/keys/{keyId}/revoke sets RevokedAt and moves key from allowed to revoked list - [x] GET /{anchorId}/keys/{keyId}/validity returns correct temporal validity (Active, NotYetValid, Revoked, Expired) for a given signedAt timestamp - [x] Verify temporal key validation: key added at T1 is invalid for signatures before T1, valid between T1 and revocation/expiry - [x] GET /{anchorId}/keys/warnings returns ExpiryApproaching, LongLived, and AlgorithmDeprecating warnings - [x] Verify PURL pattern matching finds most-specific anchor for a given PURL - [x] Verify VerifySignatureAuthorizationAsync combines key validity + predicate type check - [x] Verify algorithm validation rejects keys with unsupported algorithms ## Verification - **Run ID**: run-001 - **Date**: 2026-02-10 - **Method**: Tier 1 code review + Tier 2d existing test verification - **Build**: PASS (0 errors, 0 warnings) - **Tests**: PASS (491/491 signer tests pass) - **Code Review**: - KeyRotationService: Full temporal key lifecycle verified. AddKeyAsync validates algorithm against configurable AllowedAlgorithms list, creates KeyHistoryEntity + KeyAuditLogEntity in EF Core transaction. CheckKeyValidityAsync implements correct temporal precedence: NotYetValid (signedAt < AddedAt) > Revoked (signedAt >= RevokedAt) > Expired (signedAt >= ExpiresAt) > Active. GetRotationWarningsAsync checks three warning types with configurable thresholds. - TrustAnchorManager: PURL pattern matching verified -- glob-to-regex conversion, specificity scoring (segments*10 - wildcards*5), most-specific-match-wins semantics. VerifySignatureAuthorizationAsync correctly combines temporal key validity with predicate type authorization. - Tests: KeyRotationServiceTests (add/revoke/validity checks), TemporalKeyVerificationTests (boundary conditions for temporal validation), TrustAnchorManagerTests (PURL matching, specificity scoring), KeyRotationWorkflowIntegrationTests (end-to-end rotation workflows with EF Core InMemory provider). - **Verdict**: PASS ## Recheck (Run-002) - **Verified**: 2026-02-10 - **Method**: Tier 2a live API replay + Tier 1 regression suite replay. - **Tests**: PASS (496/496 signer tests pass). - **Tier 2 Evidence**: `docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-002/tier2-api-check.json` - **Regression Coverage Added**: `KeyValidity_ReturnsNotFound_ForUnknownAnchorOrKey`. - **Outcome**: Unknown key validity lookups now return `404 Not Found` instead of `200 Unknown`. ## Recheck (Run-003) - **Verified**: 2026-02-10 - **Method**: Tier 2 follow-up deterministic replay. - **Tests**: PASS (`src/Signer/StellaOps.Signer/StellaOps.Signer.Tests`: 496/496). - **Tier 2 Evidence**: `docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-003/tier2-api-check.json` - **Outcome**: Key-validity and temporal semantics remain stable, including unknown-key 404 handling. ## Recheck (Run-004) - **Verified**: 2026-02-10 - **Method**: Tier 2 replay + full Signer suite replay. - **Tests**: PASS (`src/Signer/StellaOps.Signer/StellaOps.Signer.Tests`: 496/496). - **Tier 2 Evidence**: `docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-004/tier2-api-check.json` - **Outcome**: Key-validity API behavior (including unknown-key semantics) remains stable. ## Recheck (Run-005) - **Verified**: 2026-02-10 - **Method**: Tier 2 replay validated via Signer suite and endpoint coverage. - **Tests**: PASS (src/Signer/StellaOps.Signer/StellaOps.Signer.Tests: 496/496). - **Tier 2 Evidence**: docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-005/tier2-api-check.json - **Outcome**: Checked signer behavior remains healthy in follow-up replay. ## Recheck (Run-006) - **Verified**: 2026-02-10 - **Method**: Tier 2 replay (API + integration) with deterministic signer suite verification. - **Tests**: PASS (src/Signer/StellaOps.Signer/StellaOps.Signer.Tests: 496/496). - **Tier 2 Evidence**: docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-006/tier2-api-check.json - **Outcome**: Checked signer behavior remains healthy in continued replay. ## Recheck (Run-007) - **Verified**: 2026-02-10 - **Method**: Tier 2 replay (API + integration) with deterministic signer suite verification. - **Tests**: PASS (src/Signer/StellaOps.Signer/StellaOps.Signer.Tests: 496/496). - **Tier 2 Evidence**: docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-007/tier2-api-check.json - **Outcome**: Checked signer behavior remains healthy in continued replay. ## Recheck (Run-008) - **Verified**: 2026-02-10 - **Method**: Tier 2a API replay + deterministic integration suite replay. - **Tests**: PASS (src/Signer/StellaOps.Signer/StellaOps.Signer.Tests: 496/496). - **Tier 2 Evidence**: docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-008/tier2-api-check.json - **Outcome**: Checked Signer behavior remains healthy in continued replay. ## Recheck (Run-009) - **Verified**: 2026-02-10 - **Method**: Tier 2a API replay + deterministic integration suite replay. - **Tests**: PASS (src/Signer/StellaOps.Signer/StellaOps.Signer.Tests: 496/496). - **Tier 2 Evidence**: docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-009/tier2-api-check.json - **Outcome**: Checked Signer behavior remains healthy in continued replay. ## Recheck (Run-010) - **Verified**: 2026-02-10 - **Method**: Tier 2d deterministic integration replay. - **Tests**: PASS (src/Signer/StellaOps.Signer/StellaOps.Signer.Tests: 496/496). - **Tier 2 Evidence**: docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-010/tier2-integration-check.json - **Outcome**: Checked signer behavior remains healthy in continued replay. ## Recheck (Run-011) - **Verified**: 2026-02-10 - **Method**: Tier 2d deterministic integration replay. - **Tests**: PASS (src/Signer/StellaOps.Signer/StellaOps.Signer.Tests: 496/496). - **Tier 2 Evidence**: docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-011/tier2-integration-check.json - **Outcome**: Checked signer behavior remains healthy in continued replay. ## Recheck (Run-012) - **Verified**: 2026-02-10 - **Method**: Tier 2 replay + deterministic integration suite replay. - **Tests**: PASS (src/Signer/StellaOps.Signer/StellaOps.Signer.Tests: 496/496). - **Tier 2 Evidence**: docs/qa/feature-checks/runs/signer/key-rotation-service-with-temporal-validity/run-012/tier2-api-check.json - **Outcome**: Checked signer behavior remains healthy in continued replay.