Files
m2pack-secure/docs/key-rotation.md
2026-04-14 12:34:07 +02:00

2.1 KiB

Key rotation

m2pack-secure supports archive-level key_id so releases can move away from a single permanent content key.

Why rotate

Rotate when:

  • a content key may have leaked
  • a signing key may have leaked
  • you want to expire old launcher material
  • you want to separate major release lines
  • you change pack validation or loader policy

Current model

  • each archive stores a key_id in its header
  • the client chooses the verifier public key by key_id
  • the runtime master key must be delivered with the same key_id
  • .m2p loading fails if the archive key_id and runtime key_id do not match
  • keep key_id monotonic
  • reserve one key_id per release line or rotation event
  • never reuse an old key_id for different secret material
  • keep old public verification keys only as long as you need to support those releases
  • remove stale keys from the client once old archives are no longer supported

Rotation procedure

  1. Generate a new master.key.
  2. Generate a new signing keypair if needed.
  3. Assign a new key_id.
  4. Rebuild archives with --key-id <new-id>.
  5. Export a new M2PackKeys.h for the client.
  6. Export a new runtime key payload for the launcher.
  7. Ship client, launcher, and .m2p together.
  8. Retire old runtime material after rollout is complete.

Example

./build/m2pack keygen --out-dir keys-2026-05

./build/m2pack build \
  --input /srv/build/client-root \
  --output out/root.m2p \
  --key keys-2026-05/master.key \
  --sign-secret-key keys-2026-05/signing.key \
  --key-id 4

./build/m2pack export-client-config \
  --key keys-2026-05/master.key \
  --public-key keys-2026-05/signing.pub \
  --key-id 4 \
  --output /path/to/m2dev-client-src/src/PackLib/M2PackKeys.h

./build/m2pack export-runtime-key \
  --key keys-2026-05/master.key \
  --public-key keys-2026-05/signing.pub \
  --key-id 4 \
  --format blob \
  --output out/runtime-key.bin

Operational note

If you need overlapping support for multiple release lines, extend the client header with multiple verifier slots and keep launcher delivery strict: one runtime master key per active process, matching the archive key_id.