The primary protection mechanism against unauthorized code readout/copying in STM32 is Read Protection, accomplished through a dedicated Option byte, RDP. It can be set to 3 levels - RDP0 (short for RDP Level 0) is the default, unprotected mode; RDP1 prevents against code readout, but the chip still can be reprogrammed (while a bulkerase is performed); RDP2 is the highest readout protection where no further programming is possible and also the SWD/JTAG debugging mechanism is completely disabled.
In the 'G0/'G4 families, there is a new option bit, BOOT_LOCK, which is probably intended to increase security by preventing to boot from System memory or RAM, ie. boot is always from the User FLASH. However, combining BOOT_LOCK together with RDP1 has the following effect (quoting directly from RM):
Caution: If BOOT_LOCK is set in association with RDP Level 1, the debug capabilities of the device are stopped and the reset value of the DBG_SWEN bit of the FLASH_ACR register becomes zero. If DBG_SWEN bit is not set by the application code after reset, there is no way to recover from this situation.
So, in effect, BOOT_LOCK=1 and RDP1 has the same effect than RDP2; except that contrary to RDP2, it can be "reverted from inside".
More dramatic of course is the impact to the unaware, if this combination is set inadvertently.
The 'G0x0 "Value line" subfamily oficially does not have the BOOT_LOCK bit; however, as the die is the same as of some of the "full-fledged" 'G0s, this distinction is only in the programming software (e.g. CubeProgrammer) which does not display the state of this bit and does not allow to program it.