Currently, only LUKSv1 is supported.
Create a secret:
<secret ephemeral='no' private='yes'>
<description></description>
<usage type='volume'>
<volume>/vms/PATH</volume>
</usage>
</secret>
virsh secret-define volume-secret.xml
Populate the secret:
virsh secret-set-value UUID --file FILE --plain
Secret value set
Modifications to Domain XML if underlying device is a file:
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/vms/PATH'>
<encryption format='luks'>
<secret type='passphrase' uuid='SECRET_UUID'/>
</encryption>
</source>
<target dev='vdb' bus='virtio'/>
</disk>
Modifications to Domain XML if underlying device is a block device/LV:
<disk type='block' device='disk'>
<driver name='qemu' type='raw'/>
<source dev='/vms/PATH'>
<encryption format='luks'>
<secret type='passphrase' uuid='SECRET_UUID'/>
</encryption>
</source>
<target dev='vdb' bus='virtio'/>
</disk>
Full Setup Cycle
pwgen 32 1 > testkey
lvcreate -L20G -ndtest-luks pool1
cryptsetup luksFormat --type luks1 /dev/mapper/pool1-dtest--luks testkey
cat <<EOF | virsh secret-define /dev/stdin
<secret ephemeral='no' private='yes'>
<description></description>
<usage type='volume'>
<volume>/dev/mapper/pool1-dtest--luks</volume>
</usage>
</secret>
EOF
Secret 105d8a13-53d5-4e1f-8dd1-8d7f6c68f5ef created
virsh secret-set-value 105d8a13-53d5-4e1f-8dd1-8d7f6c68f5ef --file testkey
cat <<EOF | virsh attach-device --config dtest /dev/stdin
> <disk type='block' device='disk'>
<driver name='qemu' type='raw'/>
<source dev='/dev/mapper/pool1-dtest--luks'>
<encryption format='luks'>
<secret type='passphrase' uuid='105d8a13-53d5-4e1f-8dd1-8d7f6c68f5ef'/>
</encryption>
</source>
<target dev='vdb' bus='virtio'/>
</disk>
EOF