# 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 ## Recommended policy - 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 `. 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 ```bash ./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`.