Skip to content

feat(security)!: remove IEncryptionProvider.RotateKeyAsync overloads#157

Merged
AbongileBoja merged 1 commit intodevelopfrom
feat/remove-rotate-key-async-138
Apr 27, 2026
Merged

feat(security)!: remove IEncryptionProvider.RotateKeyAsync overloads#157
AbongileBoja merged 1 commit intodevelopfrom
feat/remove-rotate-key-async-138

Conversation

@AbongileBoja
Copy link
Copy Markdown
Owner

Summary

4.0 BREAKING — Phase 3c of v4 release. Closes the 3.x deprecation shipped in #137. Both overloads were [Obsolete(error: true)] in 3.x and every shipping implementation (AesEncryptionProvider, AesGcmEncryptionProvider, MigratingEncryptionProvider) threw NotSupportedException. ApiCompat reports CP0001 (member removed) on both.

Removed

  • IEncryptionProvider.RotateKeyAsync()
  • IEncryptionProvider.RotateKeyAsync(CancellationToken) (the DIM that delegated to the CT-less overload)
  • AesEncryptionProvider.RotateKeyAsync implementation
  • AesGcmEncryptionProvider.RotateKeyAsync implementation
  • MigratingEncryptionProvider.RotateKeyAsync implementation
  • 2 reflection-based throw-asserting tests:
    • RotateKeyAsync_Throws_NotSupported in AesGcmEncryptionProviderTests
    • RotateKeyAsync_AlwaysThrows in MigratingEncryptionProviderTests

Migration

Implement key rotation at the storage layer:

  1. Construct a new provider with the new key.
  2. For each persisted ciphertext: decrypt under the old provider, re-encrypt under the new provider, persist.
  3. Cut over reads to the new provider once re-encryption completes.

For MigratingEncryptionProvider specifically, the existing prefix-tag dispatch already supports this pattern — register the previous writer as a legacy reader and promote the new writer.

Local verification

  • dotnet build -c Release -p:QUERYSPEC_SKIP_SIGN=true — 0 errors
  • dotnet test -c Release718 unique tests green across net8.0/9.0/10.0 (was 720; 2 removed)

Phase context — final v4 API break

Closes #138
Refs #73

BREAKING CHANGES — Phase 3c of v4 release. Both overloads were
[Obsolete(error: true)] in 3.x and every shipping implementation threw
NotSupportedException. ApiCompat reports CP0001 (member removed) on both.

Removed:
- IEncryptionProvider.RotateKeyAsync()
- IEncryptionProvider.RotateKeyAsync(CancellationToken) (the DIM that
  delegated to the CT-less overload)
- AesEncryptionProvider.RotateKeyAsync impl
- AesGcmEncryptionProvider.RotateKeyAsync impl
- MigratingEncryptionProvider.RotateKeyAsync impl
- 2 reflection-based throw-asserting tests
  (RotateKeyAsync_Throws_NotSupported in AesGcmEncryptionProviderTests,
  RotateKeyAsync_AlwaysThrows in MigratingEncryptionProviderTests)

Migration: implement key rotation at the storage layer — construct a new
provider with the new key, decrypt with the old, re-encrypt with the new,
persist, then cut over reads. For MigratingEncryptionProvider, register
the previous writer as a legacy reader and promote the new writer.

Tests: 718 unique green across net8.0/9.0/10.0 (was 720; 2 removed).

Closes #138
Refs #73
@AbongileBoja AbongileBoja merged commit 1d2e35c into develop Apr 27, 2026
13 of 14 checks passed
@AbongileBoja AbongileBoja deleted the feat/remove-rotate-key-async-138 branch April 27, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove obsolete IEncryptionProvider.RotateKeyAsync overloads in 4.0

1 participant