Skip to content

Remove MIP-03/MIP-04 legacy exporter-secret + media compat code (deadline expired 2026-05-15) #304

@erskingardner

Description

@erskingardner

Why now

The MIP-03 legacy exporter-secret migration deadline and the MIP-04 legacy media key-derivation deadline both expired on 2026-05-15 00:00:00 UTC (see CHANGELOG entry for #222 which moved the deadline from June 4 to May 15). Both are encoded as the unix-epoch constant 1_778_803_200 in two parallel places in mdk-core.

From today onward, the runtime gates (allow_legacy_media_fallback_at / allow_legacy_exporter_secret_fallback_at) both return false for any caller using real time. That means every if allow_legacy { … } branch downstream of the gates is unreachable in production — but the legacy derivation code, storage trait methods, and threaded allow_legacy parameters are still in the source tree, still compile, and still get exercised by tests (which now must pin a pre-deadline timestamp via the _at variants introduced in #222).

#303 migrated the two real-time tests that started failing at midnight to the deterministic _at variants (2-line change in test bodies only) so CI would unblock; the production compat code was deliberately left untouched and is the subject of this issue.

Scope — two parallel surfaces

1. Media decryption (MIP-04)

2. Message decryption (MIP-03)

3. Storage backends

Both mdk-memory-storage and mdk-sqlite-storage implement get_group_legacy_exporter_secret / save_group_legacy_exporter_secret. The sqlite backend has the legacy_exporter_secrets table (or equivalent rows) — decide whether to drop the table in a migration or leave the rows orphaned.

4. Tests / fixtures

  • fixed_pre_deadline_ts() / fixed_post_deadline_ts() helpers in encrypted_media/manager.rs and messages/decryption.rs
  • The two *_legacy_media_compat tests that feat(mdk-core): accept caller-supplied d-tag for KeyPackage events #303 migrated to the _at variants (they're regression coverage for the soon-to-be-removed code — delete with it)
  • The boundary tests test_allow_legacy_media_fallback_at_boundary and equivalents

Concrete change checklist

  • Drop LEGACY_MEDIA_MIGRATION_DEADLINE + allow_legacy_media_fallback_at + the gate call site in manager.rs
  • Drop the allow_legacy: bool parameter from all media-path helpers; remove the if allow_legacy { … } branches
  • Drop derive_legacy_encryption_key_with_secret from encrypted_media/crypto.rs and its use imports
  • Drop LEGACY_EXPORTER_SECRET_MIGRATION_DEADLINE + allow_legacy_exporter_secret_fallback_at from messages/decryption.rs
  • Drop decrypt_message_with_legacy_exporter_secret from messages/crypto.rs
  • Drop MDK::legacy_exporter_secret from groups.rs and the allow_legacy_exporter_secret parameter threading
  • Remove get_group_legacy_exporter_secret / save_group_legacy_exporter_secret from the mdk-storage-traits trait + macros
  • Update mdk-memory-storage and mdk-sqlite-storage implementations
  • Decide migration story for existing sqlite rows in legacy_exporter_secrets (drop the table vs. leave orphaned)
  • Delete the *_legacy_media_compat tests, the fixed_pre_deadline_ts / fixed_post_deadline_ts helpers, and the boundary tests
  • CHANGELOG: breaking-change entry across mdk-core, mdk-storage-traits, mdk-memory-storage, mdk-sqlite-storage

Breaking changes

  • MdkStorageProvider (via GroupStorage) loses two trait methods — implementers downstream of mdk-storage-traits must update.
  • Existing groups with legacy_exporter_secret rows in storage are still readable (no decryption error) but those rows become inert; clients that still rely on legacy media/message decryption beyond today are already broken at runtime regardless of this PR — no callers can come back and fail "harder" than they already do.
  • Estimated diff size: ~300-600 LOC removed across the workspace.

Out of scope

  • The MIP-00 kind:443 → kind:30443 KeyPackage event-kind migration. That's a separate sunset with deadline May 31, 2026 (16 days from filing), and it's a manual/documented sunset (TODOs in key_packages.rs:434 and key_packages.rs:3338), not a runtime timestamp gate. File a separate issue for that one when its deadline approaches.

References

  • #222 — introduced both deadlines and the _at deterministic variants for tests
  • #303 — migrated the two real-time tests to the _at variants when they exploded on 2026-05-15 (commit 21c50b6); did NOT remove any legacy production code

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions