# Key Rotation Service with Temporal Validity ## Module Signer ## Status IMPLEMENTED ## 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 - [ ] POST /api/v1/anchors/{anchorId}/keys adds a key and returns updated AllowedKeyIds with audit log ID - [ ] POST /{anchorId}/keys/{keyId}/revoke sets RevokedAt and moves key from allowed to revoked list - [ ] GET /{anchorId}/keys/{keyId}/validity returns correct temporal validity (Active, NotYetValid, Revoked, Expired) for a given signedAt timestamp - [ ] Verify temporal key validation: key added at T1 is invalid for signatures before T1, valid between T1 and revocation/expiry - [ ] GET /{anchorId}/keys/warnings returns ExpiryApproaching, LongLived, and AlgorithmDeprecating warnings - [ ] Verify PURL pattern matching finds most-specific anchor for a given PURL - [ ] Verify VerifySignatureAuthorizationAsync combines key validity + predicate type check - [ ] Verify algorithm validation rejects keys with unsupported algorithms