On Tue, Jun 16, 2026 at 05:08:30AM +0000, Abhisek Panda wrote:
I have re-architected the support for enabling the TLS-PSK-based encrypted migration in Libvirt. In this design, Libvirt handles the lifecycle of pre-shared keys, managing their generation, persistent storage, and cleanup. We propose the following changes to Libvirt.
1. Add the following configuration attributes: "migrate_base_psk_dir" and "migrate_psk_length" to qemu.conf. This allows users to define the base directory containing the generated pre-shared keys and the size of the pre-shared key in bytes. Note: The default value of "migrate_base_psk_dir" is set to "/var/run/libvirt/qemu" and "migrate_psk_length" is set to "32".
Note, PSKs should be treated as one-time-use keys that are generated on demand when a migration is initiated and thrown away at completion. I don't think we need to expose a user controlled directory as we do not expect users to create the keys ahead of time.
2. Introduce a new migration flag VIR_MIGRATE_TLS_PSK, that enables the use of TLS-PSK-based authentication mechanism for an encrypted migration session.
IMHO we should always use a generated PSK if VIR_MIGRATE_TLS is passed and no certificates are configured for use with QEMU. I don't think we need any new API flag.
3. If the VIR_MIGRATE_TLS_PSK flag is set, Libvirt generates a random key of "migrate_psk_length" bytes on the source, and embeds it within a new <migration-key> element inside the migration cookie. Subsequently, it writes this key into a file located at <migrate_base_psk_dir>/<vm_uuid>/keys.psk with the following contents: qemu:<generated_key>.
4. The destination Libvirt reads the key from <migration-key> in the incoming cookie. Subsequently, it writes the key into a file located in <migrate_base_psk_dir>/<vm_uuid>/keys.psk with the same content as in step-3. 5. During the perform stage, Libvirt creates the tls-creds-psk QEMU object with the appropriate attributes for enabling encrypted migration. 6. Upon migration completion and on all failure/abort paths, Libvirt deletes the <migrate_base_psk_dir>/<vm_uuid> directory, thereby ensuring no key specific information is present on the disk.
In case the user wants to use an existing secret for a migration session, we extend the design with a new migration parameter: "VIR_MIGRATE_PARAM_TLS_PSK_SECRET_UUID". In this workflow, a user can initialise the pre-shared key as the secret payload. Libvirt is then provided the secret UUID using the "VIR_MIGRATE_PARAM_TLS_PSK_SECRET_UUID" migration parameter. In this case, Libvirt reads the required PSK via lookup of the secret API and utilizes for encrypting the migration stream, skipping the auto generation step entirely.
A key is just a set of random bytes. The user is no better at creating random bytes than libvirt so I see no reason to expose this parameter. It is liable to promote bad practices that an app uses a single PSK for every VM. With regards, Daniel -- |: https://berrange.com ~~ https://hachyderm.io/@berrange :| |: https://libvirt.org ~~ https://entangle-photo.org :| |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|