My LUKS2 model of smartcard integration stores the key encrypted in the luks2 header. This has since been implemented in other processes such as clevis and systemd but the boot process in debian/ubuntu does not include systemd making it difficult to use this model. I have solved this by creating a utility and some boot scripts. Here are the various methods I have used.
deb available at luks-root-smartcard . src available at https://github.com/jtmoree-github-com/luks-root-smartcard
Smartcard integration with root LUKS drives can be complex. These utilities integrate LUKS2, smartcards, systemd, gpg, and initramfs-tools allowing for multiple unlock methods. Advantages of this over stock debian/ubuntu.
supports systemd-pkcs11 LUKS2 header tokens without systemd in initrd
supports gpg luks2 header tokens so no decrypted partitions are needed
allows fallback to stock smartcard implementation
minimum changes to crypttab
no other file changes needed
This is the tried and true method of encrypting root using stock debian/ubuntu. We store an encrypted version of a luks key on disk and unlock it with the smartcard.
It is supported OOTB which does not fallback to passphrase. Debian has not accepted that change (not from me) but might be open to it. ( I don't know why as that seems to be the only sane way to do this. If I break/lose my smartcard I'm locked out of my system. ) When I was using this method I used a custom script to enable fallback but have to hack it into the system on updates because it gets overwritten.
All the data needed to boot and decrypt root is stored in the luks2 header, fetched, and decrypted via use of smartcard. I created a custom process to decrypt from the luks2 header token and feed the decrypted key to cryptsetup to open root. Like the Luks1 workflow above I had to hack it into the debian boot process and it would get lost on updates to cryptsetup.
Around 2021 systemd created a plugin for cryptsetup to store the key material in the luks2 header. Ideally, this would be useful for booting but it has challenges. Systemd is not supported in debian's initramfs-tools boot process. Adding it is complex and likely frowned upon by many for various reasons. For this reason dracut might be used instead. I could not get any of those approaches to work. It is my opinion that systemd-pkcs11 is not supportable on stock debian/ubuntu.
In theory clevis could store the key in the luks2 header but I could not get it to work.