ADR-023, from docs/DECISIONS.md in the QuantyKube repository.
Status In force
A container runs as the user the kubelet sends (runAsUser,
runAsGroup, a user name, supplemental groups), and otherwise as the
image's User. Names are looked up in the image's own /etc/passwd and
/etc/group, never the host's, and the groups a user is a member of
there are added, as runc does. An image user that does not exist is an
error, not root. ImageStatus reports the image's user so that the
kubelet can enforce runAsNonRoot before a container starts.
A process that is not root starts with no capabilities at all, the
bounding set still limited to the default set and no_new_privs
set, which is what Docker and containerd give it. The ids are set with
raw system calls: glibc's wrappers would try to synchronise threads that
exist only in the parent.
StartContainer now returns only once the container's process has called execve, read from a pipe that closes on exec. Without that, an exec right after a start could join a mount namespace still being set up.
The cost: user namespaces are not used, so root in a container is root on the host, held in only by capabilities, seccomp and the mounts.