diff --git a/README.md b/README.md index cb5c736..0e3a2ec 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ with. - `XChaCha20-Poly1305` authenticated encryption per file - `Ed25519` signed manifest for tamper detection - JSON output for AI agents and automation +- no real content master key embedded in the client header ## Current commands diff --git a/docs/client-integration.md b/docs/client-integration.md index 486aeca..07aa434 100644 --- a/docs/client-integration.md +++ b/docs/client-integration.md @@ -14,7 +14,7 @@ tool. - legacy format for old `.pack` - new format for `.m2p` 4. Embed only the signing public key in the client. -5. Resolve the content decryption key from: +5. Resolve the content decryption key from runtime delivery: - launcher-provided memory - machine-bound cache - or a derived release secret @@ -36,6 +36,12 @@ m2pack export-client-config \ That keeps loader constants aligned with the archive builder. +Important: + +- the generated client header no longer embeds the real master key +- `.m2p` loading now requires a runtime master key +- if a `.m2p` file exists and fails validation or runtime key resolution, the client should not silently fall back to `.pck` + ## Runtime validation Minimum validation: @@ -100,7 +106,7 @@ Recommended production path: - launcher creates the shared mapping - launcher starts the client with `--m2pack-key-map Local\\M2PackSharedKeys` - client reads runtime keys during startup -- compiled fallback key remains only as migration fallback and should be removed later +- client rejects `.m2p` loading if the runtime master key is missing ## Loader notes diff --git a/src/cli.cpp b/src/cli.cpp index 0d1860f..45f7a22 100644 --- a/src/cli.cpp +++ b/src/cli.cpp @@ -296,15 +296,19 @@ void command_export_client_config(const ParsedArgs& args) return out.str(); }; + const std::vector zero_master(kAeadKeySize, 0); + std::ostringstream header; header << "#pragma once\n\n" << "#include \n" << "#include \n\n" << "// Generated by m2pack export-client-config.\n" - << "// Do not edit manually.\n\n" + << "// Do not edit manually.\n" + << "// Runtime master key delivery is required for .m2p loading.\n\n" + << "constexpr bool M2PACK_RUNTIME_MASTER_KEY_REQUIRED = true;\n\n" << "constexpr std::array M2PACK_MASTER_KEY = {" - << render_array(master) + << render_array(zero_master) << "};\n\n" << "constexpr std::array M2PACK_SIGN_PUBLIC_KEY = {" << render_array(public_key)