Locking is advisory in the sense that it lives in the block markup, so anybody with the code editor open can remove it — and the capability filter decides who sees the option.
add_filter( 'block_editor_settings_all', function ( array $s ): array {
$s['canLockBlocks'] = current_user_can( 'edit_theme_options' );
return $s;
} );
// false: the lock UI disappears and existing locks are
// still enforced. which is usually what a client site wants.
Hiding the lock control while keeping the locks enforced is the useful configuration and is not the default — by default an editor can unlock anything they can see. The code editor remains an escape hatch for anybody with the capability, which is a good reason to remove that capability from the editor role on a site with a strict design.