Skip to content

Key Rotation

Key rotation is the practice of periodically replacing encryption keys with new ones. Tayra supports versioned key rotation through ITayra, allowing you to create new keys while preserving old ones for decrypting existing data.

Why Rotate Keys?

Key rotation limits the impact of a potential key compromise:

  • Reduce blast radius — If a key is exposed, only data encrypted with that specific version is affected.
  • Compliance requirements — Many regulatory frameworks (PCI DSS, HIPAA) mandate periodic key rotation.
  • Cryptographic hygiene — Limiting the amount of data encrypted under a single key reduces the effectiveness of statistical attacks.

Basic Rotation

Use tayra.RotateKeyAsync() to create a new versioned key for a data subject. The old key is preserved so existing ciphertext remains decryptable. Then call ReEncryptAsync to re-encrypt the object's PII fields with the new key.

cs
// Rotate the key — creates a new versioned key (e.g., "cust-subject-rotate-001:v1").
// The old key is preserved so existing data can still be decrypted.
var rotationResult = await tayra.RotateKeyAsync("cust-subject-rotate-001");

// Re-encrypt the object with the new key
await tayra.ReEncryptAsync(rotationCustomer);

Console.WriteLine($"Old key: {rotationResult.OldKeyId}");
Console.WriteLine($"New key: {rotationResult.NewKeyId}");
Console.WriteLine($"Version: {rotationResult.NewVersion}");
anchor

Rotation Result

RotateKeyAsync returns a KeyRotationResult with details about the rotation:

cs
// KeyRotationResult contains all the details of the rotation
Console.WriteLine($"Rotated from '{rotationResult.OldKeyId}' to '{rotationResult.NewKeyId}'");
Console.WriteLine($"New version number: {rotationResult.NewVersion}");
// OldKeyId: "cust-subject-rotate-001"       (original unversioned key)
// NewKeyId: "cust-subject-rotate-001:v1"     (new versioned key)
// NewVersion: 1
anchor

The KeyRotationResult record contains:

PropertyDescription
OldKeyIdThe previous key ID (e.g., "cust-subject:v1" or the unversioned base key)
NewKeyIdThe newly created versioned key ID (e.g., "cust-subject:v2")
NewVersionThe integer version number of the new key

Versioning Scheme

Tayra uses a colon-separated version suffix for rotated keys:

Base key:     "cust-subject-001"        (original, unversioned)
After rotate: "cust-subject-001:v1"     (first rotation)
After rotate: "cust-subject-001:v2"     (second rotation)
After rotate: "cust-subject-001:v3"     (third rotation)

The rotator discovers existing versions by querying the key store with the base key ID as a prefix. The highest version number is incremented for the new key.

Old Key Preservation

Old keys are never deleted during rotation. This is by design:

  1. Existing data still needs the old key for decryption until it is re-encrypted.
  2. Gradual migration — You can re-encrypt records in batches over time, not all at once.
  3. Rollback safety — If something goes wrong during re-encryption, old ciphertext is still readable.

To clean up old keys after all data has been re-encrypted, delete them explicitly using tayra.ShredAsync().

Re-Encryption Workflow

A typical rotation workflow for a batch of records:

  1. Call tayra.RotateKeyAsync() to create the new versioned key.
  2. Load each record from your database.
  3. Call tayra.ReEncryptAsync() on each record to decrypt with the old key and re-encrypt with the new one.
  4. Save the updated record back to the database.
  5. Optionally shred old key versions once all records have been migrated.

WARNING

ReEncryptAsync modifies the object's PII fields in-place. Make sure to persist the re-encrypted values to your database after calling it.

When to Rotate

Consider rotating keys:

  • On a schedule — Monthly or quarterly, depending on your compliance requirements.
  • After a suspected breach — Rotate affected keys immediately and re-encrypt all data.
  • When an employee leaves — If the employee had access to key material.
  • Before key retirement — Rotate to a new key, re-encrypt all data, then shred the old key.

See Also